-
-
[原创]iOS内核修改之过某音等PT_DENY_ATTACH反动态ptrace调试
-
发表于:
2021-4-1 16:39
24605
-
[原创]iOS内核修改之过某音等PT_DENY_ATTACH反动态ptrace调试
现在很多iOS App都有PT_DENY_ATTACH反调试, 造成debugserver无法附加调试.
1 2 3 4 | debugserver-@(
for arm64.
Attaching to process 1468...
Segmentation fault: 11
|
光是用Frida调动Hook进行分析难度和工作量很大,里还有很多动态跳转,静态分析难度重重.
重新打包IPA,之前hook ptrace或sysctl等方法跳过检测也已经失效,因为现在都是直接调用syscall调用内核接口.
1 2 3 4 5 6 7 8 9 10 11 | static __attribute__((always_inline)) void asm_ptrace() {
__asm__("mov X0, #31\n"
"mov X1, #0\n"
"mov X2, #0\n"
"mov X3, #0\n"
"mov X16, #26\n"
"svc #0x80\n"
);
}
|
所以比较好的解决方法就是对内核进行修改.先看一下ptrace内核的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | int
ptrace(struct proc *p, struct ptrace_args *uap, int32_t *retval)
{
//....
if (uap->req == PT_DENY_ATTACH) {
//....
proc_lock(p);
if (ISSET(p->p_lflag, P_LTRACED)) {
proc_unlock(p);
//...
exit1(p, W_EXITCODE(ENOTSUP, 0), retval);
thread_exception_return();
/* NOTREACHED */
}
SET(p->p_lflag, P_LNOATTACH);//p_lflag |=0x00001000
proc_unlock(p);
return 0;
}
|
实现PT_DENY_ATTACH很简单,就是对相关进程proc的p_lflag加上P_LNOATTACH标识位.
那调试就是去掉P_LNOATTACH就行,那就要找到当前系统所有的进程信息,所有进程都放在了kernproc
1 2 3 4 5 | /* Components of the first process -- never freed. */
struct proc proc0 = { .p_comm = "kernel_task", .p_name = "kernel_task" };
SECURITY_READ_ONLY_LATE(proc_t) kernproc = &proc0;
proc_t XNU_PTRAUTH_SIGNED_PTR("initproc") initproc;
|
再找到相关进程的proc,查看proc的结构,也就是所有的内核kernproc(proc0)的子进程都放在了p_list里
1 2 3 | struct proc {
LIST_ENTRY(proc) p_list; /* List of all processes. */
****
|
找到kernproc在内核的地址,然后通tfp0(task for pid 0)调用
mach_vm_read读取kernproc,遍历kernproc的p_list找到相当进程的proc,对p_lflag,进行修改,再mach_vm_write写回内存即可.
1 2 3 4 | if (proc->p_pid == pid) {
proc->p_lflag &= P_LNOATTACH;//P_LNOATTACH=0x1000
mach_vm_write (...&proc->p_lflag...)
}
|
debugserver此时已经可以进行调试.
有兴趣一起研究iOS内核开发交流可Q: 3.1.0.4.1.9.0.6.2 (倒序) 简单的如tfp0是什么,怎么实现就不要来问我了
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!
最后于 2021-4-1 17:22
被alice编辑
,原因: