jailbreak.m 25 KB

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