diff --git a/checkra1n/kpf/main.c b/checkra1n/kpf/main.c index 567a092e..672fcce1 100644 --- a/checkra1n/kpf/main.c +++ b/checkra1n/kpf/main.c @@ -1926,6 +1926,32 @@ bool kpf_amfi_mac_syscall_low(struct xnu_pf_patch *patch, uint32_t *opcode_strea // So we need to follow the b.eq for 0x5a here. return kpf_amfi_mac_syscall(patch, opcode_stream + 3 + sxt32(opcode_stream[3] >> 5, 19)); // uint32 takes care of << 2 } + +// written in nano fr +bool kpf_amfi_hash_agility(struct xnu_pf_patch *patch, uint32_t *opcode_stream) { + uint64_t page = ((uint64_t)(opcode_stream) & ~0xfffULL) + adrp_off(opcode_stream[0]); + uint32_t off = (opcode_stream[1] >> 10) & 0xfff; + const char *str = (const char *)(page + off); + + if (strcmp(str, "AMFI: \'%s\': no hash agility data and first cd hash type (%d) does not match best cd hash type (%d)\n") == 0) { + uint32_t *b = find_next_insn(opcode_stream, 0x6, 0x14000000, 0xff000000); + + b[0] = NOP; + + printf("KPF: found not best cdhash type\n"); + return true; + } else if (strcmp(str, "AMFI: \'%s\': first code directory doesn\'t match the best code directory, but no hash agility data") == 0) { + uint32_t *b = find_next_insn(opcode_stream, 0x4, 0x14000000, 0xff000000); + + b[0] = NOP; + + printf("KPF: found not best code directory\n"); + return true; + } else { + return false; + } +} + void kpf_amfi_kext_patches(xnu_pf_patchset_t* patchset) { // this patch helps us find the return of the amfi function so that we can jump into shellcode from there and modify the cs flags // to do that we search for the sequence below also as an example from i7 13.3: @@ -2109,6 +2135,16 @@ void kpf_amfi_kext_patches(xnu_pf_patchset_t* patchset) { 0xff00001f, }; xnu_pf_maskmatch(patchset, "amfi_mac_syscall_low", iiii_matches, iiii_masks, sizeof(iiii_matches)/sizeof(uint64_t), false, (void*)kpf_amfi_mac_syscall_low); + + uint64_t iiiiii_matches[] = { + 0x00000000, + 0x91000000, + }; + uint64_t iiiiii_masks[] = { + 0x0f000000, + 0xff000000, + }; + xnu_pf_maskmatch(patchset, "hash_agility", iiiiii_matches, iiiiii_masks, sizeof(iiiiii_matches)/sizeof(uint64_t), false, (void*)kpf_amfi_hash_agility); } void kpf_sandbox_kext_patches(xnu_pf_patchset_t* patchset) {