Skip to content

Commit eb1ec32

Browse files
committed
add ipad6 ipados18 patches
1 parent 5d2d2ef commit eb1ec32

File tree

4 files changed

+162
-2
lines changed

4 files changed

+162
-2
lines changed

checkra1n/kpf-test/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ typedef struct boot_args
9292
uint64_t bootFlags;
9393
uint64_t memSizeActual;
9494
} iOS13;
95+
struct {
96+
char CommandLine[0x400];
97+
uint32_t __pad;
98+
uint64_t bootFlags;
99+
uint64_t memSizeActual;
100+
} iOS18;
95101
};
96102
} __attribute__((packed)) boot_args;
97103

checkra1n/kpf/main.c

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,48 @@ bool sb_ops_callback(struct xnu_pf_patch* patch, uint64_t* sbops_stream) {
10051005
return true;
10061006
}
10071007

1008+
bool found_apfs_root_hash_new = false;
1009+
bool kpf_apfs_root_hash_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
1010+
uint32_t* b = find_prev_insn(opcode_stream, 3, 0x14000000, 0xfc000000);
1011+
1012+
if (!b) return false;
1013+
1014+
uint32_t* cbz = find_next_insn(opcode_stream, 10, 0x34000000, 0xff00001f); // cbz w0, Lvalidated_root_hash
1015+
1016+
if (!cbz) return false;
1017+
1018+
if ((cbz[-1] & 0xfc000000) != 0x94000000) return false; // bl
1019+
1020+
if (found_apfs_root_hash_new)
1021+
panic("kpf_apfs_root_hash_new: found twice!");
1022+
1023+
cbz[-1] = 0x52800000; // mov w0, #0
1024+
1025+
found_apfs_root_hash_new = true;
1026+
1027+
printf("KPF: found apfs_root_hash_new\n");
1028+
return true;
1029+
}
1030+
1031+
void* found_apfs_handle_fsioc_graft = NULL;
1032+
bool kpf_apfs_handle_fsioc_graft_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
1033+
uint32_t* cbz = find_prev_insn(opcode_stream, 20, 0x34000000, 0xff00001f); // cbz w0, Lvalidated_payload_and_manifest
1034+
1035+
if (!cbz) return false;
1036+
1037+
if ((cbz[-1] & 0xfc000000) != 0x94000000) return false; // bl
1038+
1039+
if (found_apfs_handle_fsioc_graft && found_apfs_handle_fsioc_graft != cbz)
1040+
panic("kpf_apfs_handle_fsioc_graft_new: found twice!");
1041+
1042+
cbz[-1] = 0x52800000; // mov w0, #0
1043+
1044+
found_apfs_handle_fsioc_graft = cbz;
1045+
1046+
printf("KPF: found apfs_handle_fsioc_graft_new\n");
1047+
return true;
1048+
}
1049+
10081050
bool found_apfs_rename = false;
10091051
bool kpf_apfs_patches_rename(struct xnu_pf_patch* patch, uint32_t* opcode_stream) {
10101052
if (
@@ -1121,7 +1163,7 @@ bool kpf_apfs_root_snapshot_name(struct xnu_pf_patch *patch, uint32_t *opcode_st
11211163
return true;
11221164
}
11231165

1124-
void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfsop_mount_string_match) {
1166+
void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfsop_mount_string_match, bool ipad6_ipados18) {
11251167
// there is a check in the apfs mount function that makes sure that the kernel task is calling this function (current_task() == kernel_task)
11261168
// we also want to call it so we patch that check out
11271169
// example from i7 13.3:
@@ -1273,6 +1315,46 @@ void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfso
12731315
xnu_pf_maskmatch(patchset,
12741316
"apfs_root_snapshot_name", root_snapshot_matches, root_snapshot_masks, sizeof(root_snapshot_matches) / sizeof(uint64_t), true ,(void *)kpf_apfs_root_snapshot_name);
12751317
}
1318+
1319+
if (ipad6_ipados18) {
1320+
// Patch root hash verification
1321+
1322+
uint64_t root_hash_new_matches[] = {
1323+
0xd3430c02 // ubfx x2, xN, #3, #1
1324+
};
1325+
1326+
uint64_t root_hash_new_masks[] = {
1327+
0xfffffc1f
1328+
};
1329+
1330+
xnu_pf_maskmatch(patchset,
1331+
"apfs_graft_new", root_hash_new_matches, root_hash_new_masks, sizeof(root_hash_new_matches) / sizeof(uint64_t), true ,(void *)kpf_apfs_root_hash_new);
1332+
1333+
// Patch root hash image4 verification
1334+
1335+
uint64_t handle_fsioc_graft_matches[] = {
1336+
0xaa1003e0, // mov x0, x{16-31}
1337+
0xaa1003e1, // mov x1, x{16-31}
1338+
0xaa1003e3, // mov x3, x{16-31}
1339+
0xd2800004, // mov x4, #0
1340+
0xd2800005, // mov x5, #0
1341+
0xaa1003e6, // mov x6, x{16-31}
1342+
0x14000000 // b
1343+
};
1344+
1345+
uint64_t handle_fsioc_graft_masks[] = {
1346+
0xfff0ffff,
1347+
0xfff0ffff,
1348+
0xfff0ffff,
1349+
0xffffffff,
1350+
0xffffffff,
1351+
0xfff0ffff,
1352+
0xfc000000
1353+
};
1354+
1355+
xnu_pf_maskmatch(patchset,
1356+
"handle_fsioc_graft_new", handle_fsioc_graft_matches, handle_fsioc_graft_masks, sizeof(handle_fsioc_graft_matches) / sizeof(uint64_t), false ,(void *)kpf_apfs_handle_fsioc_graft_new);
1357+
}
12761358
}
12771359
static uint32_t* amfi_ret;
12781360
bool kpf_amfi_execve_tail(struct xnu_pf_patch* patch, uint32_t* opcode_stream) {
@@ -2347,6 +2429,19 @@ static void kpf_cmd(void)
23472429
if (!apfs_vfsop_mount_string_match)
23482430
strlcat((char*)((int64_t)gBootArgs->iOS13.CommandLine - 0x800000000 + kCacheableView), " rootdev=md0", 0x270);
23492431

2432+
const char root_hash_string[] = "%s:%d: %s Failed to authenticate root hash (volume type %d): %d\n";
2433+
const char* root_hash_string_match = apfs_text_cstring_range ? memmem(apfs_text_cstring_range->cacheable_base, apfs_text_cstring_range->size, root_hash_string, sizeof(root_hash_string)) : NULL;
2434+
if (!root_hash_string_match) root_hash_string_match = memmem(text_cstring_range->cacheable_base, text_cstring_range->size, root_hash_string, sizeof(root_hash_string));
2435+
2436+
const char graft_image4_string[] = "%s:%d: %s Failed to validate image4 payload and manifest for grafting: %d\n";
2437+
const char* graft_image4_string_match = apfs_text_cstring_range ? memmem(apfs_text_cstring_range->cacheable_base, apfs_text_cstring_range->size, graft_image4_string, sizeof(graft_image4_string)) : NULL;
2438+
if (!graft_image4_string_match) graft_image4_string_match = memmem(text_cstring_range->cacheable_base, text_cstring_range->size, graft_image4_string, sizeof(graft_image4_string));
2439+
2440+
if (gKernelVersion.darwinMajor < 24 || xnu_platform() != PLATFORM_IOS) {
2441+
graft_image4_string_match = NULL;
2442+
root_hash_string_match = NULL;
2443+
}
2444+
23502445
xnu_pf_range_t* bootdata_range = xnu_pf_section(hdr, "__BOOTDATA", "__init");
23512446
xnu_pf_range_t* const_klddata_range = xnu_pf_section(hdr, "__KLDDATA", "__const");
23522447

@@ -2393,6 +2488,51 @@ static void kpf_cmd(void)
23932488

23942489
bool protobox_used = (protobox_string_match != NULL && gKernelVersion.xnuMajor >= 8792);
23952490

2491+
bool ipad6_ipados18 = false;
2492+
#if !defined(KPF_TEST)
2493+
char* model = dt_prop(gDeviceTree, "model", NULL);
2494+
if (gKernelVersion.darwinMajor >= 24 &&
2495+
(strcmp(model, "iPad7,5") == 0 || strcmp(model, "iPad7,6") == 0)) {
2496+
ipad6_ipados18 = true;
2497+
}
2498+
2499+
if (ipad6_ipados18) {
2500+
puts("Fixing up bootargs");
2501+
2502+
dt_node_t *memory_map = dt_node(gDeviceTree, "/chosen/memory-map");
2503+
struct memmap *map = dt_alloc_memmap(memory_map, "FunnyBootArgs");
2504+
if(!map)
2505+
{
2506+
panic("Failed to allocate FunnyBootArgs memory map");
2507+
}
2508+
2509+
struct boot_args* cBootArgs = (struct boot_args*)((uint64_t)gBootArgs - 0x800000000 + kCacheableView);
2510+
struct boot_args* new_BootArgs = alloc_static(0x4000);
2511+
bzero(new_BootArgs, sizeof(struct boot_args));
2512+
new_BootArgs->Revision = 3;
2513+
new_BootArgs->Version = 2;
2514+
new_BootArgs->virtBase = cBootArgs->virtBase;
2515+
new_BootArgs->physBase = cBootArgs->physBase;
2516+
new_BootArgs->memSize = cBootArgs->memSize;
2517+
new_BootArgs->topOfKernelData = cBootArgs->topOfKernelData;
2518+
memcpy(&new_BootArgs->Video, &cBootArgs->Video, sizeof(struct Boot_Video));
2519+
new_BootArgs->machineType = cBootArgs->machineType;
2520+
new_BootArgs->deviceTreeLength = cBootArgs->deviceTreeLength;
2521+
new_BootArgs->deviceTreeP = cBootArgs->deviceTreeP;
2522+
memcpy(new_BootArgs->iOS18.CommandLine, cBootArgs->iOS13.CommandLine, BOOT_LINE_LENGTH_iOS13);
2523+
new_BootArgs->iOS18.bootFlags = cBootArgs->iOS13.bootFlags;
2524+
new_BootArgs->iOS18.memSizeActual = cBootArgs->iOS13.memSizeActual;
2525+
gBootArgs = (void*)(((uint64_t)new_BootArgs) + 0x800000000 - kCacheableView);
2526+
map->addr = ((uint64_t)new_BootArgs) + 0x800000000 - kCacheableView;
2527+
map->size = 0x4000;
2528+
2529+
*(uint32_t*)dt_prop(dt_find(gDeviceTree, "/chosen"), "debug-enabled", NULL) = 1;
2530+
}
2531+
#else
2532+
if (gKernelVersion.darwinMajor >= 24 && xnu_platform() == PLATFORM_IOS)
2533+
ipad6_ipados18 = true;
2534+
#endif
2535+
23962536
for(size_t i = 0; i < sizeof(kpf_components)/sizeof(kpf_components[0]); ++i)
23972537
{
23982538
kpf_component_t *component = kpf_components[i];
@@ -2460,7 +2600,7 @@ static void kpf_cmd(void)
24602600
}
24612601
}
24622602

2463-
kpf_apfs_patches(apfs_patchset, livefs_string_match != NULL, apfs_vfsop_mount_string_match != NULL);
2603+
kpf_apfs_patches(apfs_patchset, livefs_string_match != NULL, apfs_vfsop_mount_string_match != NULL, ipad6_ipados18);
24642604
#if 0
24652605
if(livefs_string_match)
24662606
{

example/include/pongo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define DT_KEY_LEN 0x20
3333
#define BOOT_LINE_LENGTH_iOS12 0x100
3434
#define BOOT_LINE_LENGTH_iOS13 0x260
35+
#define BOOT_LINE_LENGTH_iOS18 0x400
3536

3637
struct Boot_Video {
3738
unsigned long v_baseAddr; /* Base address of video memory */
@@ -68,6 +69,12 @@ typedef struct boot_args {
6869
uint64_t bootFlags; /* Additional flags specified by the bootloader */
6970
uint64_t memSizeActual; /* Actual size of memory */
7071
} iOS13;
72+
struct {
73+
char CommandLine[BOOT_LINE_LENGTH_iOS18]; /* Passed in command line */
74+
uint32_t __pad;
75+
uint64_t bootFlags; /* Additional flags specified by the bootloader */
76+
uint64_t memSizeActual; /* Actual size of memory */
77+
} iOS18;
7178
};
7279
} __attribute__((packed)) boot_args;
7380

src/kernel/pongo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
#define BOOT_LINE_LENGTH_iOS12 0x100
6060
#define BOOT_LINE_LENGTH_iOS13 0x260
61+
#define BOOT_LINE_LENGTH_iOS18 0x400
6162

6263
extern int service_cmd(const char* name, int cmd_id, void* data_in, size_t in_size, void* data_out, size_t* out_size);
6364

@@ -103,6 +104,12 @@ typedef struct boot_args {
103104
uint64_t bootFlags; /* Additional flags specified by the bootloader */
104105
uint64_t memSizeActual; /* Actual size of memory */
105106
} iOS13;
107+
struct {
108+
char CommandLine[BOOT_LINE_LENGTH_iOS18]; /* Passed in command line */
109+
uint32_t __pad;
110+
uint64_t bootFlags; /* Additional flags specified by the bootloader */
111+
uint64_t memSizeActual; /* Actual size of memory */
112+
} iOS18;
106113
};
107114
} __attribute__((packed)) boot_args;
108115

0 commit comments

Comments
 (0)