From dc1a1a3486bb5d74b8f2ea6ada782acdc2f34d0a Mon Sep 17 00:00:00 2001 From: opa334 Date: Thu, 16 May 2024 00:29:12 +0200 Subject: [PATCH 1/5] Fix intendation --- BaseBin/libjailbreak/src/kcall_Fugu14.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/BaseBin/libjailbreak/src/kcall_Fugu14.c b/BaseBin/libjailbreak/src/kcall_Fugu14.c index 66406f33d..1b1a7f2e3 100644 --- a/BaseBin/libjailbreak/src/kcall_Fugu14.c +++ b/BaseBin/libjailbreak/src/kcall_Fugu14.c @@ -19,14 +19,14 @@ void pac_loop(void); uint64_t mapKernelPage(uint64_t addr) { - uint64_t page = addr & ~0x3FFFULL; - uint64_t off = addr & 0x3FFFULL; - uint64_t translated = kvtophys(page); - void *map = NULL; - if (kmap(translated, 0x4000, &map) == 0) { - return ((uint64_t)map) + off; - } - return -1; + uint64_t page = addr & ~0x3FFFULL; + uint64_t off = addr & 0x3FFFULL; + uint64_t translated = kvtophys(page); + void *map = NULL; + if (kmap(translated, 0x4000, &map) == 0) { + return ((uint64_t)map) + off; + } + return -1; } uint64_t getUserReturnThreadContext(void) @@ -130,8 +130,8 @@ int fugu14_kcall_init(int (^threadSigner)(mach_port_t threadPort)) // Write register values uint64_t str_x8_x9_gadget = kgadget(str_x8_x9); - uint64_t exception_return_after_check = kgadget(exception_return_after_check); - uint64_t brX22 = kgadget(br_x22); + uint64_t exception_return_after_check = kgadget(exception_return_after_check); + uint64_t brX22 = kgadget(br_x22); kwrite64(actContext + offsetof(kRegisterState, pc), str_x8_x9_gadget); kwrite32(actContext + offsetof(kRegisterState, cpsr), CPSR_KERN_INTR_DIS); kwrite64(actContext + offsetof(kRegisterState, lr), exception_return_after_check); From 43cf5c500868645c6fd8dcfbe987d2b209148b7e Mon Sep 17 00:00:00 2001 From: opa334 Date: Thu, 23 May 2024 20:37:21 +0300 Subject: [PATCH 2/5] Make it possible for binaries to get different PMAP_CS trust levels using the jb.pmap_cs.custom_trust entitlement --- .../src/jbserver/jbdomain_systemwide.c | 20 +++++++ BaseBin/libjailbreak/src/info.c | 29 ++++++++- BaseBin/libjailbreak/src/info.h | 16 +++++ BaseBin/libjailbreak/src/util.c | 60 +++++++++++++++++++ BaseBin/libjailbreak/src/util.h | 6 ++ 5 files changed, 128 insertions(+), 3 deletions(-) diff --git a/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c b/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c index 14b1bbb28..82cc5ca42 100644 --- a/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c +++ b/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c @@ -218,6 +218,26 @@ static int systemwide_process_checkin(audit_token_t *processToken, char **rootPa proc_csflags_set(proc, CS_PLATFORM_BINARY); } +#ifdef __arm64e__ + // On arm64e every image has a trust level associated with it + // "In trust cache" trust levels have higher runtime enforcements, this can be a problem for some tools as Dopamine trustcaches everything that's adhoc signed + // So we add the ability for a binary to get a different trust level using the "jb.pmap_cs_custom_trust" entitlement + // This is for binaries that rely on weaker PMAP_CS checks (e.g. Lua trampolines need it) + xpc_object_t customTrustObj = xpc_copy_entitlement_for_token("jb.pmap_cs.custom_trust", processToken); + if (customTrustObj) { + if (xpc_get_type(customTrustObj) == XPC_TYPE_STRING) { + const char *customTrustStr = xpc_string_get_string_ptr(customTrustObj); + uint32_t customTrust = pmap_cs_trust_string_to_int(customTrustStr); + if (customTrust >= 2) { + uint64_t mainCodeDir = proc_find_main_binary_code_dir(proc); + if (mainCodeDir) { + kwrite32(mainCodeDir + koffsetof(pmap_cs_code_directory, trust), customTrust); + } + } + } + } +#endif + proc_rele(proc); return 0; } diff --git a/BaseBin/libjailbreak/src/info.c b/BaseBin/libjailbreak/src/info.c index 092bf8624..885f88651 100644 --- a/BaseBin/libjailbreak/src/info.c +++ b/BaseBin/libjailbreak/src/info.c @@ -80,15 +80,27 @@ void jbinfo_initialize_hardcoded_offsets(void) gSystemInfo.kernelStruct.pmap.tte = 0x0; gSystemInfo.kernelStruct.pmap.ttep = 0x8; #ifdef __arm64e__ - gSystemInfo.kernelStruct.pmap.sw_asid = 0xBE + pmapEl2Adjust; - gSystemInfo.kernelStruct.pmap.wx_allowed = 0xC2 + pmapEl2Adjust; - gSystemInfo.kernelStruct.pmap.type = 0xC8 + pmapEl2Adjust; + gSystemInfo.kernelStruct.pmap.pmap_cs_main = 0x90; + gSystemInfo.kernelStruct.pmap.sw_asid = 0xBE + pmapEl2Adjust; + gSystemInfo.kernelStruct.pmap.wx_allowed = 0xC2 + pmapEl2Adjust; + gSystemInfo.kernelStruct.pmap.type = 0xC8 + pmapEl2Adjust; #else gSystemInfo.kernelStruct.pmap.sw_asid = 0x96; gSystemInfo.kernelStruct.pmap.wx_allowed = 0; gSystemInfo.kernelStruct.pmap.type = 0x9c + pmapA11Adjust; #endif +#ifdef __arm64e__ + // pmap_cs_region + gSystemInfo.kernelStruct.pmap_cs_region.pmap_cs_region_next = 0x0; + gSystemInfo.kernelStruct.pmap_cs_region.cd_entry = 0x28; + + // pmap_cs_code_directory + gSystemInfo.kernelStruct.pmap_cs_code_directory.pmap_cs_code_directory_next = 0x0; + gSystemInfo.kernelStruct.pmap_cs_code_directory.main_binary = 0x50; + gSystemInfo.kernelStruct.pmap_cs_code_directory.trust = 0x9C; +#endif + // pt_desc gSystemInfo.kernelStruct.pt_desc.pmap = 0x10; gSystemInfo.kernelStruct.pt_desc.va = 0x18; @@ -222,6 +234,12 @@ void jbinfo_initialize_hardcoded_offsets(void) gSystemInfo.kernelStruct.pmap.type = 0x94 + pmapA11Adjust; #endif +#ifdef __arm64e__ + // pmap_cs_code_directory + gSystemInfo.kernelStruct.pmap_cs_code_directory.main_binary = 0x190; + gSystemInfo.kernelStruct.pmap_cs_code_directory.trust = 0x1DC; +#endif + if (strcmp(xnuVersion, "22.1.0") >= 0) { // iOS 16.1+ gSystemInfo.kernelStruct.ipc_space.table_uses_smr = true; if (strcmp(xnuVersion, "22.3.0") >= 0) { // iOS 16.3+ @@ -231,6 +249,11 @@ void jbinfo_initialize_hardcoded_offsets(void) gSystemInfo.kernelStruct.proc.flag = 0x454; gSystemInfo.kernelStruct.proc.textvp = 0x548; +#ifdef __arm64e__ + // pmap_cs_code_directory + gSystemInfo.kernelStruct.pmap_cs_code_directory.trust = 0x1EC; +#endif + if (strcmp(xnuVersion, "22.4.0") == 0) { // iOS 16.4 ONLY // iOS 16.4 beta 1-3 use the old proc struct, 16.4b4+ use new if (gSystemInfo.kernelStruct.proc.struct_size != 0x730) { diff --git a/BaseBin/libjailbreak/src/info.h b/BaseBin/libjailbreak/src/info.h index 074a6555d..39fa8a61c 100644 --- a/BaseBin/libjailbreak/src/info.h +++ b/BaseBin/libjailbreak/src/info.h @@ -189,11 +189,23 @@ struct system_info { struct { uint32_t tte; uint32_t ttep; + uint32_t pmap_cs_main; uint32_t sw_asid; uint32_t wx_allowed; uint32_t type; } pmap; + struct { + uint32_t pmap_cs_region_next; + uint32_t cd_entry; + } pmap_cs_region; + + struct { + uint32_t pmap_cs_code_directory_next; + uint32_t main_binary; + uint32_t trust; + } pmap_cs_code_directory; + struct { uint32_t pmap; uint32_t va; @@ -359,10 +371,14 @@ extern struct system_info gSystemInfo; \ iterator(ctx, kernelStruct.pmap.tte); \ iterator(ctx, kernelStruct.pmap.ttep); \ + iterator(ctx, kernelStruct.pmap.pmap_cs_main); \ iterator(ctx, kernelStruct.pmap.sw_asid); \ iterator(ctx, kernelStruct.pmap.wx_allowed); \ iterator(ctx, kernelStruct.pmap.type); \ \ + iterator(ctx, kernelStruct.pmap_cs_region.pmap_cs_region_next); \ + iterator(ctx, kernelStruct.pmap_cs_region.cd_entry); \ + \ iterator(ctx, kernelStruct.pt_desc.pmap); \ iterator(ctx, kernelStruct.pt_desc.va); \ iterator(ctx, kernelStruct.pt_desc.ptd_info); \ diff --git a/BaseBin/libjailbreak/src/util.c b/BaseBin/libjailbreak/src/util.c index 43b674f1f..6cee92654 100644 --- a/BaseBin/libjailbreak/src/util.c +++ b/BaseBin/libjailbreak/src/util.c @@ -379,6 +379,66 @@ int pmap_map_in(uint64_t pmap, uint64_t uaStart, uint64_t paStart, uint64_t size return 0; } + +#ifdef __arm64e__ +uint64_t pmap_find_main_binary_code_dir(uint64_t pmap) +{ + uint64_t mainCodeDir = 0; + uint64_t pmap_cs_region = kread_ptr(pmap + koffsetof(pmap, pmap_cs_main)); + while (pmap_cs_region && !mainCodeDir) { + uint64_t pmap_cs_code_dir = kread_ptr(pmap_cs_region + koffsetof(pmap_cs_region, cd_entry)); + while (pmap_cs_code_dir) { + _Bool mainBinary = kread64(pmap_cs_code_dir + koffsetof(pmap_cs_code_directory, main_binary)); + if (mainBinary) { + mainCodeDir = pmap_cs_code_dir; + break; + } + pmap_cs_code_dir = kread_ptr(pmap_cs_code_dir + koffsetof(pmap_cs_code_directory, pmap_cs_code_directory_next)); + } + pmap_cs_region = kread_ptr(pmap_cs_region + koffsetof(pmap_cs_region, pmap_cs_region_next)); + } + return mainCodeDir; +} + +uint64_t proc_find_main_binary_code_dir(uint64_t proc) +{ + uint64_t task = proc_task(proc); + uint64_t map = kread_ptr(task + koffsetof(task, map)); + uint64_t pmap = kread_ptr(map + koffsetof(vm_map, pmap)); + return pmap_find_main_binary_code_dir(pmap); +} + +uint32_t pmap_cs_trust_string_to_int(const char *trustString) +{ + int trustInt = 0; + if (__builtin_available(iOS 16.0, *)) { + if (!strcmp(trustString, "PMAP_CS_UNTRUSTED")) trustInt = 0; + else if (!strcmp(trustString, "PMAP_CS_RETIRED")) trustInt = 1; + else if (!strcmp(trustString, "PMAP_CS_PROFILE_PREFLIGHT")) trustInt = 2; + else if (!strcmp(trustString, "PMAP_CS_COMPILATION_SERVICE")) trustInt = 3; + else if (!strcmp(trustString, "PMAP_CS_OOP_JIT")) trustInt = 4; + else if (!strcmp(trustString, "PMAP_CS_LOCAL_SIGNING")) trustInt = 5; + else if (!strcmp(trustString, "PMAP_CS_PROFILE_VALIDATED")) trustInt = 6; + else if (!strcmp(trustString, "PMAP_CS_APP_STORE")) trustInt = 7; + else if (!strcmp(trustString, "PMAP_CS_IN_LOADED_TRUST_CACHE")) trustInt = 8; + else if (!strcmp(trustString, "PMAP_CS_IN_STATIC_TRUST_CACHE")) trustInt = 9; + } + else { + if (!strcmp(trustString, "PMAP_CS_UNTRUSTED")) trustInt = 0; + else if (!strcmp(trustString, "PMAP_CS_RETIRED")) trustInt = 1; + else if (!strcmp(trustString, "PMAP_CS_PROFILE_PREFLIGHT")) trustInt = 2; + else if (!strcmp(trustString, "PMAP_CS_COMPILATION_SERVICE")) trustInt = 3; + else if (!strcmp(trustString, "PMAP_CS_LOCAL_SIGNING")) trustInt = 4; + else if (!strcmp(trustString, "PMAP_CS_PROFILE_VALIDATED")) trustInt = 5; + else if (!strcmp(trustString, "PMAP_CS_APP_STORE")) trustInt = 6; + else if (!strcmp(trustString, "PMAP_CS_IN_LOADED_TRUST_CACHE")) trustInt = 7; + else if (!strcmp(trustString, "PMAP_CS_IN_STATIC_TRUST_CACHE")) trustInt = 8; + } + return trustInt; +} + +#endif + int sign_kernel_thread(uint64_t proc, mach_port_t threadPort) { uint64_t threadKobj = task_get_ipc_port_kobject(proc_task(proc), threadPort); diff --git a/BaseBin/libjailbreak/src/util.h b/BaseBin/libjailbreak/src/util.h index 12677d16b..b095ab266 100644 --- a/BaseBin/libjailbreak/src/util.h +++ b/BaseBin/libjailbreak/src/util.h @@ -25,6 +25,12 @@ uint64_t pmap_alloc_page_table(uint64_t pmap, uint64_t va); int pmap_expand_range(uint64_t pmap, uint64_t vaStart, uint64_t size); int pmap_map_in(uint64_t pmap, uint64_t uaStart, uint64_t paStart, uint64_t size); +#ifdef __arm64e__ +uint64_t pmap_find_main_binary_code_dir(uint64_t pmap); +uint64_t proc_find_main_binary_code_dir(uint64_t proc); +uint32_t pmap_cs_trust_string_to_int(const char *trustString); +#endif + int sign_kernel_thread(uint64_t proc, mach_port_t threadPort); uint64_t kpacda(uint64_t pointer, uint64_t modifier); uint64_t kptr_sign(uint64_t kaddr, uint64_t pointer, uint16_t salt); From cdd113fcb1e329159ac77a9c36f01b1d195f3859 Mon Sep 17 00:00:00 2001 From: opa334 Date: Thu, 23 May 2024 23:05:45 +0300 Subject: [PATCH 3/5] Fix codesign bypass not working when passing an archpref to posix_spawn --- .../Dopamine/Jailbreak/DOJailbreaker.m | 2 +- .../src/jbserver/jbdomain_systemwide.c | 25 ++++++++++--- BaseBin/launchdhook/src/spawn_hook.c | 2 +- BaseBin/libjailbreak/src/jbclient_xpc.c | 5 ++- BaseBin/libjailbreak/src/jbclient_xpc.h | 2 +- BaseBin/libjailbreak/src/signatures.h | 2 +- BaseBin/libjailbreak/src/signatures.m | 26 ++++++++++++-- BaseBin/libjailbreak/src/util.h | 2 +- BaseBin/systemhook/src/common.c | 36 +++++++++++++++++-- BaseBin/systemhook/src/common.h | 2 +- BaseBin/systemhook/src/objc.m | 2 +- 11 files changed, 87 insertions(+), 19 deletions(-) diff --git a/Application/Dopamine/Jailbreak/DOJailbreaker.m b/Application/Dopamine/Jailbreak/DOJailbreaker.m index 2d12a87b7..42cad58d0 100644 --- a/Application/Dopamine/Jailbreak/DOJailbreaker.m +++ b/Application/Dopamine/Jailbreak/DOJailbreaker.m @@ -384,7 +384,7 @@ - (NSError *)createFakeLib cdhash_t *cdhashes = NULL; uint32_t cdhashesCount = 0; - macho_collect_untrusted_cdhashes(JBRootPath("/basebin/.fakelib/dyld"), NULL, NULL, &cdhashes, &cdhashesCount); + macho_collect_untrusted_cdhashes(JBRootPath("/basebin/.fakelib/dyld"), NULL, NULL, NULL, NULL, 0, &cdhashes, &cdhashesCount); if (cdhashesCount != 1) return [NSError errorWithDomain:JBErrorDomain code:JBErrorCodeFailedInitFakeLib userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Got unexpected number of cdhashes for dyld???: %d", cdhashesCount]}]; trustcache_file_v1 *dyldTCFile = NULL; diff --git a/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c b/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c index 82cc5ca42..4b6483639 100644 --- a/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c +++ b/BaseBin/launchdhook/src/jbserver/jbdomain_systemwide.c @@ -67,7 +67,7 @@ static int systemwide_get_boot_uuid(char **bootUUIDOut) return 0; } -static int trust_file(const char *filePath, const char *dlopenCallerImagePath, const char *dlopenCallerExecutablePath) +static int trust_file(const char *filePath, const char *dlopenCallerImagePath, const char *dlopenCallerExecutablePath, xpc_object_t preferredArchsArray) { // Shared logic between client and server, implemented in client // This should essentially mean these files never reach us in the first place @@ -76,9 +76,23 @@ static int trust_file(const char *filePath, const char *dlopenCallerImagePath, c if (can_skip_trusting_file(filePath, (bool)dlopenCallerExecutablePath, false)) return -1; + size_t preferredArchCount = 0; + if (preferredArchsArray) preferredArchCount = xpc_array_get_count(preferredArchsArray); + uint32_t preferredArchTypes[preferredArchCount]; + uint32_t preferredArchSubtypes[preferredArchCount]; + for (size_t i = 0; i < preferredArchCount; i++) { + preferredArchTypes[i] = 0; + preferredArchSubtypes[i] = UINT32_MAX; + xpc_object_t arch = xpc_array_get_value(preferredArchsArray, i); + if (xpc_get_type(arch) == XPC_TYPE_DICTIONARY) { + preferredArchTypes[i] = xpc_dictionary_get_uint64(arch, "type"); + preferredArchSubtypes[i] = xpc_dictionary_get_uint64(arch, "subtype"); + } + } + cdhash_t *cdhashes = NULL; uint32_t cdhashesCount = 0; - macho_collect_untrusted_cdhashes(filePath, dlopenCallerImagePath, dlopenCallerExecutablePath, &cdhashes, &cdhashesCount); + macho_collect_untrusted_cdhashes(filePath, dlopenCallerImagePath, dlopenCallerExecutablePath, preferredArchTypes, preferredArchSubtypes, preferredArchCount, &cdhashes, &cdhashesCount); if (cdhashes && cdhashesCount > 0) { jb_trustcache_add_cdhashes(cdhashes, cdhashesCount); free(cdhashes); @@ -87,9 +101,9 @@ static int trust_file(const char *filePath, const char *dlopenCallerImagePath, c } // Not static because launchd will directly call this from it's posix_spawn hook -int systemwide_trust_binary(const char *binaryPath) +int systemwide_trust_binary(const char *binaryPath, xpc_object_t preferredArchsArray) { - return trust_file(binaryPath, NULL, NULL); + return trust_file(binaryPath, NULL, NULL, preferredArchsArray); } static int systemwide_trust_library(audit_token_t *processToken, const char *libraryPath, const char *callerLibraryPath) @@ -105,7 +119,7 @@ static int systemwide_trust_library(audit_token_t *processToken, const char *lib // This is to support dlopen("@executable_path/whatever", RTLD_NOW) and stuff like that // (Yes that is a thing >.<) // Also we need to pass the path of the image that called dlopen due to @loader_path, sigh... - return trust_file(libraryPath, callerLibraryPath, callerPath); + return trust_file(libraryPath, callerLibraryPath, callerPath, NULL); } static int systemwide_process_checkin(audit_token_t *processToken, char **rootPathOut, char **bootUUIDOut, char **sandboxExtensionsOut, bool *fullyDebuggedOut) @@ -343,6 +357,7 @@ struct jbserver_domain gSystemwideDomain = { .handler = systemwide_trust_binary, .args = (jbserver_arg[]){ { .name = "binary-path", .type = JBS_TYPE_STRING, .out = false }, + { .name = "preferred-archs", .type = JBS_TYPE_ARRAY, .out = false }, { 0 }, }, }, diff --git a/BaseBin/launchdhook/src/spawn_hook.c b/BaseBin/launchdhook/src/spawn_hook.c index 00869046f..76ae8c0cd 100644 --- a/BaseBin/launchdhook/src/spawn_hook.c +++ b/BaseBin/launchdhook/src/spawn_hook.c @@ -10,7 +10,7 @@ #include extern char **environ; -extern int systemwide_trust_binary(const char *binaryPath); +extern int systemwide_trust_binary(const char *binaryPath, xpc_object_t preferredArchsArray); extern int platform_set_process_debugged(uint64_t pid, bool fullyDebugged); #define LOG_PROCESS_LAUNCHES 0 diff --git a/BaseBin/libjailbreak/src/jbclient_xpc.c b/BaseBin/libjailbreak/src/jbclient_xpc.c index 01a3c4a09..63b83a283 100644 --- a/BaseBin/libjailbreak/src/jbclient_xpc.c +++ b/BaseBin/libjailbreak/src/jbclient_xpc.c @@ -184,7 +184,7 @@ char *realafpath(const char *restrict path, char *restrict resolved_path) } } -int jbclient_trust_binary(const char *binaryPath) +int jbclient_trust_binary(const char *binaryPath, xpc_object_t preferredArchsArray) { if (!binaryPath) return -1; @@ -195,6 +195,9 @@ int jbclient_trust_binary(const char *binaryPath) xpc_object_t xargs = xpc_dictionary_create_empty(); xpc_dictionary_set_string(xargs, "binary-path", absolutePath); + if (preferredArchsArray) { + xpc_dictionary_set_value(xargs, "preferred-archs", preferredArchsArray); + } xpc_object_t xreply = jbserver_xpc_send(JBS_DOMAIN_SYSTEMWIDE, JBS_SYSTEMWIDE_TRUST_BINARY, xargs); xpc_release(xargs); if (xreply) { diff --git a/BaseBin/libjailbreak/src/jbclient_xpc.h b/BaseBin/libjailbreak/src/jbclient_xpc.h index 501f905d3..c4601a473 100644 --- a/BaseBin/libjailbreak/src/jbclient_xpc.h +++ b/BaseBin/libjailbreak/src/jbclient_xpc.h @@ -12,7 +12,7 @@ xpc_object_t jbserver_xpc_send(uint64_t domain, uint64_t action, xpc_object_t xa char *jbclient_get_jbroot(void); char *jbclient_get_boot_uuid(void); -int jbclient_trust_binary(const char *binaryPath); +int jbclient_trust_binary(const char *binaryPath, xpc_object_t preferredArchsArray); int jbclient_trust_library(const char *libraryPath, void *addressInCaller); int jbclient_process_checkin(char **rootPathOut, char **bootUUIDOut, char **sandboxExtensionsOut, bool *fullyDebuggedOut); int jbclient_fork_fix(uint64_t childPid); diff --git a/BaseBin/libjailbreak/src/signatures.h b/BaseBin/libjailbreak/src/signatures.h index 1022ed104..b4518ce00 100644 --- a/BaseBin/libjailbreak/src/signatures.h +++ b/BaseBin/libjailbreak/src/signatures.h @@ -4,6 +4,6 @@ #include typedef uint8_t cdhash_t[CS_CDHASH_LEN]; -void macho_collect_untrusted_cdhashes(const char *path, const char *callerImagePath, const char *callerExecutablePath, cdhash_t **cdhashesOut, uint32_t *cdhashCountOut); +void macho_collect_untrusted_cdhashes(const char *path, const char *callerImagePath, const char *callerExecutablePath, uint32_t *preferredArchTypes, uint32_t *preferredArchSubtypes, size_t preferredArchCount, cdhash_t **cdhashesOut, uint32_t *cdhashCountOut); #endif \ No newline at end of file diff --git a/BaseBin/libjailbreak/src/signatures.m b/BaseBin/libjailbreak/src/signatures.m index 9af65f75f..8e19959ec 100644 --- a/BaseBin/libjailbreak/src/signatures.m +++ b/BaseBin/libjailbreak/src/signatures.m @@ -114,7 +114,7 @@ bool csd_superblob_is_adhoc_signed(CS_DecodedSuperBlob *superblob) } } -void macho_collect_untrusted_cdhashes(const char *path, const char *callerImagePath, const char *callerExecutablePath, cdhash_t **cdhashesOut, uint32_t *cdhashCountOut) +void macho_collect_untrusted_cdhashes(const char *path, const char *callerImagePath, const char *callerExecutablePath, uint32_t *preferredArchTypes, uint32_t *preferredArchSubtypes, size_t preferredArchCount, cdhash_t **cdhashesOut, uint32_t *cdhashCountOut) { @autoreleasepool { if (!path) return; @@ -140,7 +140,16 @@ void macho_collect_untrusted_cdhashes(const char *path, const char *callerImageP if (!callerExecutablePath) { FAT *mainFAT = fat_init_from_path(path); if (mainFAT) { - MachO *mainMachO = ljb_fat_find_preferred_slice(mainFAT); + MachO *mainMachO = NULL; + if (preferredArchCount > 0) { + for (size_t i = 0; i < preferredArchCount; i++) { + if (preferredArchTypes[i] != 0 && preferredArchSubtypes[i] != UINT32_MAX) { + mainMachO = fat_find_slice(mainFAT, preferredArchTypes[i], preferredArchSubtypes[i]); + if (mainMachO) break; + } + } + } + if (!mainMachO) mainMachO = ljb_fat_find_preferred_slice(mainFAT); if (mainMachO) { if (macho_get_filetype(mainMachO) == MH_EXECUTE) { callerExecutablePath = path; @@ -160,7 +169,18 @@ void macho_collect_untrusted_cdhashes(const char *path, const char *callerImageP NSString *resolvedBinaryPath = resolveDependencyPath(binaryPath, sourceImagePath, sourceExecutablePath); FAT *fat = fat_init_from_path(resolvedBinaryPath.fileSystemRepresentation); if (!fat) return; - MachO *macho = ljb_fat_find_preferred_slice(fat); + MachO *macho = NULL; + if ([binaryPath isEqualToString:sourceExecutablePath]) { + if (preferredArchCount > 0) { + for (size_t i = 0; i < preferredArchCount; i++) { + if (preferredArchTypes[i] != 0 && preferredArchSubtypes[i] != UINT32_MAX) { + macho = fat_find_slice(fat, preferredArchTypes[i], preferredArchSubtypes[i]); + if (macho) break; + } + } + } + } + if (!macho) macho = ljb_fat_find_preferred_slice(fat); if (!macho) { fat_free(fat); return; diff --git a/BaseBin/libjailbreak/src/util.h b/BaseBin/libjailbreak/src/util.h index b095ab266..b1fa14216 100644 --- a/BaseBin/libjailbreak/src/util.h +++ b/BaseBin/libjailbreak/src/util.h @@ -53,7 +53,7 @@ int exec_cmd_suspended(pid_t *pidOut, const char *binary, ...); int exec_cmd_root(const char *binary, ...); #define exec_cmd_trusted(x, args ...) ({ \ - jbclient_trust_binary(x); \ + jbclient_trust_binary(x, NULL); \ int retval; \ retval = exec_cmd(x, args); \ retval; \ diff --git a/BaseBin/systemhook/src/common.c b/BaseBin/systemhook/src/common.c index fcad8cb98..59587ac5f 100644 --- a/BaseBin/systemhook/src/common.c +++ b/BaseBin/systemhook/src/common.c @@ -233,7 +233,7 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, char *const argv[restrict], char *const envp[restrict], void *orig, - int (*trust_binary)(const char *), + int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), int (*set_process_debugged)(uint64_t pid, bool fullyDebugged)) { int (*pspawn_orig)(pid_t *restrict, const char *restrict, const posix_spawn_file_actions_t *restrict, const posix_spawnattr_t *restrict, char *const[restrict], char *const[restrict]) = orig; @@ -244,8 +244,38 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, kBinaryConfig binaryConfig = configForBinary(path, argv); if (!(binaryConfig & kBinaryConfigDontProcess)) { + + bool preferredArchsSet = false; + cpu_type_t preferredTypes[4]; + cpu_subtype_t preferredSubtypes[4]; + size_t sizeOut = 0; + if (posix_spawnattr_getarchpref_np(attrp, 4, preferredTypes, preferredSubtypes, &sizeOut) == 0) { + for (size_t i = 0; i < sizeOut; i++) { + if (preferredTypes[i] != 0 || preferredSubtypes[i] != UINT32_MAX) { + preferredArchsSet = true; + break; + } + } + } + + xpc_object_t preferredArchsArray = NULL; + if (preferredArchsSet) { + preferredArchsArray = xpc_array_create_empty(); + for (size_t i = 0; i < sizeOut; i++) { + xpc_object_t curArch = xpc_dictionary_create_empty(); + xpc_dictionary_set_uint64(curArch, "type", preferredTypes[i]); + xpc_dictionary_set_uint64(curArch, "subtype", preferredSubtypes[i]); + xpc_array_set_value(preferredArchsArray, XPC_ARRAY_APPEND, curArch); + xpc_release(curArch); + } + } + // Upload binary to trustcache if needed - trust_binary(path); + trust_binary(path, preferredArchsArray); + + if (preferredArchsArray) { + xpc_release(preferredArchsArray); + } } const char *existingLibraryInserts = envbuf_getenv((const char **)envp, "DYLD_INSERT_LIBRARIES"); @@ -256,7 +286,7 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, systemHookAlreadyInserted = true; } else { - trust_binary(existingLibraryInsert); + trust_binary(existingLibraryInsert, NULL); } }); } diff --git a/BaseBin/systemhook/src/common.h b/BaseBin/systemhook/src/common.h index 1aa2450ff..6e7399519 100644 --- a/BaseBin/systemhook/src/common.h +++ b/BaseBin/systemhook/src/common.h @@ -16,5 +16,5 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, char *const argv[restrict], char *const envp[restrict], void *orig, - int (*trust_binary)(const char *), + int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), int (*set_process_debugged)(uint64_t pid, bool fullyDebugged)); \ No newline at end of file diff --git a/BaseBin/systemhook/src/objc.m b/BaseBin/systemhook/src/objc.m index 485dc1cb9..c9f085a61 100644 --- a/BaseBin/systemhook/src/objc.m +++ b/BaseBin/systemhook/src/objc.m @@ -36,7 +36,7 @@ bool NSConcreteTask_launchWithDictionary_error__hook(id self, id sender, NSDicti NSString *executablePath = __objc_msgSend_1(dictionary, @selector(objectForKey:), keyExecutablePath); if (executablePath) { const char *executablePathC = __objc_msgSend_0(executablePath, @selector(UTF8String)); - jbclient_trust_binary(executablePathC); + jbclient_trust_binary(executablePathC, NULL); } NSDictionary *existingEnvironment = __objc_msgSend_1(dictionary, @selector(objectForKey:), keyEnvironmentDict); From 8a5b34c082547d464ac4de83bed867a70588007d Mon Sep 17 00:00:00 2001 From: opa334 Date: Mon, 27 May 2024 12:21:36 +0800 Subject: [PATCH 4/5] Fix pmap_cs_code_directory offsets getting lost --- BaseBin/libjailbreak/src/info.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BaseBin/libjailbreak/src/info.h b/BaseBin/libjailbreak/src/info.h index 39fa8a61c..a56edbcbe 100644 --- a/BaseBin/libjailbreak/src/info.h +++ b/BaseBin/libjailbreak/src/info.h @@ -379,6 +379,10 @@ extern struct system_info gSystemInfo; iterator(ctx, kernelStruct.pmap_cs_region.pmap_cs_region_next); \ iterator(ctx, kernelStruct.pmap_cs_region.cd_entry); \ \ + iterator(ctx, kernelStruct.pmap_cs_code_directory.pmap_cs_code_directory_next); \ + iterator(ctx, kernelStruct.pmap_cs_code_directory.main_binary); \ + iterator(ctx, kernelStruct.pmap_cs_code_directory.trust); \ + \ iterator(ctx, kernelStruct.pt_desc.pmap); \ iterator(ctx, kernelStruct.pt_desc.va); \ iterator(ctx, kernelStruct.pt_desc.ptd_info); \ From 5c844b2fbf86bba3b0bcd58e5e55b6f87803d6a2 Mon Sep 17 00:00:00 2001 From: opa334 Date: Mon, 27 May 2024 22:43:34 +0800 Subject: [PATCH 5/5] 2.1.5 --- Application/Dopamine.xcodeproj/project.pbxproj | 4 ++-- BaseBin/_external/basebin/.version | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Application/Dopamine.xcodeproj/project.pbxproj b/Application/Dopamine.xcodeproj/project.pbxproj index 1a7bea12c..bef1d1a83 100644 --- a/Application/Dopamine.xcodeproj/project.pbxproj +++ b/Application/Dopamine.xcodeproj/project.pbxproj @@ -2229,7 +2229,7 @@ "$(PROJECT_DIR)/Dopamine/Dependencies", "$(PROJECT_DIR)/Dopamine/Resources", ); - MARKETING_VERSION = 2.1.4; + MARKETING_VERSION = 2.1.5; PRODUCT_BUNDLE_IDENTIFIER = com.opa334.Dopamine; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -2266,7 +2266,7 @@ "$(PROJECT_DIR)/Dopamine/Dependencies", "$(PROJECT_DIR)/Dopamine/Resources", ); - MARKETING_VERSION = 2.1.4; + MARKETING_VERSION = 2.1.5; PRODUCT_BUNDLE_IDENTIFIER = com.opa334.Dopamine; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/BaseBin/_external/basebin/.version b/BaseBin/_external/basebin/.version index c346e7a04..c5864dcf3 100644 --- a/BaseBin/_external/basebin/.version +++ b/BaseBin/_external/basebin/.version @@ -1 +1 @@ -2.1.4 \ No newline at end of file +2.1.5 \ No newline at end of file