3636static bool need_convert_port_to_map_patch = false;
3737static 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+
84103static 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
207307static bool found_task_conversion_eval_ldr = false;
0 commit comments