forked from akusio/KernBypass-Public
-
Notifications
You must be signed in to change notification settings - Fork 25
/
jelbrekLib.h
584 lines (529 loc) · 14.7 KB
/
jelbrekLib.h
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
typedef int (*kexecFunc)(uint64_t function, size_t argument_count, ...);
typedef char hash_t[20];
extern uint32_t KASLR_Slide;
extern uint64_t KernelBase;
extern mach_port_t TFP0;
extern kexecFunc kernel_exec;
typedef bool BOOL;
/*
Purpose: Initialize jelbrekLib (first thing you have to call)
Parameters:
kernel task port (tfp0)
Return values:
1: tfp0 port not valid
2: Something messed up while finding the kernel base
3: patchfinder didn't initialize properly
4: kernelSymbolFinder didn't initialize properly
*/
typedef int (*kexecFunc)(uint64_t function, size_t argument_count, ...);
int init_jelbrek(mach_port_t tfpzero);
int init_with_kbase(mach_port_t tfpzero, uint64_t kernelBase, kexecFunc kexec); // iOS 12
/*
Purpose: Free memory used by jelbrekLib & clean up (last thing you have to call)
*/
void term_jelbrek(void);
/*
Purpose:
Add a macho binary on the AMFI trustcache
Parameters:
A path to single macho or a directory for recursive patching
Return values:
-1: path doesn't exist
-2: Couldn't find valid macho in directory
2: Binary not an executable
3: Binary bigger than 0x4000 bytes or something weird happened when running lstat
4: Permission denied when trying to open file
5: Something weird happened when reading data from the file
6: Binary is not a macho
7: file mmap() failed
*/
int trustbin(const char *path);
int trust_hash(hash_t hash);
/*
Purpose:
Bypass all codesign checks for a macho. Binary can be signed with SHA1 or SHA256
Parameters:
A path to a macho
Return values:
-1: error
0: success
*/
int bypassCodeSign(const char *macho);
/*
Purpose:
Unsandboxes a process
Parameters:
The process ID
Return values:
pointer to original sandbox slot: successfully unsandboxed or already unsandboxed
false: something went wrong
*/
uint64_t unsandbox(pid_t pid);
/*
Purpose:
Sandboxes a process
Parameters:
The process ID
Kernel pointer to sandbox slot
Return values:
true: successfully sandboxed
false: something went wrong
*/
BOOL sandbox(pid_t pid, uint64_t sb);
/*
Purpose:
Sets special codesigning flags on a process
Parameters:
The process ID
Return values:
true: successfully patched or already has flags
false: something went wrong
*/
BOOL setcsflags(pid_t pid);
/*
Purpose:
Patches the UID & GID of a process to 0
Parameters:
The process ID
Return values:
true: successfully patched or already has root
false: something went wrong
*/
BOOL rootify(pid_t pid);
/*
Purpose:
Sets TF_PLATFORM flag on a process & CS_PLATFORM_BINARY csflag
Parameters:
The process ID
Return values:
true: successfully patched or already has root
false: something went wrong
*/
void platformize(pid_t pid);
/*
Purpose:
Adds a new entitlement on ones stored by AMFI (not the actual entitlements of csblob)
Parameters:
The process ID
The entitlement (eg. com.apple.private.skip-library-validation)
Entitlement value, either true or false
Return values:
true: successfully patched or already has entitlement
false: something went wrong
*/
BOOL entitlePidOnAMFI(pid_t pid, const char *ent, BOOL val);
/*
Purpose:
Replaces entitlements stored on the csblob & ones on AMFI. Differently from above function this will FULLY REPLACE entitlements. Adding new ones on top is doable but for now this works.
Parameters:
The process ID
The entitlement string (e.g. "<key>task_for_pid-allow</key><true/>")
Return values:
true: successfully patched
false: something went wrong
*/
BOOL patchEntitlements(pid_t pid, const char *entitlementString);
/*
Purpose:
Adds file sandbox exceptions
Parameters:
Process ID
The entitlement key corresponding to the type of exception (e.g. com.apple.security.exception.files.absolute-path.read-only)
An pointer to a string array with non-slash-terminated paths & NULL as last member
(e.g.):
const char* path_exceptions[] = {
"/Library",
NULL
};
*/
bool addSandboxExceptionsToPid(pid_t pid, char *ent_key, char **paths);
/*
Purpose:
Borrows credentials from another process ID
Parameters:
The target's process ID
The donor's process ID
Return values:
Original credentials (use to revert later)
*/
uint64_t borrowCredsFromPid(pid_t target, pid_t donor);
/*
Purpose:
Spawns a binary and borrows credentials from it
Parameters:
The target's process ID
The donor binary path & up to 6 arguments (Leave NULL if not using)
Return values:
Success: Original credentials (use to revert later)
Error: posix_spawn return value
*/
uint64_t borrowCredsFromDonor(pid_t target, char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env);
/*
Purpose:
Undoes crenetial dontaion
Parameters:
The target's process ID
The original credentials
*/
void undoCredDonation(pid_t target, uint64_t origcred);
/*
Purpose:
Spawn a process as platform binary
Parameters:
Binary path
Up to 6 arguments (Leave NULL if not using)
environment variables (Leave NULL if not using)
Return values:
Success: child exit status
Error: posix_spawn return value
*/
int launchAsPlatform(char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env);
/*
Purpose:
Spawn a process
Parameters:
Binary path
Up to 6 arguments (Leave NULL if not using)
environment variables (Leave NULL if not using)
Return values:
Success: child exit status
Error: posix_spawn return value
*/
int launch(char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env);
/*
Purpose:
Spawn a process suspended
Parameters:
Binary path
Up to 6 arguments (Leave NULL if not using)
environment variables (Leave NULL if not using)
Return values:
Success: child pid
Error: posix_spawn return value
*/
int launchSuspended(char *binary, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5, char *arg6, char**env);
/*
Purpose:
Mount a device as read and write on a specified path
Parameters:
Device name
Path to mount
Return values:
mount() return value
*/
int mountDevAtPathAsRW(const char* devpath, const char* path);
/*
Purpose:
Mount / as read and write on iOS 10.3-11.4b3
Return values:
0: mount succeeded
-1: mount failed
*/
int remountRootFS(void);
/*
Purpose:
Get the kernel vnode pointer for a specified path
Parameters:
Target path
Return values:
Vnode pointer of path
*/
uint64_t getVnodeAtPath(const char *path);
/*
Purpose:
Same effect as "ln -sf replacement original" but not persistent through reboots
Parameters:
"original": path you wish to patch
"replacement": where to link the original path
vnode1 & vnode2: pointers where addresses of the two files vnodes will be stored OR NULL
*/
void copyFileInMemory(char *original, char *replacement, uint64_t *vnode1, uint64_t *vnode2);
/*
Purpose:
Do a hex dump I guess
Parameters:
Address in kernel from where to get data
Size of data to get
*/
void HexDump(uint64_t addr, size_t size);
/*
Purpose:
Execute code within the kernel
Parameters:
Slid address of function
Up to 7 arguments
Return address:
Return address of called function (must call ZmFixAddr before using returned pointers)
*/
uint64_t Kernel_Execute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
uint64_t ZmFixAddr(uint64_t addr);
/*
Purpose:
Find a kernel symbol
Parameters:
Name of symbol
Whether to print info or not
Return value:
Address of kernel symbol
*/
uint64_t find_symbol(const char *symbol, bool verbose); //powered by kernelSymbolFinder ;)
/*
Purpose:
Remap tfp0 as host special port 4
Return value:
1: Error
0: Success
*/
int setHSP4(void);
/*
Purpose:
Patch host type to make hgsp() work
Parameters:
host port. mach_host_self() for the host port of this process
Return value:
YES: Success or already good
NO: Failure
WARNING:
DO **NOT** USE WITH mach_host_self() ON A PROCESS THAT WAS MEANT TO RUN AS "mobile" (ANY app),
ON A DEVICE WITH SENSTIVE INFORMATION OR IN A NON-DEVELOPER JAILBREAK
THAT IN COMBINATION WITH setHSP4() WILL GIVE ANY APP THE ABILITY TO GET THE KERNEL TASK, FULL CONTROL OF YOUR DEVICE
On a developer device, you can do that and will probably be very helpful for debugging :)
The original idea was implemented by Ian Beer. Another example of this patch can be found inside FakeHostPriv() which creates a dummy port which acts like mach_host_self() of a root process
*/
BOOL PatchHostPriv(mach_port_t host);
/*
Purpose:
Unlock nvram memory
*/
void UnlockNVRAM(void);
/*
Purpose:
Relock nvram memory. unlocknvmram() must have been used beforehand
Return value:
-1: Error
0: Success
*/
int LockNVRAM(void);
/*
Purpose:
Brute force KASLR and find kernel base
Return value:
Kernel base?
*/
uint64_t FindKernelBase(void);
/*
Purpose:
Internal vnode utilities
*/
int vnode_lookup(const char *path, int flags, uint64_t *vnode, uint64_t vfs_context);
uint64_t get_vfs_context(void);
int vnode_put(uint64_t vnode);
/*
Purpose:
Internal snapshot utilities
*/
int list_snapshots(const char *vol);
char *find_system_snapshot(void);
int do_rename(const char *vol, const char *snap, const char *nw);
char *copyBootHash(void);
int mountSnapshot(const char *vol, const char *name, const char *dir);
int snapshot_check(const char *vol, const char *name);
/*
Purpose:
Patchfinding (by xerub & ninjaprawn & me)
*/
uint64_t Find_allproc(void);
uint64_t Find_add_x0_x0_0x40_ret(void);
uint64_t Find_copyout(void);
uint64_t Find_bzero(void);
uint64_t Find_bcopy(void);
uint64_t Find_rootvnode(void);
uint64_t Find_trustcache(void);
uint64_t Find_amficache(void);
uint64_t Find_pmap_load_trust_cache_ppl(void);
uint64_t Find_OSBoolean_True(void);
uint64_t Find_OSBoolean_False(void);
uint64_t Find_zone_map_ref(void);
uint64_t Find_osunserializexml(void);
uint64_t Find_smalloc(void);
uint64_t Find_sbops(void);
uint64_t Find_bootargs(void);
uint64_t Find_vfs_context_current(void);
uint64_t Find_vnode_lookup(void);
uint64_t Find_vnode_put(void);
uint64_t Find_cs_gen_count(void);
uint64_t Find_cs_validate_csblob(void);
uint64_t Find_kalloc_canblock(void);
uint64_t Find_cs_blob_allocate_site(void);
uint64_t Find_kfree(void);
uint64_t Find_cs_find_md(void);
// PAC
uint64_t Find_l2tp_domain_module_start(void);
uint64_t Find_l2tp_domain_module_stop(void);
uint64_t Find_l2tp_domain_inited(void);
uint64_t Find_sysctl_net_ppp_l2tp(void);
uint64_t Find_sysctl_unregister_oid(void);
uint64_t Find_mov_x0_x4__br_x5(void);
uint64_t Find_mov_x9_x0__br_x1(void);
uint64_t Find_mov_x10_x3__br_x6(void);
uint64_t Find_kernel_forge_pacia_gadget(void);
uint64_t Find_kernel_forge_pacda_gadget(void);
uint64_t Find_IOUserClient_vtable(void);
uint64_t Find_IORegistryEntry__getRegistryEntryID(void);
/*
Purpose:
Internal utilities
*/
uint64_t TaskSelfAddr(void);
uint64_t IPCSpaceKernel(void);
uint64_t FindPortAddress(mach_port_name_t port);
mach_port_t FakeHostPriv(void);
void convertPortToTaskPort(mach_port_t port, uint64_t space, uint64_t task_kaddr);
void MakePortFakeTaskPort(mach_port_t port, uint64_t task_kaddr);
/*
Purpose:
For reading & writing & copying & allocating & freeing kernel memory
*/
size_t KernelRead(uint64_t where, void *p, size_t size);
size_t KernelWrite(uint64_t where, void *p, size_t size);
uint32_t KernelRead_32bits(uint64_t where);
uint64_t KernelRead_64bits(uint64_t where);
size_t kwrite(uint64_t where, const void *p, size_t size);
void KernelWrite_32bits(uint64_t where, uint32_t what);
void KernelWrite_64bits(uint64_t where, uint64_t what);
void Kernel_memcpy(uint64_t dest, uint64_t src, uint32_t length);
void Kernel_free(mach_vm_address_t address, vm_size_t size);
uint64_t Kernel_alloc(vm_size_t size);
uint64_t Kernel_alloc_wired(uint64_t size);
/*
Purpose:
Find proc struct on kernel
Parameters:
Process ID
Return values:
Kernel pointer to proc struct or 0 on error
*/
uint64_t proc_of_pid(pid_t pid);
/*
Purpose:
Find proc struct on kernel
Parameters:
Process name
Return values:
Kernel pointer to proc struct or 0 on error
*/
uint64_t proc_of_procName(char *nm);
/*
Purpose:
Find pid of process
Parameters:
Process name
Return values:
Process ID of process or -1 on error
*/
unsigned int pid_of_procName(char *nm);
/*
Purpose:
Find the task struct of a pid
Parameters:
Process ID
Return values:
Kernel pointer to task struct or 0 on error
*/
uint64_t taskStruct_of_pid(pid_t pid);
/*
Purpose:
Find the task struct of a process
Parameters:
Process name
Return values:
Kernel pointer to task struct or 0 on error
*/
uint64_t taskStruct_of_procName(char *nm);
/*
Purpose:
Find the kernel address of the task port of a PID
Parameters:
Process ID
Return values:
Kernel pointer of task port or 0 on error
*/
uint64_t taskPortKaddr_of_pid(pid_t pid);
/*
Purpose:
Find the kernel address of the task port of a process
Parameters:
Process name
Return values:
Kernel pointer of task port or 0 on error
*/
uint64_t taskPortKaddr_of_procName(char *nm);
/*
Purpose:
task_for_pid without special entitlements :)
Parameters:
Process ID
Return values:
Process task port or MACH_PORT_NULL on error
*/
mach_port_t task_for_pid_in_kernel(pid_t pid);
/*
Purpose:
Inject dylib on process
Parameters:
Process ID
Path to dylib
Return values:
-1: Error
0: Success
*/
int inject_dylib(pid_t pid, char *loaded_dylib);
/*
Purpose:
Internal function used to set an exception handler for amfid
Parameters:
amfid's task port
Function pointer to an exception handler
Return values:
1: Error
0: Success
*/
int setAmfidExceptionHandler(mach_port_t amfid_task_port, void *(exceptionHandler)(void*));
/*
Purpose:
Patch amfid to allow fakesigned binaries to run
Return values:
On error: -1
On success: Address to the original MISValidateSignatureAndCopyInfo of amfid
*/
uint64_t patchAMFID(void);
/*
Purpose:
Make a path invisible
Parameters:
path
Return value:
true: Success
false: Failure
*/
BOOL hidePath(char *path);
/*
Purpose:
Allow mmap of executable from every process with read access to it
Parameters:
path
Return value:
true: Success
false: Failure
*/
BOOL fixMmap(char *path);
/*
Purpose:
Get fg_data for a file descriptor (a struct vnode for files, struct socket for sockets, struct pipe for pipes etc...)
Parameters:
The file descriptor
The pid the file descriptor belongs to
Return value:
proc->p_fd->fd_ofiles[fd]->fproc->fg_data;
*/
uint64_t dataForFD(int fd, int pid);