Last active
February 1, 2025 22:34
-
-
Save jakeajames/5ee29a99107cdd2fd665b468f9f8e664 to your computer and use it in GitHub Desktop.
"kppless" sandbox profile patch for iOS 12
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
addr_t Find_platform_profile() { | |
uint64_t string = Find_strref("\"failed to initialize platform sandbox", 1, 0, false); | |
if (!string) { | |
string = Find_strref("\"failed to initialize platform sandbox", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t adrp = Step64_back(Kernel, string, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
adrp = Step64_back(Kernel, adrp - 4, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
adrp = Step64_back(Kernel, adrp - 4, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t x0 = Calc64(Kernel, adrp, adrp + 8, 0); | |
if (!x0) { | |
return 0; | |
} | |
return x0 + KernDumpBase + KASLR_Slide; | |
} | |
addr_t Find_platform_data() { | |
uint64_t string = Find_strref("\"failed to initialize platform sandbox", 1, 0, false); | |
if (!string) { | |
string = Find_strref("\"failed to initialize platform sandbox", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t adrp = Step64_back(Kernel, string, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
adrp = Step64_back(Kernel, adrp - 4, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t x1 = Calc64(Kernel, adrp, adrp + 8, 1); | |
if (!x1) { | |
return 0; | |
} | |
return x1 + KernDumpBase + KASLR_Slide; | |
} | |
addr_t Find_platform_data_size() { | |
uint64_t string = Find_strref("\"failed to initialize platform sandbox", 1, 0, false); | |
if (!string) { | |
string = Find_strref("\"failed to initialize platform sandbox", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t adrp = Step64_back(Kernel, string, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
adrp = Step64_back(Kernel, adrp - 4, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t w3 = Calc64mov(Kernel, adrp + 8, adrp + 12, 3); | |
if (!w3) { | |
return 0; | |
} | |
return w3; | |
} | |
addr_t Find_do_profile_create() { | |
uint64_t string = Find_strref("\"failed to initialize platform sandbox", 1, 0, false); | |
if (!string) { | |
string = Find_strref("\"failed to initialize platform sandbox", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t bl = Step64_back(Kernel, string, 100, INSN_CALL); | |
if (!bl) { | |
return 0; | |
} | |
uint64_t call = Follow_call64(Kernel, bl); | |
if (!call) { | |
return 0; | |
} | |
return call + KernDumpBase + KASLR_Slide; | |
} | |
addr_t Find_sandbox_collection() { | |
uint64_t string = Find_strref("failed to initialize collection", 1, 0, false); | |
if (!string) { | |
string = Find_strref("failed to initialize collection", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t do_profile_create = Find_do_profile_create(); | |
do_profile_create -= KernDumpBase + KASLR_Slide; | |
uint64_t bl = 0; | |
for (int i = 0; i < 10; i++) { | |
bl = Step64_back(Kernel, string, 100, INSN_CALL); | |
if (!bl) { | |
return 0; | |
} | |
uint64_t call = Follow_call64(Kernel, bl); | |
if (!call) { | |
return 0; | |
} | |
if (call == do_profile_create) { | |
break; | |
} | |
string = bl - 4; | |
} | |
uint64_t adrp = Step64_back(Kernel, bl, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
adrp = Step64_back(Kernel, adrp - 4, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t page = Calc64(Kernel, adrp, adrp + 4, 22); | |
if (!page) { | |
page = Calc64(Kernel, adrp, adrp + 4, 20); | |
if (!page) { | |
return 0; | |
} | |
} | |
uint64_t str = adrp + 4; | |
uint32_t op = *(uint32_t*)(Kernel + str); | |
unsigned imm = ((op >> 10) & 0xFFF) << 3; | |
return page + imm + KernDumpBase + KASLR_Slide; | |
} | |
addr_t Find_collection_data() { | |
uint64_t string = Find_strref("failed to initialize collection", 1, 0, false); | |
if (!string) { | |
string = Find_strref("failed to initialize collection", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t do_profile_create = Find_do_profile_create(); | |
do_profile_create -= KernDumpBase + KASLR_Slide; | |
uint64_t bl = 0; | |
for (int i = 0; i < 10; i++) { | |
bl = Step64_back(Kernel, string, 100, INSN_CALL); | |
if (!bl) { | |
return 0; | |
} | |
uint64_t call = Follow_call64(Kernel, bl); | |
if (!call) { | |
return 0; | |
} | |
if (call == do_profile_create) { | |
break; | |
} | |
string = bl - 4; | |
} | |
uint64_t adrp = Step64_back(Kernel, bl, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t x1 = Calc64(Kernel, adrp, adrp + 8, 1); | |
if (!x1) { | |
return 0; | |
} | |
return x1 + KernDumpBase + KASLR_Slide; | |
} | |
addr_t Find_collection_data_size() { | |
uint64_t string = Find_strref("failed to initialize collection", 1, 0, false); | |
if (!string) { | |
string = Find_strref("failed to initialize collection", 1, 1, false); | |
if (!string) { | |
return 0; | |
} | |
} | |
string -= KernDumpBase; | |
uint64_t do_profile_create = Find_do_profile_create(); | |
do_profile_create -= KernDumpBase + KASLR_Slide; | |
uint64_t bl = 0; | |
for (int i = 0; i < 10; i++) { | |
bl = Step64_back(Kernel, string, 100, INSN_CALL); | |
if (!bl) { | |
return 0; | |
} | |
uint64_t call = Follow_call64(Kernel, bl); | |
if (!call) { | |
return 0; | |
} | |
if (call == do_profile_create) { | |
break; | |
} | |
string = bl - 4; | |
} | |
uint64_t adrp = Step64_back(Kernel, bl, 100, INSN_ADRP); | |
if (!adrp) { | |
return 0; | |
} | |
uint64_t w3 = Calc64mov(Kernel, adrp + 8, adrp + 16, 3); | |
if (!w3) { | |
return 0; | |
} | |
return w3; | |
} | |
addr_t Find_sandbox_operations_list() { | |
uint64_t platform_profile = Find_platform_profile(); | |
if (!platform_profile) { | |
return 0; | |
} | |
return platform_profile + 8; | |
} | |
int Find_number_of_sb_operations() { | |
uint64_t list = Find_sandbox_operations_list(); | |
if (!list) { | |
return 0; | |
} | |
list -= KernDumpBase + KASLR_Slide; | |
int num = 0; | |
for (int i = 0; i < 500; i++) { | |
uint64_t ptr = *(uint64_t*)(Kernel + list); | |
if (!ptr) { | |
return 0; | |
} | |
if ((ptr & 0xfffffff000000000) != 0xfffffff000000000) { // tagged pointers | |
ptr |= 0xfffffff000000000; | |
} | |
ptr -= KernDumpBase; | |
char *string = (char *)(Kernel + ptr); | |
if (!strcmp(string, "HOME")) break; | |
list += 8; | |
num++; | |
} | |
return num; | |
} | |
int Find_sandbox_operation_index(char *op) { | |
uint64_t list = Find_sandbox_operations_list(); | |
if (!list) { | |
return 0; | |
} | |
list -= KernDumpBase + KASLR_Slide; | |
int count = Find_number_of_sb_operations(); | |
for (int i = 0; i < count; i++) { | |
uint64_t ptr = *(uint64_t*)(Kernel + list); | |
if (!ptr) { | |
return 0; | |
} | |
if ((ptr & 0xfffffff000000000) != 0xfffffff000000000) { // tagged pointers | |
ptr |= 0xfffffff000000000; | |
} | |
ptr -= KernDumpBase; | |
char *string = (char *)(Kernel + ptr); | |
if (!strcmp(string, op)) { | |
return i; | |
} | |
list += 8; | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int patch_platform_profile() { | |
if (!container_sb) { | |
printf("[-] I need a sandbox\n"); | |
return 1; | |
} | |
uint32_t size = (uint32_t)Find_platform_data_size(); | |
if (!size) { | |
return 2; | |
} | |
int numsbops = Find_number_of_sb_operations(); | |
if (!numsbops) { | |
return 3; | |
} | |
int fme_idx = Find_sandbox_operation_index("file-map-executable"); | |
if (!fme_idx) { // only "default" should be at index 0 | |
return 4; | |
} | |
/*int procexec_idx = Find_sandbox_operation_index("process-exec*"); | |
if (!procexec_idx) { | |
return 4; | |
}*/ | |
int interpreter_idx = Find_sandbox_operation_index("process-exec-interpreter"); | |
if (!interpreter_idx) { | |
return 4; | |
} | |
uint64_t pprofile = Find_platform_profile(); | |
if (!pprofile) { | |
return 5; | |
} | |
uint64_t platform_profile_ptr = KernelRead_64bits(pprofile); | |
uint64_t platform_profile = KernelRead_64bits(platform_profile_ptr); | |
uint64_t copy = Kernel_alloc(size); | |
void *ucopy = malloc(size); | |
KernelRead(platform_profile, ucopy, size); | |
KernelWrite(copy, ucopy, size); | |
free(ucopy); | |
KernelWrite_64bits(platform_profile_ptr, copy); | |
int idx = 0; | |
uint32_t val = 0; | |
uint16_t patch = 0; | |
do { | |
KernelRead(copy + idx * 2, &patch, sizeof(uint16_t)); | |
val = KernelRead_32bits(copy + patch * 8); | |
idx++; | |
} while (val != 1); | |
KernelWrite(copy + 12 + fme_idx * 2, &patch, sizeof(uint16_t)); | |
//KernelWrite(copy + 12 + procexec_idx * 2, &patch, sizeof(uint16_t)); | |
KernelWrite(copy + 12 + interpreter_idx * 2, &patch, sizeof(uint16_t)); | |
return 0; | |
} | |
uint64_t container_sb = 0; | |
int patch_sandbox_container() { | |
if (!container_sb) { | |
printf("[-] I need a sandbox\n"); | |
return 1; | |
} | |
uint32_t size = (uint32_t)Find_collection_data_size(); | |
if (!size) { | |
return 2; | |
} | |
int numsbops = Find_number_of_sb_operations(); | |
if (!numsbops) { | |
return 3; | |
} | |
int fme_idx = Find_sandbox_operation_index("file-map-executable"); | |
if (!fme_idx) { // only "default" should be at index 0 | |
return 4; | |
} | |
int fread_idx = Find_sandbox_operation_index("file-read*"); | |
if (!fread_idx) { | |
return 4; | |
} | |
int freaddata_idx = Find_sandbox_operation_index("file-read-data"); | |
if (!freaddata_idx) { | |
return 4; | |
} | |
int freadmeta_idx = Find_sandbox_operation_index("file-read-metadata"); | |
if (!freadmeta_idx) { | |
return 4; | |
} | |
int mach_lookup_idx = Find_sandbox_operation_index("mach-lookup"); | |
if (!mach_lookup_idx) { | |
return 4; | |
} | |
uint64_t profile = KernelRead_64bits(container_sb); | |
uint64_t data = KernelRead_64bits(profile); | |
uint64_t copy = Kernel_alloc(size); | |
void *ucopy = malloc(size); | |
KernelRead(data, ucopy, size); | |
KernelWrite(copy, ucopy, size); | |
free(ucopy); | |
KernelWrite_64bits(profile, copy); | |
uint32_t container_off = 0; | |
char *found = NULL; | |
int idx = 0; | |
do { | |
if (found) { | |
free(found); | |
found = NULL; | |
} | |
uint16_t string_off = (uint16_t)KernelRead_32bits(copy + 14 + (numsbops + 2) * 2 * idx); | |
uint32_t size = KernelRead_32bits(copy + string_off * 8); | |
found = malloc(size); | |
KernelRead(copy + string_off * 8 + 4, found, size); | |
container_off = 14 + (numsbops + 2) * 2 * idx; | |
idx++; | |
} while (strcmp(found, "container")); | |
idx = 0; | |
uint32_t val = 0; | |
uint16_t patch = 0; | |
do { | |
KernelRead(copy + container_off + idx * 2, &patch, sizeof(uint16_t)); | |
val = KernelRead_32bits(copy + patch * 8); | |
idx++; | |
} while (val != 1); | |
KernelWrite(copy + container_off + 4 + fme_idx * 2, &patch, sizeof(uint16_t)); | |
KernelWrite(copy + container_off + 4 + fread_idx * 2, &patch, sizeof(uint16_t)); | |
KernelWrite(copy + container_off + 4 + freaddata_idx * 2, &patch, sizeof(uint16_t)); | |
KernelWrite(copy + container_off + 4 + freadmeta_idx * 2, &patch, sizeof(uint16_t)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment