jailbreak.m 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. //
  2. // jailbreak.m
  3. // Meridian
  4. //
  5. // Created by Ben Sparkes on 16/02/2018.
  6. // Copyright © 2018 Ben Sparkes. All rights reserved.
  7. //
  8. #include "v0rtex.h"
  9. #include "kernel.h"
  10. #include "helpers.h"
  11. #include "root-rw.h"
  12. #include "amfi.h"
  13. #include "offsetfinder.h"
  14. #include "jailbreak.h"
  15. #include "ViewController.h"
  16. #include "patchfinder64.h"
  17. #include "patchfinders/offsetdump.h"
  18. #include "nvpatch.h"
  19. #include <mach/mach_types.h>
  20. #include <sys/stat.h>
  21. #import <Foundation/Foundation.h>
  22. #import "NSData+GZip.h"
  23. #include <sys/spawn.h>
  24. #import "fun_objc.h"
  25. //#import "NSTask.h"
  26. NSFileManager *fileMgr;
  27. offsets_t offsets;
  28. BOOL great_success = FALSE;
  29. int makeShitHappen(ViewController *view) {
  30. int ret;
  31. fileMgr = [NSFileManager defaultManager];
  32. // run v0rtex
  33. [view writeText:@"running v0rtex..."];
  34. suspend_all_threads();
  35. ret = runV0rtex();
  36. resume_all_threads();
  37. if (ret != 0) {
  38. [view writeText:@"failed!"];
  39. if (ret == -420) {
  40. [view writeTextPlain:@"failed to load offsets!"];
  41. }
  42. return 1;
  43. }
  44. [view writeTextPlain:@"succeeded! praize siguza!"];
  45. // set up stuff
  46. init_patchfinder(NULL);
  47. ret = init_amfi();
  48. if (ret != 0) {
  49. [view writeTextPlain:@"failed to initialize amfi class!"];
  50. return 1;
  51. }
  52. // patch containermanager
  53. [view writeText:@"patching containermanager..."];
  54. ret = patchContainermanagerd();
  55. if (ret != 0) {
  56. [view writeText:@"failed!"];
  57. return 1;
  58. }
  59. [view writeText:@"done!"];
  60. // remount root fs
  61. [view writeText:@"remounting rootfs as r/w..."];
  62. ret = remountRootFs();
  63. if (ret != 0) {
  64. [view writeText:@"failed!"];
  65. return 1;
  66. }
  67. [view writeText:@"done!"];
  68. /* Begin the filesystem fuckery */
  69. [view writeText:@"some filesytem fuckery..."];
  70. // Remove /meridian in the case of PB's
  71. if (file_exists("/meridian") == 0 &&
  72. file_exists("/meridian/.bootstrap") != 0) {
  73. [[NSFileManager defaultManager] removeItemAtPath:@"/meridian" error:nil];
  74. }
  75. if (file_exists("/Library/LaunchDaemons/._dropbear.plist") == 0) {
  76. unlink("/Library/LaunchDaemons/._dropbear.plist");
  77. }
  78. /*
  79. if (file_exists("/meridian/.bootstrap") == 0) {
  80. unlink("/meridian/.bootstrap");
  81. }
  82. //take these out later, just so i can update the plists as i tweak the payload
  83. if (file_exists("/Library/LaunchDaemons/com.openssh.sshd.plist") == 0) {
  84. unlink("/Library/LaunchDaemons/com.openssh.sshd.plist");
  85. }
  86. if (file_exists("/Library/LaunchDaemons/dropbear.plist") == 0) {
  87. unlink("/Library/LaunchDaemons/dropbear.plist");
  88. }
  89. */
  90. // if (file_exists("/usr/lib/TweakInject.dylib") == 0) {
  91. // ret = unlink("/usr/lib/TweakInject.dylib");
  92. // if (ret != 0) {
  93. // [view writeText:@"failed!"];
  94. // [view writeTextPlain:@"removing /usr/lib/TweakInject.dylib failed with error %d: %s", errno, strerror(errno)];
  95. // return 1;
  96. // }
  97. //
  98. // }
  99. if (file_exists("/meridian") != 0) {
  100. ret = mkdir("/meridian", 0755);
  101. if (ret != 0) {
  102. [view writeText:@"failed!"];
  103. [view writeTextPlain:@"creating /meridian failed with error %d: %s", errno, strerror(errno)];
  104. return 1;
  105. }
  106. }
  107. if (file_exists("/meridian/logs") != 0) {
  108. ret = mkdir("/meridian/logs", 0755);
  109. if (ret != 0) {
  110. [view writeText:@"failed!"];
  111. [view writeTextPlain:@"creating /meridian/logs failed with error %d: %s", errno, strerror(errno)];
  112. return 1;
  113. }
  114. }
  115. if (file_exists("/meridian/tar") == 0) {
  116. ret = unlink("/meridian/tar");
  117. if (ret != 0) {
  118. [view writeText:@"failed!"];
  119. [view writeTextPlain:@"removing /meridian/tar failed with error %d: %s", errno, strerror(errno)];
  120. return 1;
  121. }
  122. }
  123. if (file_exists("/meridian/tar.tar") == 0) {
  124. ret = unlink("/meridian/tar.tar");
  125. if (ret != 0) {
  126. [view writeText:@"failed!"];
  127. [view writeTextPlain:@"deleting /meridian/tar.tar failed with error %d: %s", errno, strerror(errno)];
  128. return 1;
  129. }
  130. }
  131. ret = extract_bundle("tar.tar", "/meridian");
  132. if (ret != 0) {
  133. [view writeText:@"failed!"];
  134. [view writeTextPlain:@"failed to extract tar.tar bundle! ret: %d, errno: %d: %s", ret, errno, strerror(errno)];
  135. return 1;
  136. }
  137. if (file_exists("/meridian/tar") != 0) {
  138. [view writeText:@"failed!"];
  139. [view writeTextPlain:@"/meridian/tar was not found :("];
  140. return 1;
  141. }
  142. ret = chmod("/meridian/tar", 0755);
  143. if (ret != 0) {
  144. [view writeText:@"failed!"];
  145. [view writeTextPlain:@"chmod(755)'ing /meridian/tar failed with error %d: %s", errno, strerror(errno)];
  146. return 1;
  147. }
  148. ret = inject_trust("/meridian/tar");
  149. if (ret != 0) {
  150. [view writeText:@"failed!"];
  151. [view writeTextPlain:@"injecting trust to /meridian/tar failed with retcode %d", ret];
  152. return 1;
  153. }
  154. [view writeText:@"done!"];
  155. // extract meridian-bootstrap
  156. [view writeText:@"extracting meridian files..."];
  157. ret = extractMeridianData();
  158. if (ret != 0) {
  159. [view writeText:@"failed!"];
  160. [view writeTextPlain:[NSString stringWithFormat:@"error code: %d", ret]];
  161. return 1;
  162. }
  163. [view writeText:@"done!"];
  164. // dump offsets to file for later use (/meridian/offsets.plist)
  165. dumpOffsetsToFile(&offsets, kernel_base, kslide);
  166. // patch amfid
  167. [view writeText:@"patching amfid..."];
  168. ret = defecateAmfi();
  169. if (ret != 0) {
  170. [view writeText:@"failed!"];
  171. if (ret > 0) {
  172. [view writeTextPlain:[NSString stringWithFormat:@"failed to patch - %d tries", ret]];
  173. }
  174. return 1;
  175. }
  176. [view writeText:@"done!"];
  177. // touch .cydia_no_stash
  178. touch_file("/.cydia_no_stash");
  179. // symlink /Library/MobileSubstrate/DynamicLibraries -> /usr/lib/tweaks
  180. //setUpSymLinks();
  181. // remove Substrate's SafeMode (MobileSafety) if it's installed
  182. // removing from dpkg will be handled by Cydia conflicts later
  183. if (file_exists("/usr/lib/tweaks/MobileSafety.dylib") == 0) {
  184. unlink("/usr/lib/tweaks/MobileSafety.dylib");
  185. }
  186. if (file_exists("/usr/lib/tweaks/MobileSafety.plist") == 0) {
  187. unlink("/usr/lib/tweaks/MobileSafety.plist");
  188. }
  189. // extract bootstrap (if not already extracted)
  190. if (file_exists("/meridian/.bootstrap") != 0) {
  191. [view writeText:@"extracting bootstrap..."];
  192. int exitCode = 0;
  193. ret = extractBootstrap(&exitCode);
  194. if (ret != 0) {
  195. [view writeText:@"failed!"];
  196. switch (ret) {
  197. case 1:
  198. [view writeTextPlain:@"failed to extract system-base.tar"];
  199. break;
  200. case 2:
  201. [view writeTextPlain:@"failed to extract installer-base.tar"];
  202. break;
  203. case 3:
  204. [view writeTextPlain:@"failed to extract dpkgdb-base.tar"];
  205. break;
  206. case 4:
  207. [view writeTextPlain:@"failed to extract cydia-base.tar"];
  208. break;
  209. case 5:
  210. [view writeTextPlain:@"failed to extract optional-base.tar"];
  211. break;
  212. case 6:
  213. [view writeTextPlain:@"failed to run uicache!"];
  214. break;
  215. }
  216. [view writeTextPlain:@"exit code: %d", exitCode];
  217. return 1;
  218. }
  219. [view writeText:@"done!"];
  220. }
  221. //unlink("/usr/lib/libjailbreak.dylib");
  222. //cp("/usr/lib/libjailbreak.dylib","/electra/libjailbreak.dylib");
  223. /*
  224. // add the midnight repo
  225. if (file_exists("/etc/apt/sources.list.d/meridian.list") != 0) {
  226. FILE *fd = fopen("/etc/apt/sources.list.d/meridian.list", "w+");
  227. const char *text = "deb http://repo.midnight.team ./";
  228. fwrite(text, strlen(text) + 1, 1, fd);
  229. fclose(fd);
  230. }
  231. */
  232. pid_t pd;
  233. //posix_spawn(&pd, "/bin/bash", NULL, NULL, (char **)&(const char*[]){ "bash", "/usr/libexec/nito/firmware.sh", NULL }, NULL);
  234. //waitpid(pd, NULL, 0);
  235. posix_spawn(&pd, "/bin/bash", NULL, NULL, (char **)&(const char*[]){ "bash", "/Library/dpkg/info/openssh.postinst", NULL }, NULL);
  236. waitpid(pd, NULL, 0);
  237. // posix_spawn(&pd, "/bin/launchctl", NULL, NULL, (char **)&(const char*[]){ "launchctl", "load", "/Library/LaunchDaemons/com.openssh.sshd.plist", NULL }, NULL);
  238. // waitpid(pd, NULL, 0);
  239. //fixPerms();
  240. // launch dropbear
  241. [view writeText:@"launching dropbear..."];
  242. ret = launchDropbear();
  243. if (ret != 0) {
  244. [view writeText:@"failed!"];
  245. [view writeTextPlain:@"exit code: %d", ret];
  246. return 1;
  247. }
  248. //launch openssh
  249. [view writeText:@"Launching openssh..."];
  250. ret = start_launchdaemon("/Library/LaunchDaemons/com.openssh.sshd.plist");
  251. if (ret != 0) {
  252. [view writeText:@"failed!"];
  253. [view writeTextPlain:@"exit code: %d", ret];
  254. //return 1;
  255. }
  256. [view writeText:@"done!"];
  257. // link substitute stuff
  258. //setUpSubstitute();
  259. // start jailbreakd
  260. ret = inject_trust("/meridian/inject_criticald");
  261. //ret = inject_trust("/electra/amfid_payload.dylib");
  262. //ret = inject_trust("/electra/pspawn_payload.dylib");
  263. //ret = inject_trust("/electra/libjailbreak.dylib");
  264. /*
  265. "/electra/inject_criticald",
  266. "/electra/amfid_payload.dylib",
  267. "/electra/pspawn_payload.dylib",
  268. "/electra/libjailbreak.dylib"
  269. */
  270. //if (ret != 0) return -1;
  271. [view writeText:@"starting jailbreakd..."];
  272. ret = startJailbreakd();
  273. if (ret != 0) {
  274. [view writeText:@"failed"];
  275. if (ret > 1) {
  276. [view writeTextPlain:@"failed to launch - %d tries", ret];
  277. }
  278. return 1;
  279. }
  280. [view writeText:@"done!"];
  281. // patch com.apple.System.boot-nonce
  282. [view writeText:@"patching boot-nonce..."];
  283. ret = nvpatch("com.apple.System.boot-nonce");
  284. if (ret != 0) {
  285. [view writeText:@"failed!"];
  286. return 1;
  287. }
  288. [view writeText:@"done!"];
  289. // load launchdaemons
  290. [view writeText:@"loading launchdaemons..."];
  291. ret = loadLaunchDaemons();
  292. if (ret != 0) {
  293. [view writeText:@"failed!"];
  294. return 1;
  295. }
  296. [view writeText:@"done!"];
  297. great_success = TRUE;
  298. return 0;
  299. }
  300. void fixPerms() {
  301. int rv = execprog("/usr/bin/chmod", (const char **)&(const char*[]) {
  302. "/usr/bin/chmod",
  303. "-R",
  304. "0700",
  305. "/private/var/root/.ssh",
  306. NULL
  307. });
  308. rv = execprog("/usr/bin/chmod", (const char **)&(const char*[]) {
  309. "/usr/bin/chmod",
  310. "-R",
  311. "0700",
  312. "/private/etc/dropbear",
  313. NULL
  314. });
  315. }
  316. kern_return_t callback(task_t kern_task, kptr_t kbase, void *cb_data) {
  317. tfp0 = kern_task;
  318. kernel_base = kbase;
  319. kslide = kernel_base - 0xFFFFFFF007004000;
  320. return KERN_SUCCESS;
  321. }
  322. int runV0rtex() {
  323. offsets_t *offs = get_offsets();
  324. if (offs == NULL) {
  325. return -420;
  326. }
  327. offsets = *offs;
  328. int ret = v0rtex(&offsets, &callback, NULL);
  329. uint64_t kernel_task_addr = rk64(offs->kernel_task + kslide);
  330. kernprocaddr = rk64(kernel_task_addr + offs->task_bsd_info);
  331. kern_ucred = rk64(kernprocaddr + offs->proc_ucred);
  332. if (ret == 0) {
  333. NSLog(@"tfp0: 0x%x", tfp0);
  334. NSLog(@"kernel_base: 0x%llx", kernel_base);
  335. NSLog(@"kslide: 0x%llx", kslide);
  336. NSLog(@"kern_ucred: 0x%llx", kern_ucred);
  337. NSLog(@"kernprocaddr: 0x%llx", kernprocaddr);
  338. }
  339. return ret;
  340. }
  341. int patchContainermanagerd() {
  342. uint64_t cmgr = find_proc_by_name("containermanager");
  343. if (cmgr == 0) {
  344. NSLog(@"unable to find containermanager!");
  345. return 1;
  346. }
  347. wk64(cmgr + 0x100, kern_ucred);
  348. return 0;
  349. }
  350. int remountRootFs() {
  351. NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
  352. int pre130 = osVersion.minorVersion < 2 ? 1 : 0;
  353. int rv = mount_root(kslide, offsets.root_vnode, pre130);
  354. if (rv != 0) {
  355. return 1;
  356. }
  357. return 0;
  358. }
  359. int extractMeridianData() {
  360. int rv = extract_bundle_tar("meridian-bootstrap.tar");
  361. unlink("/usr/bin/cynject");
  362. unlink("/usr/bin/cycc");
  363. symlink("/meridian/inject_criticald", "/usr/bin/cynject"); //mimic cynject
  364. symlink("/usr/bin/ssh", "/usr/local/bin/"); //get scp working
  365. //rv = extract_bundle_tar("basebinaries.tar");
  366. return rv;
  367. }
  368. void setUpSymLinks() {
  369. struct stat file;
  370. stat("/Library/MobileSubstrate/DynamicLibraries", &file);
  371. if (file_exists("/Library/MobileSubstrate/DynamicLibraries") == 0 &&
  372. file_exists("/usr/lib/tweaks") == 0 &&
  373. S_ISLNK(file.st_mode)) {
  374. return;
  375. }
  376. // By the end of this check, /usr/lib/tweaks should exist containing any
  377. // tweaks (if applicable), and /Lib/MobSub/DynLib should NOT exist
  378. if (file_exists("/Library/MobileSubstrate/DynamicLibraries") == 0 &&
  379. file_exists("/usr/lib/tweaks") != 0) {
  380. // Move existing tweaks folder to /usr/lib/tweaks
  381. [[NSFileManager defaultManager] moveItemAtPath:@"/Library/MobileSubstrate/DynamicLibraries" toPath:@"/usr/lib/tweaks" error:nil];
  382. } else if (file_exists("/Library/MobileSubstrate/DynamicLibraries") == 0 &&
  383. file_exists("/usr/lib/tweaks") == 0) {
  384. // Move existing tweaks to /usr/lib/tweaks and delete the MobSub folder
  385. NSArray *fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/Library/MobileSubstrate/DynamicLibraries" error:nil];
  386. for (NSString *item in fileList) {
  387. NSString *fullPath = [NSString stringWithFormat:@"/Library/MobileSubstrate/DynamicLibraries/%@", item];
  388. [[NSFileManager defaultManager] moveItemAtPath:fullPath toPath:@"/usr/lib/tweaks" error:nil];
  389. }
  390. [[NSFileManager defaultManager] removeItemAtPath:@"/Library/MobileSubstrate/DynamicLibraries" error:nil];
  391. } else if (file_exists("/Library/MobileSubstrate/DynamicLibraries") != 0 &&
  392. file_exists("/usr/lib/tweaks") != 0) {
  393. // Just create /usr/lib/tweaks - /Lib/MobSub/DynLibs doesn't exist
  394. mkdir("/Library/MobileSubstrate", 0755);
  395. mkdir("/usr/lib/tweaks", 0755);
  396. } else if (file_exists("/Library/MobileSubstrate/DynamicLibraries") != 0 &&
  397. file_exists("/usr/lib/tweaks") == 0) {
  398. // We should be fine in this case
  399. mkdir("/Library/MobileSubstrate", 0755);
  400. }
  401. // Symlink it!
  402. symlink("/usr/lib/tweaks", "/Library/MobileSubstrate/DynamicLibraries");
  403. }
  404. void extractGz_merd(const char *from, const char *to) {
  405. NSData *gz = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@(from) ofType:@"gz"]];
  406. NSData *extracted = [gz gunzippedData];
  407. [extracted writeToFile:@(to) atomically:YES];
  408. }
  409. int extractBootstrap(int *exitCode) {
  410. int rv;
  411. unlink("/meridian/bootstrap.tar");
  412. extractGz_merd("bootstrap.tar", "/meridian/bootstrap.tar");
  413. rv = extract_tar("/meridian/bootstrap.tar");
  414. if (rv != 0) {
  415. *exitCode = rv;
  416. return 1;
  417. }
  418. // rv = uicache();
  419. // if (rv != 0) {
  420. // *exitCode = rv;
  421. // return 6;
  422. // }
  423. touch_file("/meridian/.bootstrap");
  424. touch_file("/var/mobile/Library/Preferences/.kickstart");
  425. //touch_file("/var/mobile/Library/Preferences/.nitolaunch");
  426. pid_t pd;
  427. posix_spawn(&pd, "/bin/bash", NULL, NULL, (char **)&(const char*[]){ "bash", "/usr/libexec/nito/firmware.sh", NULL }, NULL);
  428. waitpid(pd, NULL, 0);
  429. char *myenviron[] = {
  430. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games",
  431. "PS1=\\h:\\w \\u\\$ ",
  432. NULL
  433. };
  434. posix_spawn(&pd, "/usr/bin/dpkg", NULL, NULL, (char **)&(const char*[]){ "dpkg", "-i", "--refuse-downgrade", progname("nitotv.deb"), NULL }, (char **)&myenviron);
  435. waitpid(pd, NULL, 0);
  436. return 0;
  437. }
  438. int old_extractBootstrap(int *exitCode) {
  439. int rv;
  440. // extract system-base.tar
  441. rv = extract_bundle_tar("system-base.tar");
  442. if (rv != 0) {
  443. *exitCode = rv;
  444. return 1;
  445. }
  446. // extract installer-base.tar
  447. rv = extract_bundle_tar("installer-base.tar");
  448. if (rv != 0) {
  449. *exitCode = rv;
  450. return 2;
  451. }
  452. if (file_exists("/private/var/lib/dpkg/status") != 0) {
  453. rv = extract_bundle_tar("dpkgdb-base.tar");
  454. if (rv != 0) {
  455. *exitCode = rv;
  456. return 3;
  457. }
  458. }
  459. // extract cydia-base.tar
  460. rv = extract_bundle_tar("cydia-base.tar");
  461. if (rv != 0) {
  462. *exitCode = rv;
  463. return 4;
  464. }
  465. // extract optional-base.tar
  466. rv = extract_bundle_tar("optional-base.tar");
  467. if (rv != 0) {
  468. *exitCode = rv;
  469. return 5;
  470. }
  471. //enableHiddenApps();
  472. touch_file("/meridian/.bootstrap");
  473. rv = uicache();
  474. if (rv != 0) {
  475. *exitCode = rv;
  476. return 6;
  477. }
  478. return 0;
  479. }
  480. int newdefecateAmfi() {
  481. #define BinaryLocation "/electra/inject_criticald"
  482. pid_t amfid_pid = get_pid_for_name("amfid");
  483. if (amfid_pid == 0) {
  484. return -2;
  485. }
  486. pid_t pd;
  487. int rv = 0;
  488. const char* args_amfid[] = {BinaryLocation, itoa(amfid_pid), "/electra/amfid_payload.dylib", NULL};
  489. rv = posix_spawn(&pd, BinaryLocation, NULL, NULL, (char **)&args_amfid, NULL);
  490. waitpid(pd, NULL, 0);
  491. unlink("/.amfid_success");
  492. const char *args_helloworld[] = {"helloworld", NULL};
  493. rv = posix_spawn(&pd, "/electra/helloworld", NULL, NULL, (char **)&args_helloworld, NULL);
  494. waitpid(pd, NULL, 0);
  495. if (!file_exists("/.amfid_success")){
  496. return -3;
  497. }
  498. unlink("/.amfid_success");
  499. return 0;
  500. }
  501. int defecateAmfi() {
  502. // write kslide to file
  503. unlink("/meridian/kernel_slide");
  504. FILE *fd = fopen("/meridian/kernel_slide", "w");
  505. fprintf(fd, "%016llx", kslide);
  506. fclose(fd);
  507. int ret = inject_trust("/meridian/inject_criticald");
  508. if (ret != 0) return -1;
  509. // trust our payload
  510. ret = inject_trust("/meridian/amfid_payload.dylib");
  511. if (ret != 0) return -1;
  512. unlink("/var/tmp/amfid_payload.alive");
  513. pid_t pid = get_pid_for_name("amfid");
  514. if (pid == 0) {
  515. return -2;
  516. }
  517. ret = inject_library(pid, "/meridian/amfid_payload.dylib");
  518. if (ret != 0) return -2;
  519. int tries = 0;
  520. while (file_exists("/var/tmp/amfid_payload.alive") != 0) {
  521. if (tries >= 100) {
  522. NSLog(@"failed to patch amfid (%d tries)", tries);
  523. return tries;
  524. }
  525. NSLog(@"waiting for amfid patch...");
  526. usleep(100000); // 0.1 sec
  527. tries++;
  528. }
  529. return 0;
  530. }
  531. int launchDropbear() {
  532. return start_launchdaemon("/Library/LaunchDaemons/dropbear.plist");
  533. }
  534. void setUpSubstitute() {
  535. // link CydiaSubstrate.framework -> /usr/lib/libsubstrate.dylib
  536. if (file_exists("/Library/Frameworks/CydiaSubstrate.framework") == 0) {
  537. [[NSFileManager defaultManager] removeItemAtPath:@"/Library/Frameworks/CydiaSubstrate.framework" error:nil];
  538. }
  539. mkdir("/Library/Frameworks", 0755);
  540. mkdir("/Library/Frameworks/CydiaSubstrate.framework", 0755);
  541. symlink("/usr/lib/libsubstrate.dylib", "/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate");
  542. }
  543. int start_jailbreakd_e() {
  544. unlink("/var/tmp/jailbreakd.pid");
  545. unlink("/var/run/jailbreakd.pid");
  546. unlink("/var/log/jailbreakd-stderr.log");
  547. unlink("/var/log/jailbreakd-stdout.log");
  548. NSData *blob = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"jailbreakd" ofType:@"plist"]];
  549. NSMutableDictionary *job = [NSPropertyListSerialization propertyListWithData:blob options:NSPropertyListMutableContainers format:nil error:nil];
  550. job[@"EnvironmentVariables"][@"KernelBase"] = [NSString stringWithFormat:@"0x%16llx", kernel_base];
  551. [job writeToFile:@"/Library/LaunchDaemons/jailbreakd.plist" atomically:YES];
  552. chmod("/Library/LaunchDaemons/jailbreakd.plist", 0644);
  553. chown("/Library/LaunchDaemons/jailbreakd.plist", 0, 0);
  554. pid_t pid = 0;
  555. //int rv = run("/bin/launchctl load /Library/LaunchDaemons/jailbreakd.plist");
  556. int rv = start_launchdaemon("/Library/LaunchDaemons/jailbreakd.plist");
  557. if (rv == -1) {
  558. return -1;
  559. }
  560. int ex = 0;
  561. waitpid(pid, &ex, 0);
  562. NSLog(@"The dragon becomes me!");
  563. NSLog(@"once it is drawn, it cannot be sheathed without causing death");
  564. return 0;
  565. }
  566. int startJailbreakd() {
  567. unlink("/var/tmp/jailbreakd.pid");
  568. NSData *blob = [NSData dataWithContentsOfFile:@"/meridian/jailbreakd/jailbreakd.plist"];
  569. NSMutableDictionary *job = [NSPropertyListSerialization propertyListWithData:blob options:NSPropertyListMutableContainers format:nil error:nil];
  570. job[@"EnvironmentVariables"][@"KernelBase"] = [NSString stringWithFormat:@"0x%16llx", kernel_base];
  571. job[@"EnvironmentVariables"][@"KernProcAddr"] = [NSString stringWithFormat:@"0x%16llx", kernprocaddr];
  572. job[@"EnvironmentVariables"][@"ZoneMapOffset"] = [NSString stringWithFormat:@"0x%16llx", offsets.zone_map];
  573. [job writeToFile:@"/meridian/jailbreakd/jailbreakd.plist" atomically:YES];
  574. chmod("/meridian/jailbreakd/jailbreakd.plist", 0600);
  575. chown("/meridian/jailbreakd/jailbreakd.plist", 0, 0);
  576. int rv = start_launchdaemon("/meridian/jailbreakd/jailbreakd.plist");
  577. if (rv != 0) return 1;
  578. int tries = 0;
  579. while (file_exists("/var/tmp/jailbreakd.pid") != 0) {
  580. printf("Waiting for jailbreakd \n");
  581. tries++;
  582. usleep(300000); // 300ms
  583. if (tries >= 100) {
  584. NSLog(@"too many tries for jbd - %d", tries);
  585. return tries;
  586. }
  587. }
  588. usleep(100000);
  589. // tell jailbreakd to platformize launchd
  590. // this adds skip-lib-val to MACF slot and allows us
  591. // to inject pspawn without it being in trust cache
  592. // (plus FAT/multiarch in trust cache is a pain to code, i'm lazy)
  593. rv = call_jailbreakd(JAILBREAKD_COMMAND_ENTITLE, 1);
  594. if (rv != 0) return 2;
  595. // inject pspawn_hook.dylib to launchd
  596. rv = inject_library(1, "/usr/lib/pspawn_hook.dylib");
  597. //rv = inject_library(1, "/meridian/pspawn_payload.dylib");
  598. if (rv != 0) return 3;
  599. /*
  600. rv = execprog("/meridian/inject_criticald", (const char **)&(const char*[]) {
  601. "/meridian/inject_criticald",
  602. "1",
  603. "/meridian/pspawn_payload.dylib",
  604. NULL
  605. });
  606. if (rv != 0) return 3;
  607. */
  608. return 0;
  609. }
  610. int loadLaunchDaemons() {
  611. NSArray *daemons = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/Library/LaunchDaemons" error:nil];
  612. for (NSString *file in daemons) {
  613. NSString *path = [NSString stringWithFormat:@"/Library/LaunchDaemons/%@", file];
  614. NSLog(@"found launchdaemon: %@", path);
  615. chmod([path UTF8String], 0755);
  616. chown([path UTF8String], 0, 0);
  617. }
  618. return start_launchdaemon("/Library/LaunchDaemons");
  619. }
  620. void enableHiddenApps() {
  621. // enable showing of system apps on springboard
  622. // this is some funky killall stuff tho
  623. killall("cfprefsd", "-SIGSTOP");
  624. NSMutableDictionary* md = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.apple.springboard.plist"];
  625. [md setObject:[NSNumber numberWithBool:YES] forKey:@"SBShowNonDefaultSystemApps"];
  626. [md writeToFile:@"/var/mobile/Library/Preferences/com.apple.springboard.plist" atomically:YES];
  627. killall("cfprefsd", "-9");
  628. }