Skip to content

Commit 02860f4

Browse files
feat: unhardcode code signature bypass patches
1 parent b1f2a23 commit 02860f4

2 files changed

Lines changed: 112 additions & 52 deletions

File tree

hw/arm/apple-silicon/kernel_patches.c

Lines changed: 112 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
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

180182
static 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

269271
static 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

298300
static 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

321323
static 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

365367
static 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

377381
static 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

406411
static 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

418424
static 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.
437443
static 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

445451
static 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

461468
static 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+
478549
void 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
}

hw/arm/apple-silicon/t8030.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,20 +169,6 @@ static void t8030_patch_kernel(MachoHeader64 *hdr, uint32_t build_version)
169169
*(uint32_t *)vtop_slid(0xFFFFFFF008F6F774) = cpu_to_le32(0x52800000);
170170
*(uint32_t *)vtop_slid(0xFFFFFFF008F6F778) = cpu_to_le32(0xD65F0FFF);
171171
#endif
172-
173-
const uint32_t ret = cpu_to_le32(0xD65F03C0);
174-
175-
// _ubc_cs_check_validation_bitmap return 0
176-
*(uint32_t *)vtop_slid(0xFFFFFFF007EBDF40) = cpu_to_le32(0xD2800000);
177-
*(uint32_t *)vtop_slid(0xFFFFFFF007EBDF44) = ret;
178-
179-
// _pmap_cs_enforce_library_validation return 0
180-
*(uint32_t *)vtop_slid(0xFFFFFFF0097E4D2C) = cpu_to_le32(0xD2800000);
181-
*(uint32_t *)vtop_slid(0xFFFFFFF0097E4D30) = ret;
182-
183-
// pmap_cs_enforce return 0
184-
*(uint32_t *)vtop_slid(0xFFFFFFF0097EB5A8) = cpu_to_le32(0xD2800000);
185-
*(uint32_t *)vtop_slid(0xFFFFFFF0097EB5AC) = ret;
186172
}
187173

188174
static bool t8030_check_panic(T8030MachineState *t8030_machine)

0 commit comments

Comments
 (0)