如何解决在 XNU 内核上补丁查找某个函数的指针的最佳方法是什么?
我目前正在开发适用于 iOS 13.7 的 iOS 越狱。
作为越狱的一部分,我需要对内存中的 xnu 内核进行一系列补丁。
当然,内核受到 kASLR
、KPP
/ KTRR
和其他内存看门狗的保护,如果某些内容被修改,则会触发内核恐慌。
幸运的是,KTRR
(仅内核文本就绪区域)只能保护不应该更改的静态数据(即 TEXT
部分和常量)。变量仍然可以改变。
我正在构建一个 PatchFinder,它应该根据指示符号在 xnu 内存中定位一个函数或变量,我想知道什么是最有效的方法。
我目前正在通过 in7egal
在 iOS 8 时代的 PatchFinder made publicly available 上进行调整,如下所示:
uint32_t find_cs_enforcement_disable_amfi(uint32_t region,uint8_t* kdata,size_t ksize)
{
// Find a function referencing cs_enforcement_disable_amfi
const uint8_t search_function[] = {0x20,0x68,0x40,0xF4,0x70,0x20,0x60,0x00,0x90,0xBD};
uint8_t* ptr = memmem(kdata,ksize,search_function,sizeof(search_function));
if(!ptr)
return 0;
// Only LDRB in there should try to dereference cs_enforcement_disable_amfi
uint16_t* ldrb = find_last_insn_matching(region,kdata,(uint16_t*) ptr,insn_is_ldrb_imm);
if(!ldrb)
return 0;
// Weird,not the right one.
if(insn_ldrb_imm_imm(ldrb) != 0 || insn_ldrb_imm_rt(ldrb) > 12)
return 0;
// See what address that LDRB is dereferencing
return find_pc_rel_value(region,ldrb,insn_ldrb_imm_rn(ldrb));
}
我想知道是否有任何更快或更可靠的方法来定位 cs_enforcement_disable_amfi
。
一旦被 xnu Kernel 内存中的 PatchFinder 发现,它的使用方式如下:
uint32_t cs_enforcement_disable_amfi = find_cs_enforcement_disable_amfi(kernel_base,ksize);
printf("cs_enforcement_disable_amfi is at=0x%08x\n",cs_enforcement_disable_amfi);
if (cs_enforcement_disable_amfi){
char patch[] ="\x00\xbf\x00\xbf\x00\xbf\x00\xbf\x00\xbf";
kern_return_t kernret = vm_write(proccesstask,cs_enforcement_disable_amfi+kernel_base,patch,sizeof(patch)-1);
if (kernret == KERN_SUCCESS){
printf("Successfully patched cs_enforcement_disable_amfi\n");
}
}
因此 PatchFinder 必须能够可靠地将指针返回到 cs_enforcement_disable_amfi
否则我会盲目地写入无效(或有效但不同)的地址,这几乎肯定会触发内存损坏。
当前代码在大多数情况下确实返回了一个指向 cs_enforcement_disable_amfi
的有效指针,但在大约 10-15% 的时间内随机使内核恐慌,这意味着它在 10-15% 的时间内返回的地址无效.不知道如何让它更可靠。
解决方法
您要查找的变量已不存在。
第一个片段中的字节组成了 Thumb 指令,这些指令在 32 位内核缓存的 AMFI 中找到此函数:
0x8074ad04 90b5 push {r4,r7,lr}
0x8074ad06 01af add r7,sp,4
0x8074ad08 0d48 ldr r0,[0x8074ad40]
0x8074ad0a 7844 add r0,pc
0x8074ad0c 0078 ldrb r0,[r0]
0x8074ad0e 0128 cmp r0,1
0x8074ad10 03d1 bne 0x8074ad1a
0x8074ad12 0020 movs r0,0
0x8074ad14 00f04efa bl 0x8074b1b4
0x8074ad18 30b9 cbnz r0,0x8074ad28
0x8074ad1a 7c69 ldr r4,[r7,0x14]
0x8074ad1c 002c cmp r4,0
0x8074ad1e 05d0 beq 0x8074ad2c
0x8074ad20 2068 ldr r0,[r4]
0x8074ad22 40f44070 orr r0,r0,0x300
0x8074ad26 2060 str r0,[r4]
0x8074ad28 0020 movs r0,0
0x8074ad2a 90bd pop {r4,pc}
鉴于魔法常数 0x300
以及 AMFI 的 __TEXT_EXEC
段非常小这一事实,我们可以在其他内核(包括 64 位内核)中轻松找到这一点。
这是在 8.4 版本的 iPhone 5s 上的样子:
0xffffff800268d2e4 f44fbea9 stp x20,x19,[sp,-0x20]!
0xffffff800268d2e8 fd7b01a9 stp x29,x30,0x10]
0xffffff800268d2ec fd430091 add x29,0x10
0xffffff800268d2f0 f30307aa mov x19,x7
0xffffff800268d2f4 e8fc1110 adr x8,section.com.apple.driver.AppleMobileFileIntegrity.10.__DATA.__bss
0xffffff800268d2f8 1f2003d5 nop
0xffffff800268d2fc 08054039 ldrb w8,[x8,1]
0xffffff800268d300 a8000037 tbnz w8,0xffffff800268d314
0xffffff800268d304 130100b4 cbz x19,0xffffff800268d324
0xffffff800268d308 680240b9 ldr w8,[x19]
0xffffff800268d30c 08051832 orr w8,w8,0x300
0xffffff800268d310 680200b9 str w8,[x19]
0xffffff800268d314 00008052 mov w0,0
0xffffff800268d318 fd7b41a9 ldp x29,0x10]
0xffffff800268d31c f44fc2a8 ldp x20,[sp],0x20
0xffffff800268d320 c0035fd6 ret
但是到了 iOS 11 的时候,这个变量已经消失了:
0xfffffff006245d84 f44fbea9 stp x20,-0x20]!
0xfffffff006245d88 fd7b01a9 stp x29,0x10]
0xfffffff006245d8c fd430091 add x29,0x10
0xfffffff006245d90 f30307aa mov x19,x7
0xfffffff006245d94 130100b4 cbz x19,0xfffffff006245db4
0xfffffff006245d98 680240b9 ldr w8,[x19]
0xfffffff006245d9c 08051832 orr w8,0x300
0xfffffff006245da0 680200b9 str w8,[x19]
0xfffffff006245da4 00008052 mov w0,0
0xfffffff006245da8 fd7b41a9 ldp x29,0x10]
0xfffffff006245dac f44fc2a8 ldp x20,0x20
0xfffffff006245db0 c0035fd6 ret
以 iOS 12.0b1 为例,我们可以了解到该函数的签名:
_vnode_check_exec(ucred*,vnode*,label*,componentname*,unsigned int*,void*,unsigned long)
是的,找到这个函数真的很容易:
- 查找 AMFI 的
__TEXT_EXEC
细分。 - 在其中找到一个
orr wN,wN,0x300
。
但是除非您破坏内核完整性,否则这对您没有帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。