Skip to content

Commit

Permalink
Fix bootstrap and more
Browse files Browse the repository at this point in the history
  • Loading branch information
UInt2048 committed Jul 9, 2024
1 parent 7d2912c commit 75fdb57
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 100 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ endif
UNTETHER = lib$(TARGET_CLI).dylib
TRAMP = trampoline
ICONS := $(wildcard $(RES)/Icon-*.png)
FILES := $(TARGET_GUI) Info.plist Base.lproj/LaunchScreen.storyboardc $(ICONS:$(RES)/%=%) Unrestrict.dylib bootstrap.tar.lzma jailbreak-resources.deb mobilesubstrate.deb
FILES := $(TARGET_GUI) Info.plist Base.lproj/LaunchScreen.storyboardc $(ICONS:$(RES)/%=%) Unrestrict.dylib bootstrap.deb jailbreak-resources.deb mobilesubstrate.deb

SDK_FILE := src/untether/sdk.txt
SDK_RESULT := $(shell cat ${SDK_FILE})
Expand Down Expand Up @@ -75,9 +75,9 @@ $(APP)/Unrestrict.dylib:
echo Copying file to $@
cp $(RES)/Unrestrict.dylib $@

$(APP)/bootstrap.tar.lzma:
$(APP)/bootstrap.deb:
echo Copying file to $@
cp $(RES)/bootstrap.tar.lzma $@
cp $(RES)/spicebootstrap_1.0_iphoneos-arm.deb $@

$(APP)/jailbreak-resources.deb:
echo Copying file to $@
Expand Down
Binary file not shown.
113 changes: 53 additions & 60 deletions src/shared/jailbreak.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
sendLog(controller, [NSString stringWithFormat:@__VA_ARGS__]); \
LOG(__VA_ARGS__); \
} while (0)
#ifdef __LP64__
#define PWN_LOG_KPTR(...) PWN_LOG("%s %llx\n", __VA_ARGS__)
#define FORMAT_KERNEL @"0x%016llx"
#else
#define PWN_LOG_KPTR(...) PWN_LOG("%s %x\n", __VA_ARGS__)
#define FORMAT_KERNEL @"0x%08x"
#endif
#define updateStage(stage) PWN_LOG("Jailbreaking... (%d/21)", stage)

if (opt & JBOPT_POST_ONLY) {
Expand All @@ -83,7 +90,7 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
mach_msg_type_number_t cnt = TASK_DYLD_INFO_COUNT;
ASSERT_RET(out, "task_info", task_info(kernel_task, TASK_DYLD_INFO, (task_info_t)&info, &cnt));
kbase = info.all_image_info_addr;
PWN_LOG("kbase %llx\n", kbase);
PWN_LOG_KPTR("kbase", kbase);
} else {
// suspend_all_threads();

Expand All @@ -98,7 +105,7 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
}

kernel_slide = kbase - offs.constant.kernel_image_base;
PWN_LOG("kslide %llx\n", kernel_slide);
PWN_LOG_KPTR("kslide", kernel_slide);

if (!MACH_PORT_VALID(kernel_task)) {
PWN_LOG("invalid kernel task");
Expand All @@ -110,7 +117,7 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
kernproc = rk64(offs.data.kern_proc + kernel_slide);
VAL_CHECK(kernproc);

PWN_LOG("kernproc: %llx\n", kernproc);
PWN_LOG_KPTR("kernproc:", kernproc);

MACH(elevate_to_root());
updateStage(15);
Expand Down Expand Up @@ -239,45 +246,45 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
}
}

{
if ((opt & JBOPT_POST_ONLY) == 0) {
BOOL attemptFlag = NO;
if (access("/.spice_bootstrap_installed", F_OK) != 0) {
extract_bootstrap:
COPY_RESOURCE("bootstrap.tar.lzma", "/jb/bootstrap.tar.lzma");

if (access("/jb/bootstrap.tar.lzma", F_OK) != 0) {
PWN_LOG("failed to find the bootstrap file");
ret = KERN_FAILURE;
goto out;
}
BOOL attemptFlag = NO;
BOOL extractResult = YES;

PWN_LOG("extracting bootstrap...");

ArchiveFile* tar = [ArchiveFile archiveWithFile:@"/jb/bootstrap.tar.lzma"];
BOOL extractResult = [tar extractToPath:@"/"];
#define FIND_FAIL(path) \
do { \
if (access(path, F_OK) != 0) { \
PWN_LOG("Failed to find" path); \
ret = KERN_FAILURE; \
goto out; \
} \
} while (0)

if (!extractResult) {
PWN_LOG("failed to extract bootstrap!");
ret = KERN_FAILURE;
goto out;
}
#define EXTRACT_FAIL(path) \
do { \
if (!extractResult) { \
PWN_LOG("Failed to extract" path); \
ret = KERN_FAILURE; \
goto out; \
} \
} while (0)

COPY_RESOURCE("jailbreak-resources.deb", "/jb/jailbreak-resources.deb");
#define EXTRACT_DEB(path) \
do { \
FIND_FAIL(path); \
PWN_LOG("Extracting " path); \
extractResult = extractDeb(@path); \
EXTRACT_FAIL(path); \
} while (0)

if (access("/jb/jailbreak-resources.deb", F_OK) != 0) {
PWN_LOG("failed to find jailbreak-resources.deb");
ret = KERN_FAILURE;
goto out;
}
{
if ((opt & JBOPT_POST_ONLY) == 0) {

extractResult = extractDeb(@"/jb/jailbreak-resources.deb");
if (access("/.spice_bootstrap_installed", F_OK) != 0) {
extract_bootstrap:
COPY_RESOURCE("bootstrap.deb", "/jb/bootstrap.deb");
EXTRACT_DEB("/jb/bootstrap.deb");

if (!extractResult) {
PWN_LOG("failed to extract jailbreak-resources.deb!");
ret = KERN_FAILURE;
goto out;
}
COPY_RESOURCE("jailbreak-resources.deb", "/jb/jailbreak-resources.deb");
EXTRACT_DEB("/jb/jailbreak-resources.deb");

// Substrate is not in the bootstrap, so let's just install it
if (access("/usr/lib/libsubstitute.dylib", F_OK) == 0) {
Expand All @@ -289,21 +296,7 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
PWN_LOG("substrate was not found. installing it...");

COPY_RESOURCE("mobilesubstrate.deb", "/jb/mobilesubstrate.deb");

if (access("/jb/mobilesubstrate.deb", F_OK) != 0) {
PWN_LOG("tried to install substrate but failed to copy it!");
ret = KERN_FAILURE;
goto out;
}

BOOL extractResult = extractDeb(@"/jb/mobilesubstrate.deb");

if (!extractResult) {
PWN_LOG("attempted to install substrate but failed to extract it!");
ret = KERN_FAILURE;
goto out;
}

EXTRACT_DEB("/jb/mobilesubstrate.deb");
PWN_LOG("finished installing substrate");
}

Expand Down Expand Up @@ -420,15 +413,15 @@ kern_return_t jailbreak(uint32_t opt, void* controller, void (*sendLog)(void*, N
dict = [[NSMutableDictionary alloc] init];
}

dict[@"AddRetGadget"] = [NSString stringWithFormat:@"0x%016llx", offs.gadgets.add_x0_x0_ret + kernel_slide];
dict[@"KernProc"] = [NSString stringWithFormat:@"0x%016llx", offs.data.kern_proc + kernel_slide];
dict[@"OSBooleanTrue"] = [NSString stringWithFormat:@"0x%016llx", rk64(rk64(offs.data.osboolean_true + kernel_slide))];
dict[@"OSBooleanFalse"] = [NSString stringWithFormat:@"0x%016llx", rk64(rk64(offs.data.osboolean_true + 0x8 + kernel_slide))];
dict[@"OSUnserializeXML"] = [NSString stringWithFormat:@"0x%016llx", offs.funcs.osunserializexml + kernel_slide];
dict[@"ProcFind"] = [NSString stringWithFormat:@"0x%016llx", offs.funcs.proc_find + kernel_slide];
dict[@"ProcRele"] = [NSString stringWithFormat:@"0x%016llx", offs.funcs.proc_rele + kernel_slide];
dict[@"Smalloc"] = [NSString stringWithFormat:@"0x%016llx", offs.funcs.smalloc + kernel_slide];
dict[@"ZoneMapOffset"] = [NSString stringWithFormat:@"0x%016llx", offs.data.zone_map + kernel_slide];
dict[@"AddRetGadget"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.gadgets.add_x0_x0_ret + kernel_slide];
dict[@"KernProc"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.data.kern_proc + kernel_slide];
dict[@"OSBooleanTrue"] = [NSString stringWithFormat:FORMAT_KERNEL, (kptr_t)rk64(rk64(offs.data.osboolean_true + kernel_slide))];
dict[@"OSBooleanFalse"] = [NSString stringWithFormat:FORMAT_KERNEL, (kptr_t)rk64(rk64(offs.data.osboolean_true + 0x8 + kernel_slide))];
dict[@"OSUnserializeXML"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.funcs.osunserializexml + kernel_slide];
dict[@"ProcFind"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.funcs.proc_find + kernel_slide];
dict[@"ProcRele"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.funcs.proc_rele + kernel_slide];
dict[@"Smalloc"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.funcs.smalloc + kernel_slide];
dict[@"ZoneMapOffset"] = [NSString stringWithFormat:FORMAT_KERNEL, offs.data.zone_map + kernel_slide];

[dict writeToFile:@"/jb/offsets.plist" atomically:YES];
PWN_LOG("wrote offsets.plist");
Expand Down
18 changes: 14 additions & 4 deletions src/shared/kcall.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
static kmap_hdr_t zm_hdr;
const int fake_kalloc_size = 0x1000;

#ifdef __LP64__
#define LOG_KPTR(...) LOG("%s %llx\n", __VA_ARGS__)
#else
#define LOG_KPTR(...) LOG("%s %x\n", __VA_ARGS__)
#endif

mach_port_t prepare_user_client()
{
kern_return_t ret = KERN_SUCCESS;
Expand Down Expand Up @@ -94,15 +100,15 @@ kern_return_t init_kexecute(kptr_t zone_map, kptr_t add_ret_gadget)
// resolve zone map to set up zm_fix_addr
kptr_t zone_map_addr = rk64(zone_map + kernel_slide);
if (zone_map_addr == 0x0) {
LOG("wtf, failed to find zone map addr @ offset %llx", zone_map + kernel_slide);
LOG_KPTR("wtf, failed to find zone map addr @ offset", zone_map + kernel_slide);
return KERN_FAILURE;
}

kread(zone_map_addr + 0x10, (void*)&zm_hdr, sizeof(zm_hdr));

LOG("zone map start: %llx\n", zm_hdr.start);
LOG("zone map end: %llx\n", zm_hdr.end);
LOG("zone map size: %llx\n", zm_hdr.end - zm_hdr.start);
LOG_KPTR("zone map start:", zm_hdr.start);
LOG_KPTR("zone map end:", zm_hdr.end);
LOG_KPTR("zone map size:", zm_hdr.end - zm_hdr.start);

return KERN_SUCCESS;
}
Expand All @@ -125,7 +131,11 @@ void term_kexecute()
kptr_t kexecute(kptr_t addr, int n_args, ...)
{
if (fake_client == 0x0) {
#ifdef __LP64__
LOG("tried to kexecute on %llx with %d args when kexecute is not yet set up", addr, n_args);
#else
LOG("tried to kexecute on %x with %d args when kexecute is not yet set up", addr, n_args);
#endif
return -1;
}

Expand Down
31 changes: 22 additions & 9 deletions src/shared/pwn.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
} mach_msg_data_buffer_t;

kern_return_t (^kcall)(uint64_t, int, ...);
uint64_t (^zonemap_fix_addr)(uint64_t);
kptr_t (^zonemap_fix_addr)(kptr_t);

void (^kreadbuf)(uint64_t, void*, size_t);
void (^kwritebuf)(uint64_t, void*, size_t);
Expand Down Expand Up @@ -311,6 +311,11 @@ kern_return_t pwn_kernel(offsets_t offsets, task_t* tfp0, kptr_t* kbase, void* c
sendLog(controller, [NSString stringWithFormat:@__VA_ARGS__]); \
LOG(__VA_ARGS__); \
} while (0)
#ifdef __LP64__
#define PWN_LOG_KPTR(...) PWN_LOG("%s %llx", __VA_ARGS__)
#else
#define PWN_LOG_KPTR(...) PWN_LOG("%s %x", __VA_ARGS__)
#endif
#define updateStage(stage) PWN_LOG("Jailbreaking... (%d/21)", stage)

updateStage(1);
Expand All @@ -320,14 +325,18 @@ kern_return_t pwn_kernel(offsets_t offsets, task_t* tfp0, kptr_t* kbase, void* c
if (!kdata)
goto out;

PWN_LOG("our kdata buffer is at: %llx", kdata);
PWN_LOG_KPTR("our kdata buffer is at:", kdata);

// note to friends, family, next of kin, hackers alike:
// host_page_size - returns the userland page size, *always* 16K
// _host_page_size - MIG call, traps to kernel, returns PAGE_SIZE macro, will return the correct page size
vm_size_t pgsize = 0x0;
_host_page_size(mach_host_self(), &pgsize);
#ifdef __LP64__
PWN_LOG("page size: 0x%lx", pgsize);
#else
PWN_LOG("page size: 0x%x", pgsize);
#endif

io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot"));
if (service == MACH_PORT_NULL) {
Expand Down Expand Up @@ -754,21 +763,25 @@ kern_return_t pwn_kernel(offsets_t offsets, task_t* tfp0, kptr_t* kbase, void* c
// lck_rw_t = uintptr_t opaque[2] = unsigned long opaque[2]
kreadbuf(zone_map_addr + (sizeof(unsigned long) * 2), (void*)&zm_hdr, sizeof(zm_hdr));

PWN_LOG("zmap start: %llx", zm_hdr.start);
PWN_LOG("zmap end: %llx", zm_hdr.end);
PWN_LOG_KPTR("zmap start:", zm_hdr.start);
PWN_LOG_KPTR("zmap end:", zm_hdr.end);

uint64_t zm_size = zm_hdr.end - zm_hdr.start;
PWN_LOG("zmap size: %llx", zm_size);
kptr_t zm_size = zm_hdr.end - zm_hdr.start;
PWN_LOG_KPTR("zmap size:", zm_size);

if (zm_size > 0x100000000) {
PWN_LOG("zonemap too large :/");
ret = KERN_FAILURE;
goto out;
}

zonemap_fix_addr = ^(uint64_t addr) {
uint64_t spelunk = (zm_hdr.start & 0xffffffff00000000) | (addr & 0xffffffff);
return spelunk < zm_hdr.start ? spelunk + 0x100000000 : spelunk;
zonemap_fix_addr = ^(kptr_t addr) {
#ifdef __LP64__
uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | (addr & 0xffffffff);
return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp;
#else
return addr;
#endif
};

uint64_t kern_task_addr = kread64(offsets.data.kernel_task + kslide);
Expand Down
12 changes: 9 additions & 3 deletions src/shared/root.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
bool did_require_elevation = false;
uint8_t original_ucred_struct[12];

#ifdef __LP64__
#define LOG_KPTR(...) LOG("%s %llx", __VA_ARGS__)
#else
#define LOG_KPTR(...) LOG("%s %x", __VA_ARGS__)
#endif

kern_return_t elevate_to_root()
{
kptr_t kernproc = find_proc(0);
LOG("got kern proc at %llx", kernproc);
LOG_KPTR("got kern proc at", kernproc);

kptr_t ourproc = find_proc(getpid());
LOG("got ourproc at %llx", ourproc);
LOG_KPTR("got ourproc at", ourproc);

kptr_t kern_ucred = rk64(kernproc + 0x100); // proc->p_ucred
kptr_t our_ucred = rk64(ourproc + 0x100); // proc->p_ucred
Expand Down Expand Up @@ -53,7 +59,7 @@ kern_return_t restore_to_mobile()
}

kptr_t ourproc = find_proc(getpid());
LOG("got ourproc at %llx", ourproc);
LOG_KPTR("got ourproc at", ourproc);

kptr_t our_ucred = rk64(ourproc + 0x100);

Expand Down
31 changes: 16 additions & 15 deletions src/untether/install.m
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ int install(const char* config_path, const char* racoon_path, const char* dyld_c
populate_offsets(lib_offsets, myoffsets);

// uses dlsym to get an address of a symbol and then return it's unslid value
uint64_t (^get_addr_from_name)(offset_struct_t*, char*) = ^(offset_struct_t* offsets, char* name) {
void* (^slide_addr)(offsets_t*, char*) = ^(offsets_t* offsets, char* name) {
uint64_t sym = (uint64_t)dlsym(RTLD_DEFAULT, name);
if (sym == 0) {
NSLog(@"symbol (%s) not found", name);
Expand All @@ -96,29 +96,30 @@ int install(const char* config_path, const char* racoon_path, const char* dyld_c
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
syscall(294, &cache_addr); // get the current slid cache address
#pragma clang diagnostic pop
// unslide the ptr returned by dlsym
sym += 0x180000000;
// slide the ptr returned by dlsym
sym += offsets->constant.new_cache_addr;
sym -= cache_addr;
return sym;
return (void*)sym;
};

myoffsets->old_cache_addr = lib_offsets->constant.old_cache_addr;
myoffsets->new_cache_addr = lib_offsets->constant.new_cache_addr;

// Untested fallback behavior
if (lib_offsets->userland_funcs.IOConnectTrap6 == 0) {
lib_offsets->userland_funcs.IOConnectTrap6 = (void*)(get_addr_from_name(myoffsets, "IOConnectTrap6") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_ports_lookup = (void*)(get_addr_from_name(myoffsets, "mach_ports_lookup") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_task_self = (void*)(get_addr_from_name(myoffsets, "mach_task_self") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_port_destroy = (void*)(get_addr_from_name(myoffsets, "mach_port_destroy") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_port_deallocate = (void*)(get_addr_from_name(myoffsets, "mach_port_deallocate") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_port_allocate = (void*)(get_addr_from_name(myoffsets, "mach_port_allocate") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_port_insert_right = (void*)(get_addr_from_name(myoffsets, "mach_port_insert_right") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_ports_register = (void*)(get_addr_from_name(myoffsets, "mach_ports_register") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_msg = (void*)(get_addr_from_name(myoffsets, "mach_msg") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.posix_spawn = (void*)(get_addr_from_name(myoffsets, "posix_spawn") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.IOConnectTrap6 = slide_addr(lib_offsets, "IOConnectTrap6");
lib_offsets->userland_funcs.mach_ports_lookup = slide_addr(lib_offsets, "mach_ports_lookup");
lib_offsets->userland_funcs.mach_task_self = slide_addr(lib_offsets, "mach_task_self");
lib_offsets->userland_funcs.mach_port_destroy = slide_addr(lib_offsets, "mach_port_destroy");
lib_offsets->userland_funcs.mach_port_deallocate = slide_addr(lib_offsets, "mach_port_deallocate");
lib_offsets->userland_funcs.mach_port_allocate = slide_addr(lib_offsets, "mach_port_allocate");
lib_offsets->userland_funcs.mach_port_insert_right = slide_addr(lib_offsets, "mach_port_insert_right");
lib_offsets->userland_funcs.mach_ports_register = slide_addr(lib_offsets, "mach_ports_register");
lib_offsets->userland_funcs.mach_msg = slide_addr(lib_offsets, "mach_msg");
lib_offsets->userland_funcs.posix_spawn = slide_addr(lib_offsets, "posix_spawn");
}
if (lib_offsets->userland_funcs.mach_vm_remap == 0) {
lib_offsets->userland_funcs.mach_vm_remap = (void*)(get_addr_from_name(myoffsets, "_mach_vm_remap") - 0x180000000 + myoffsets->new_cache_addr);
lib_offsets->userland_funcs.mach_vm_remap = slide_addr(lib_offsets, "_mach_vm_remap");
}

myoffsets->BEAST_GADGET_LOADER = myoffsets->BEAST_GADGET + 4 * 9;
Expand Down
Loading

0 comments on commit 75fdb57

Please sign in to comment.