Skip to content

Commit 3d4a85b

Browse files
committed
Fix convert_port_to_map for 18.4
1 parent 44f9f10 commit 3d4a85b

1 file changed

Lines changed: 109 additions & 9 deletions

File tree

checkra1n/kpf/mach_port.c

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
static bool need_convert_port_to_map_patch = false;
3737
static bool found_convert_port_to_map = false;
3838

39-
static bool kpf_convert_port_to_map_callback(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
39+
static bool kpf_convert_port_to_map_callback(struct xnu_pf_patch *patch, uint32_t *patchpoint)
4040
{
4141
// Only once
4242
if(found_convert_port_to_map)
@@ -45,7 +45,6 @@ static bool kpf_convert_port_to_map_callback(struct xnu_pf_patch *patch, uint32_
4545
}
4646
found_convert_port_to_map = true;
4747

48-
uint32_t *patchpoint = opcode_stream + 7;
4948
uint32_t op = *patchpoint;
5049
if(op & 1) // is b.ne
5150
{
@@ -66,8 +65,13 @@ static bool kpf_convert_port_to_map_callback(struct xnu_pf_patch *patch, uint32_
6665
(patchpoint[1] & 0xffffe0ff) == 0x52800001 && // movz w1, {0x0-0x100 with granularity 8}
6766
(patchpoint[2] & 0xfc000000) == 0x94000000; // bl zone_require
6867
#ifdef DEV_BUILD
69-
// This is a whole mess: 15.0 beta 2 through 15.3 final, and then again 16.4 beta 1 through 16.x latest.
70-
if(have_zone_require != ((gKernelVersion.xnuMajor > 7938 && gKernelVersion.xnuMajor < 8020) || (gKernelVersion.xnuMajor > 8792 && gKernelVersion.xnuMajor < 10002)))
68+
// This is a whole mess: 15.0 beta 2 through 15.3 final, and then again 16.4 beta 1 through 16.x latest...
69+
// ...AND specifically for tvOS/audioOS 18.4 beta 1, but ONLY for A8... absolute psychosis.
70+
if(have_zone_require != (
71+
(gKernelVersion.xnuMajor > 7938 && gKernelVersion.xnuMajor < 8020) ||
72+
(gKernelVersion.xnuMajor > 8792 && gKernelVersion.xnuMajor < 10002) ||
73+
(gKernelVersion.xnuMajor == 11417 && gKernelVersion.xnuMinor == 100 && gKernelVersion.xnuPatch == 533 && gKernelVersion.xnuFlags == 503 && gKernelVersion.xnuRevision == 3 && gKernelVersion.machineConfig == 0x7000)
74+
))
7175
{
7276
panic_at(patchpoint, "kpf_convert_port_to_map: zone_require doesn't match expected XNU version");
7377
}
@@ -81,6 +85,21 @@ static bool kpf_convert_port_to_map_callback(struct xnu_pf_patch *patch, uint32_
8185
return true;
8286
}
8387

88+
static bool kpf_convert_port_to_map_callback_old(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
89+
{
90+
return kpf_convert_port_to_map_callback(patch, opcode_stream + 7);
91+
}
92+
93+
static bool kpf_convert_port_to_map_callback_new_short(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
94+
{
95+
return kpf_convert_port_to_map_callback(patch, opcode_stream + 8);
96+
}
97+
98+
static bool kpf_convert_port_to_map_callback_new_long(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
99+
{
100+
return kpf_convert_port_to_map_callback(patch, opcode_stream + 9);
101+
}
102+
84103
static void kpf_convert_port_to_map_patch(xnu_pf_patchset_t *xnu_text_exec_patchset)
85104
{
86105
// This patch is required because in some iOS 14.0 beta, Apple started cracking down on tfp0 usage.
@@ -159,13 +178,13 @@ static void kpf_convert_port_to_map_patch(xnu_pf_patchset_t *xnu_text_exec_patch
159178
0xffe0fc1f,
160179
0xff00001e,
161180
};
162-
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches, masks, sizeof(matches)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback);
181+
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches, masks, sizeof(matches)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback_old);
163182

164183
matches[4] = NOP;
165184
masks[4] = 0xffffffff;
166185
matches[5] = 0x58000000; // ldr (literal)
167186
masks[5] = 0xff000000;
168-
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches, masks, sizeof(matches)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback);
187+
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches, masks, sizeof(matches)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback_old);
169188

170189
// iOS 15.5 changes the adrp+ldr to an adrp+add:
171190
//
@@ -179,7 +198,7 @@ static void kpf_convert_port_to_map_patch(xnu_pf_patchset_t *xnu_text_exec_patch
179198
// 0xfffffff0071d11cc c0000054 b.eq 0xfffffff0071d11e4
180199
//
181200
// /x 0000403900000034000040f9002040f900000090000000911f0000eb00000054:0000c0ff000000ff00c0ffff00f8ffff0000009f0000c0ff1ffce0ff1e0000ff
182-
uint64_t matches_variant[] =
201+
uint64_t matches_155[] =
183202
{
184203
0x39400000, // ldrb wN, [xM, ...]
185204
0x34000000, // cbz
@@ -190,7 +209,7 @@ static void kpf_convert_port_to_map_patch(xnu_pf_patchset_t *xnu_text_exec_patch
190209
0xeb00001f, // cmp
191210
0x54000000, // b.ne / b.eq
192211
};
193-
uint64_t masks_variant[] =
212+
uint64_t masks_155[] =
194213
{
195214
0xffc00000,
196215
0xff000000,
@@ -201,7 +220,88 @@ static void kpf_convert_port_to_map_patch(xnu_pf_patchset_t *xnu_text_exec_patch
201220
0xffe0fc1f,
202221
0xff00001e,
203222
};
204-
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches_variant, masks_variant, sizeof(matches_variant)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback);
223+
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches_155, masks_155, sizeof(matches_155)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback_old);
224+
225+
// iOS 18.4 changed this yet again to either this:
226+
//
227+
// 0xfffffff0071d57fc 08504039 ldrb w8, [x0, 0x14]
228+
// 0xfffffff0071d5800 1f050071 cmp w8, 1
229+
// 0xfffffff0071d5804 01feff54 b.ne 0xfffffff0071d57c4
230+
// 0xfffffff0071d5808 141440f9 ldr x20, [x0, 0x28]
231+
// 0xfffffff0071d580c 822240f9 ldr x2, [x20, 0x40]
232+
// 0xfffffff0071d5810 e83b0090 adrp x8, 0xfffffff007951000
233+
// 0xfffffff0071d5814 08e10091 add x8, x8, 0x38
234+
// 0xfffffff0071d5818 5f0008eb cmp x2, x8
235+
// 0xfffffff0071d581c 40020054 b.eq 0xfffffff0071d5864
236+
//
237+
// Or this:
238+
//
239+
// 0xfffffff00723372c 08504039 ldrb w8, [x0, 0x14]
240+
// 0xfffffff007233730 1f050071 cmp w8, 1
241+
// 0xfffffff007233734 01feff54 b.ne 0xfffffff0072336f4
242+
// 0xfffffff007233738 081440f9 ldr x8, [x0, 0x28]
243+
// 0xfffffff00723373c f40308aa mov x20, x8
244+
// 0xfffffff007233740 082140f9 ldr x8, [x8, 0x40]
245+
// 0xfffffff007233744 893c00d0 adrp x9, 0xfffffff0079c5000
246+
// 0xfffffff007233748 29e10191 add x9, x9, 0x78
247+
// 0xfffffff00723374c 1f0109eb cmp x8, x9
248+
// 0xfffffff007233750 c0000054 b.eq 0xfffffff007233768
249+
//
250+
// /x 000040391f04007101000054000040f9002040f900000090000000911f0000eb00000054:0000c0ff1ffcffff1f0000ff00c0ffff00f8ffff0000009f0000c0ff1ffce0ff1e0000ff
251+
// /x 000040391f04007101000054000040f9f00300aa002040f900000090000000911f0000eb00000054:0000c0ff1ffcffff1f0000ff00c0fffff0fff0ff00f8ffff0000009f0000c0ff1ffce0ff1e0000ff
252+
uint64_t matches_184[] =
253+
{
254+
0x39400000, // ldrb wN, [xM, ...]
255+
0x7100041f, // cmp wN, 1
256+
0x54000001, // b.ne
257+
0xf9400000, // ldr xN, [xM, {0x0-0x78}]
258+
0xf9402000, // ldr xN, [xM, {0x40|0x48}]
259+
0x90000000, // adrp
260+
0x91000000, // add
261+
0xeb00001f, // cmp
262+
0x54000000, // b.ne / b.eq
263+
};
264+
uint64_t masks_184[] =
265+
{
266+
0xffc00000,
267+
0xfffffc1f,
268+
0xff00001f,
269+
0xffffc000,
270+
0xfffff800,
271+
0x9f000000,
272+
0xffc00000,
273+
0xffe0fc1f,
274+
0xff00001e,
275+
};
276+
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches_184, masks_184, sizeof(matches_184)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback_new_short);
277+
278+
uint64_t matches_184_variant[] =
279+
{
280+
0x39400000, // ldrb wN, [xM, ...]
281+
0x7100041f, // cmp wN, 1
282+
0x54000001, // b.ne
283+
0xf9400000, // ldr xN, [xM, {0x0-0x78}]
284+
0xaa0003f0, // mov x{16-31}, x{0-15}
285+
0xf9402000, // ldr xN, [xM, {0x40|0x48}]
286+
0x90000000, // adrp
287+
0x91000000, // add
288+
0xeb00001f, // cmp
289+
0x54000000, // b.ne / b.eq
290+
};
291+
uint64_t masks_184_variant[] =
292+
{
293+
0xffc00000,
294+
0xfffffc1f,
295+
0xff00001f,
296+
0xffffc000,
297+
0xfff0fff0,
298+
0xfffff800,
299+
0x9f000000,
300+
0xffc00000,
301+
0xffe0fc1f,
302+
0xff00001e,
303+
};
304+
xnu_pf_maskmatch(xnu_text_exec_patchset, "convert_port_to_map", matches_184_variant, masks_184_variant, sizeof(matches_184_variant)/sizeof(uint64_t), false, (void*)kpf_convert_port_to_map_callback_new_long);
205305
}
206306

207307
static bool found_task_conversion_eval_ldr = false;

0 commit comments

Comments
 (0)