jailbreak.m 24 KB

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