用 sysctl/proc 等枚举或 remote 请求得到 PID例如如果通过进程名获取进程 PID:调用一个内部函数 GetAllInfosMatchingName:内部会调用 sysctl,从内核中枚举出所有进程(CTL_KERN, KERN_PROC, KERN_PROC_ALL)。 --》DNBGetAllInfos然后遍历列表,把 kp_proc.p_comm(进程名字段)与 name 比较。把所有匹配的结果放入 matching_proc_infos基本mach要走的基本流程点本文在lldb方面就不再过多赘述--例如MachTask::TaskPortForProcessID这一块最后会走 MachProcess::AttachForDebug(),这个实现会使用 ptrace(如 PT_ATTACHEXC)。路径如下从这一步来说lldb就已经借用了ptrace,如果有如下反调试代码
会设置 exception ports(Mach)来接收 kernel 发来的异常;1.保存原有异常端口调用 task_get_exception_ports(...) 把当前的端口、行为、flavor 等读出来备份2.恢复/写回异常端口PortInfo::Restore() 里循环调用 task_set_exception_ports(...) 把之前保存的端口逐项写回。如果这时候就已经发生了EXC_SOFT_SIGNALlldb在异常路径中会去调用 ptrace 更新信号(PT_THUPDATE)debugserver 用 PT_THUPDATE 把信号补到内核的 signal ,来保证把 Mach 异常与 UNIX 信号对齐拦截异常 →(可选)通过 PT_THUPDATE 注入/抑制信号 → mach_msg 回复恢复线程,控制调试行为,又保持进程的 UNIX 信号语义不变
和lldb操作一样,用 sysctl/proc 等枚举或 remote 请求得到 PIDtask_for_pid(self, pid, &task) 拿到目标 task。mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &exc_port) 分配一个异常接收端口;mach_port_insert_right(self, exc_port, exc_port, MACH_MSG_TYPE_MAKE_SEND) 插入发送权;task_set_exception_ports(task, 0x1BFE, exc_port, EXCEPTION_DEFAULT(1), MACHINE_THREAD_STATE(6)) 把所有重要异常(含断点/观察点/单步/崩溃等)的投递,绑定到创建的 exc_port。mach_msg_server(exc_server, 0x800, exc_port, 0):用 XNU 自带的 exc_server MIG 处理例程在异常端口上跑服务。
回复或点赞可查看完整内容
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-288958.htm
[原创]浅入浅出Ios调试器与调试机制
60 浏览
8 回复
占楼
感谢分享
Thanks for sharing
感谢分享
tql
感谢分享
这个梳理可以666
学习一下