2424#include "qemu/error-report.h"
2525
2626#define NOP (0xD503201F)
27+ #define MOV_W0_0 (0x52800000)
28+ #define MOV_W0_0_BYTES 0x00, 0x00, 0x80, 0x52
2729#define NOP_BYTES 0x1F, 0x20, 0x03, 0xD5
2830#define RET (0xD65F03C0)
2931#define RETAB (0xD65F0FFF)
@@ -179,29 +181,29 @@ static CKPatcherRange *ck_kp_get_kernel_section(MachoHeader64 *hdr,
179181
180182static void ck_kp_apfs_patches (CKPatcherRange * range )
181183{
182- uint8_t find_root_auth [] = {
184+ static const uint8_t find_root_auth [] = {
183185 0x68 , 0x00 , 0x28 , 0x37 , // tbnz w8, 5, 0xC
184186 0X00 , 0x0A , 0x80 , 0x52 , // mov w0, 0x50
185187 0xC0 , 0x03 , 0x5F , 0xD6 , // ret
186188 };
187- uint8_t repl_root_auth [] = { NOP_BYTES , 0x00 , 0x00 , 0x80 ,
188- 0x52 }; // mov w0, #0
189+ static const uint8_t repl_root_auth [] = { NOP_BYTES , 0x00 , 0x00 , 0x80 ,
190+ 0x52 }; // mov w0, #0
189191 ck_patcher_find_replace (range , "bypass root authentication" , find_root_auth ,
190192 NULL , sizeof (find_root_auth ), repl_root_auth , NULL ,
191193 0 , sizeof (repl_root_auth ));
192194
193- uint8_t find_root_rw [] = {
195+ static const uint8_t find_root_rw [] = {
194196 0x00 , 0x00 , 0x70 , 0x37 , // tbnz w0, 0xE, ?
195197 0xA0 , 0x03 , 0x40 , 0xB9 , // ldr x?, [x29/sp, ?]
196198 0x00 , 0x78 , 0x1F , 0x12 , // and w?, w?, 0xFFFFFFFE
197199 0xA0 , 0x03 , 0x00 , 0xB9 , // str x?, [x29/sp, ?]
198200 };
199- uint8_t mask_root_rw [] = {
201+ static const uint8_t mask_root_rw [] = {
200202 0x1F , 0x00 , 0xF8 , 0xFF , 0xA0 , 0x03 , 0xFE , 0xFF ,
201203 0x00 , 0xFC , 0xFF , 0xFF , 0xA0 , 0x03 , 0xC0 , 0xFF ,
202204 };
203205 QEMU_BUILD_BUG_ON (sizeof (find_root_rw ) != sizeof (mask_root_rw ));
204- uint8_t repl_root_rw [] = { 0x00 , 0x00 , 0x80 , 0x52 }; // mov w0, #0
206+ static const uint8_t repl_root_rw [] = { MOV_W0_0_BYTES };
205207 ck_patcher_find_replace (range , "allow mounting root as r/w" , find_root_rw ,
206208 mask_root_rw , sizeof (find_root_rw ), repl_root_rw ,
207209 NULL , 0 , sizeof (repl_root_rw ));
@@ -268,13 +270,13 @@ static bool ck_kp_tc_callback(void *ctx, uint8_t *buffer)
268270
269271static void ck_kp_tc_patch (CKPatcherRange * range )
270272{
271- uint8_t find [] = {
273+ static const uint8_t find [] = {
272274 0x00 , 0x02 , 0x80 , 0x52 , // mov w?, 0x16
273275 0x00 , 0x00 , 0x00 , 0xD3 , // lsr ?
274276 0x00 , 0x00 , 0x00 , 0x9B , // madd ?
275277 };
276- uint8_t mask [] = { 0x00 , 0xFF , 0xFF , 0xFF , 0x00 , 0x00 ,
277- 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0xFF };
278+ static const uint8_t mask [] = { 0x00 , 0xFF , 0xFF , 0xFF , 0x00 , 0x00 ,
279+ 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0xFF };
278280 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
279281 ck_patcher_find_callback (range , "AMFI, all binaries in trustcache" , find ,
280282 mask , sizeof (find ), ck_kp_tc_callback );
@@ -297,8 +299,8 @@ static bool ck_kp_tc_ios16_callback(void *ctx, uint8_t *buffer)
297299
298300static void ck_kp_tc_ios16_patch (CKPatcherRange * range )
299301{
300- uint8_t find [] = { 0xC0 , 0xCF , 0x9D , 0xD2 }; // mov w?, 0xEE7E
301- uint8_t mask [] = { 0xC0 , 0xFF , 0xFF , 0xFF };
302+ static const uint8_t find [] = { 0xC0 , 0xCF , 0x9D , 0xD2 }; // mov w?, 0xEE7E
303+ static const uint8_t mask [] = { 0xC0 , 0xFF , 0xFF , 0xFF };
302304 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
303305 ck_patcher_find_callback (range , "AMFI, all binaries in trustcache (iOS 16)" ,
304306 find , mask , sizeof (find ), ck_kp_tc_ios16_callback );
@@ -320,8 +322,8 @@ static bool ck_kp_amfi_sha1(void *ctx, uint8_t *buffer)
320322
321323static void ck_kp_amfi_patches (CKPatcherRange * range )
322324{
323- uint8_t find [] = { 0x02 , 0x00 , 0xD0 , 0x36 }; // tbz w2, 0x1A, ?
324- uint8_t mask [] = { 0x1F , 0x00 , 0xF8 , 0xFF };
325+ static const uint8_t find [] = { 0x02 , 0x00 , 0xD0 , 0x36 }; // tbz w2, 0x1A, ?
326+ static const uint8_t mask [] = { 0x1F , 0x00 , 0xF8 , 0xFF };
325327 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
326328 ck_patcher_find_callback (range , "allow SHA1 signatures in AMFI" , find , mask ,
327329 sizeof (find ), ck_kp_amfi_sha1 );
@@ -364,28 +366,31 @@ static bool ck_kp_mac_mount_callback(void *ctx, uint8_t *buffer)
364366
365367static void ck_kp_mac_mount_patch (CKPatcherRange * range )
366368{
367- uint8_t find_old [] = { 0xE9 , 0x2F , 0x1F , 0x32 }; // orr w9, wzr, 0x1FFE
369+ static const uint8_t find_old [] = { 0xE9 , 0x2F , 0x1F ,
370+ 0x32 }; // orr w9, wzr, 0x1FFE
368371 ck_patcher_find_callback (
369372 range , "allow remounting rootfs, union mounts (old)" , find_old , NULL ,
370373 sizeof (find_old ), ck_kp_mac_mount_callback );
371- uint8_t find_new [] = { 0xC9 , 0xFF , 0x83 , 0x52 }; // movz w9, 0x1FFE
374+ static const uint8_t find_new [] = { 0xC9 , 0xFF , 0x83 ,
375+ 0x52 }; // movz w9, 0x1FFE
372376 ck_patcher_find_callback (
373377 range , "allow remounting rootfs, union mounts (new)" , find_new , NULL ,
374378 sizeof (find_new ), ck_kp_mac_mount_callback );
375379}
376380
377381static void ck_kp_kprintf_patch (CKPatcherRange * range )
378382{
379- uint8_t find [] = {
383+ static const uint8_t find [] = {
380384 0xAA , 0x43 , 0x00 , 0x91 , // add x10, fp, #0x10
381385 0xEA , 0x07 , 0x00 , 0xF9 , // str x10, [sp, #0x8]
382386 0x08 , 0x00 , 0x00 , 0x2A , // orr w8, w?, w?
383387 0x08 , 0x00 , 0x00 , 0x34 , // cbz w8, #?
384388 };
385- uint8_t mask [] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
386- 0x1F , 0xFC , 0xE0 , 0xFF , 0x1F , 0x00 , 0x00 , 0xFF };
389+ static const uint8_t mask [] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
390+ 0xFF , 0xFF , 0x1F , 0xFC , 0xE0 , 0xFF ,
391+ 0x1F , 0x00 , 0x00 , 0xFF };
387392 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
388- uint8_t replace [] = { 0xE8 , 0x03 , 0x1F , 0x2A };
393+ static const uint8_t replace [] = { 0xE8 , 0x03 , 0x1F , 0x2A };
389394 ck_patcher_find_replace (range , "force enable kprintf" , find , mask ,
390395 sizeof (find ), replace , NULL , 8 , sizeof (replace ));
391396}
@@ -405,20 +410,21 @@ static bool ck_kp_amx_callback(void *ctx, uint8_t *buffer)
405410
406411static void ck_kp_amx_patch (CKPatcherRange * range )
407412{
408- uint8_t find [] = {
413+ static const uint8_t find [] = {
409414 0xE9 , 0x83 , 0x05 , 0x32 , // mov w9, #0x8000800
410415 0x09 , 0x00 , 0x00 , 0xAA , // orr x9, x?, x?
411416 };
412- uint8_t mask [] = { 0xFF , 0xFF , 0xFF , 0xFF , 0x1F , 0xFC , 0xE0 , 0xFF };
417+ static const uint8_t mask [] = { 0xFF , 0xFF , 0xFF , 0xFF ,
418+ 0x1F , 0xFC , 0xE0 , 0xFF };
413419 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
414420 ck_patcher_find_callback (range , "disable AMX" , find , mask , sizeof (find ),
415421 ck_kp_amx_callback );
416422}
417423
418424static void ck_kp_apfs_snapshot_patch (CKPatcherRange * range )
419425{
420- uint8_t find [] = "com.apple.os.update-" ;
421- uint8_t repl [] = "shitcode.os.bullshit" ;
426+ static const uint8_t find [] = "com.apple.os.update-" ;
427+ static const uint8_t repl [] = "shitcode.os.bullshit" ;
422428 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (repl ));
423429 ck_patcher_find_replace (range , "disable APFS snapshots" , find , NULL ,
424430 sizeof (find ), repl , NULL , 0 , sizeof (repl ));
@@ -436,45 +442,110 @@ static void ck_kp_apfs_snapshot_patch(CKPatcherRange *range)
436442// We do NOT endorse nor approve the theft of property.
437443static void ck_kp_hactivation_patch (CKPatcherRange * range )
438444{
439- uint8_t find [] = "\0release" ;
440- uint8_t repl [] = "profile" ;
445+ static const uint8_t find [] = "\0release" ;
446+ static const uint8_t repl [] = "profile" ;
441447 ck_patcher_find_replace (range , "enable hactivation" , find , NULL ,
442448 sizeof (find ), repl , NULL , 1 , sizeof (repl ));
443449}
444450
445451static void ck_kp_sep_mgr_patches (CKPatcherRange * range )
446452{
447- uint8_t find [] = {
453+ static const uint8_t find [] = {
448454 0x00 , 0x04 , 0x00 , 0xF9 , // str x?, [x?, #0x8]
449455 0x08 , 0x04 , 0x80 , 0x52 , // mov w8, #0x20
450456 0x08 , 0x10 , 0x00 , 0xB9 , // str w8, [x?, #0x10]
451457 };
452- uint8_t mask [] = { 0x00 , 0xFC , 0xFF , 0xFF , 0xFF , 0xFF ,
453- 0xFF , 0xFF , 0x1F , 0xFC , 0xFF , 0xFF };
458+ static const uint8_t mask [] = { 0x00 , 0xFC , 0xFF , 0xFF , 0xFF , 0xFF ,
459+ 0xFF , 0xFF , 0x1F , 0xFC , 0xFF , 0xFF };
454460 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
455- uint8_t repl [] = { 0x28 , 0x00 , 0xA0 , 0x52 }; // mov w8, #0x10000
461+ static const uint8_t repl [] = { 0x28 , 0x00 , 0xA0 ,
462+ 0x52 }; // mov w8, #0x10000
456463 ck_patcher_find_replace (
457464 range , "increase SCOT size to 0x10000 to use it as TRAC" , find , mask ,
458465 sizeof (find ), repl , NULL , 4 , sizeof (repl ));
459466}
460467
461468static void ck_kp_img4_patches (CKPatcherRange * range )
462469{
463- uint8_t find [] = {
470+ static const uint8_t find [] = {
464471 0xE1 , 0x03 , 0x00 , 0xAA , // mov x1, x?
465472 0x00 , 0x00 , 0x00 , 0x94 , // bl #?
466473 0x1F , 0x04 , 0x00 , 0x31 , // cmn w0, #0x1
467474 0x00 , 0x00 , 0x00 , 0x54 , // b.eq #?
468475 };
469- uint8_t mask [] = { 0xFF , 0xFF , 0xE0 , 0xFF , 0x00 , 0x00 , 0x00 , 0xFC ,
470- 0xFF , 0xFF , 0xFF , 0xFF , 0x1F , 0x00 , 0xF8 , 0xFF };
476+ static const uint8_t mask [] = { 0xFF , 0xFF , 0xE0 , 0xFF , 0x00 , 0x00 ,
477+ 0x00 , 0xFC , 0xFF , 0xFF , 0xFF , 0xFF ,
478+ 0x1F , 0x00 , 0xF8 , 0xFF };
471479 QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
472- uint8_t repl [] = { 0x00 , 0x00 , 0x80 , 0x52 , NOP_BYTES }; // mov w0, #0
480+ static const uint8_t repl [] = { MOV_W0_0_BYTES , NOP_BYTES }; // mov w0, #0
473481 ck_patcher_find_replace (
474482 range , "allow unsigned firmware in img4_firmware_evaluate" , find , mask ,
475483 sizeof (find ), repl , NULL , 8 , sizeof (repl ));
476484}
477485
486+ static void ck_kp_cs_patches (CKPatcherRange * range )
487+ {
488+ // skip code signature checks in vm_fault_enter
489+ static const uint8_t find [] = {
490+ 0x00 , 0x00 , 0x18 , 0x36 , // tbz w?, #3, #?
491+ 0x00 , 0x00 , 0x80 , 0x52 , // mov w?, #0
492+ };
493+ static const uint8_t mask [] = { 0x00 , 0x00 , 0xF8 , 0xFF ,
494+ 0xE0 , 0xFF , 0xFF , 0xFF };
495+ QEMU_BUILD_BUG_ON (sizeof (find ) != sizeof (mask ));
496+ static const uint8_t repl [] = { NOP_BYTES };
497+ ck_patcher_find_replace (range , "bypass code signature checks" , find , mask ,
498+ sizeof (find ), repl , NULL , 0 , sizeof (repl ));
499+ static const uint8_t find_alt [] = {
500+ 0x00 , 0x00 , 0x18 , 0x36 , // tbz w?, #3, #?
501+ 0x10 , 0x02 , 0x17 , 0xAA , // mov x?, x?
502+ 0x00 , 0x00 , 0x80 , 0x52 , // mov w?, #0
503+ };
504+ static const uint8_t mask_alt [] = { 0x00 , 0x00 , 0xF8 , 0xFF , 0x10 , 0xFE ,
505+ 0xFF , 0xFF , 0xE0 , 0xFF , 0xFF , 0xFF };
506+ QEMU_BUILD_BUG_ON (sizeof (find_alt ) != sizeof (mask_alt ));
507+ ck_patcher_find_replace (range , "bypass code signature checks (alt)" ,
508+ find_alt , mask_alt , sizeof (find_alt ), repl , NULL , 0 ,
509+ sizeof (repl ));
510+ }
511+
512+ static bool ck_kp_pmap_cs_enforce_callback (void * ctx , uint8_t * buffer )
513+ {
514+ uint8_t * pacibsp =
515+ ck_patcher_find_prev_insn (buffer , 0x30 , PACIBSP , 0xFFFFFFFF , 0 );
516+ if (pacibsp == NULL ) {
517+ error_report ("%s: failed to find pacibsp" , __func__ );
518+ return false;
519+ }
520+ stl_le_p (pacibsp , MOV_W0_0 );
521+ stl_le_p (pacibsp + 4 , RET );
522+ return true;
523+ }
524+
525+ static void ck_kp_pmap_cs_enforce_patch (CKPatcherRange * range )
526+ {
527+ static const uint8_t find_pmap_cs_enforce [] = {
528+ 0xE0 , 0x03 , 0x00 , 0xAA , // mov x0, x?
529+ 0xE1 , 0x03 , 0x00 , 0xAA , // mov x1, x?
530+ 0x02 , 0x10 , 0x80 , 0x52 , // mov w2, #0x80
531+ 0x03 , 0x10 , 0x80 , 0x52 , // mov w3, #0x80
532+ 0x04 , 0x00 , 0x80 , 0x52 , // mov w4, #0
533+ 0x00 , 0x00 , 0x00 , 0x94 , // bl #?
534+ };
535+ static const uint8_t mask_pmap_cs_enforce [] = {
536+ 0xFF , 0xFF , 0xE0 , 0xFF , 0xFF , 0xFF , 0xE0 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
537+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x00 , 0x00 , 0x00 , 0xFC
538+ };
539+ QEMU_BUILD_BUG_ON (sizeof (find_pmap_cs_enforce ) !=
540+ sizeof (mask_pmap_cs_enforce ));
541+ ck_patcher_find_callback (range , "bypass pmap_cs_enforce" ,
542+ find_pmap_cs_enforce , mask_pmap_cs_enforce ,
543+ sizeof (find_pmap_cs_enforce ),
544+ ck_kp_pmap_cs_enforce_callback );
545+ fprintf (stderr , "%s: base=0x%llX size=0x%llX end=0x%llX" , __func__ ,
546+ range -> addr , range -> length , range -> addr + range -> length );
547+ }
548+
478549void ck_patch_kernel (MachoHeader64 * hdr )
479550{
480551 MachoHeader64 * apfs_hdr ;
@@ -485,7 +556,7 @@ void ck_patch_kernel(MachoHeader64 *hdr)
485556 g_autofree CKPatcherRange * img4_text ;
486557 g_autofree CKPatcherRange * kernel_text ;
487558 g_autofree CKPatcherRange * kernel_const ;
488- g_autofree CKPatcherRange * ppltext_exec ;
559+ g_autofree CKPatcherRange * kernel_ppltext ;
489560
490561 apfs_hdr = ck_kp_find_image_header (hdr , "com.apple.filesystems.apfs" );
491562 apfs_text = ck_kp_find_section_range (apfs_hdr , "__TEXT_EXEC" , "__text" );
@@ -512,14 +583,17 @@ void ck_patch_kernel(MachoHeader64 *hdr)
512583 ck_kp_mac_mount_patch (kernel_text );
513584 ck_kp_kprintf_patch (kernel_text );
514585 ck_kp_amx_patch (kernel_text );
586+ ck_kp_cs_patches (kernel_text );
515587 kernel_const = ck_kp_get_kernel_section (hdr , "__TEXT" , "__const" );
516588 ck_kp_hactivation_patch (kernel_const );
517589
518- ppltext_exec = ck_kp_find_section_range (hdr , "__PPLTEXT" , "__text" );
519- if (ppltext_exec == NULL ) {
590+ kernel_ppltext = ck_kp_find_section_range (hdr , "__PPLTEXT" , "__text" );
591+ if (kernel_ppltext == NULL ) {
520592 warn_report ("Failed to find `__PPLTEXT.__text`." );
593+ ck_kp_pmap_cs_enforce_patch (kernel_text );
521594 } else {
522- ck_kp_tc_patch (ppltext_exec );
523- ck_kp_tc_ios16_patch (ppltext_exec );
595+ ck_kp_tc_patch (kernel_ppltext );
596+ ck_kp_tc_ios16_patch (kernel_ppltext );
597+ ck_kp_pmap_cs_enforce_patch (kernel_ppltext );
524598 }
525599}
0 commit comments