PTrace
需要首先关闭 SIP 后再继续进行后面的任务.
使用如下命令可以大概看到当前系统中所有的系统调用:
sudo dtrace -ln 'syscall:::entry' | wc -l
DTrace 基于 ptrace
系统调用, 如果要查看实际 ptrace 函数的执行, 可以使用下面的命令, 当每次 ptrace 调用的时候, 都会打印信息:
sudo dtrace -qn 'syscall::ptrace:entry { printf("%s(%d, %d, %d, %d) from %s\n", probefunc, arg0, arg1, arg2, arg3, execname); }'
上面实际通过 DTrace 启动了一个针对 ptrace 的探针, 每次有 ptrace 调用的时候都会打印信息.
使用下面的 lldb 命令通过名字 attach 进程:
lldb -n Finder
当 attach 后, 可以看到打印了 ptrace 的调用信息. 而且可以发现是 debugserver
在调用 ptrace. debugserver 类似在 linux 上的 lldbserver, 在 lldb 的 C/S 结构中作为 server.
下面的命令可以打印 debugserver 的 PID:
pgrep debugserver
如果要看 debugserver 是如何启动的, 可以使用下面的命令:
ps -fp `pgrep -x debugserver`
上面的命令使用斜飘号 "`" 来使得后面的命令可以被执行. debugserver 在执行的时候也会有一个本地端口, 这样 lldb 就可以进行连接.
下面的命令打印 debugserver 的父进程 PID:
ps -o ppid= $(pgrep -x debugserver)
再使用 ps -a <pid>
即可找到父进程的具体信息.
当然通过 ptrace 的 man page 还可以发现一些周边的内容:
man ptrace -> man sigaction -> 什么是 core image(核心映像)? core image 是当前进程在内存中当前执行时的内存内容.
如果要进行远程 debug, 有如下方式:
- Remote debugging using Xcode (A)
- Remove debugging using lldb and debugserver (B)
- Remove debugging using lldb over SSH (C)
目前 A 是不支持的, B 的话费时费力, C 是最简单的办法.
要使 用 lldb over ssh, 首先要开启远程机器的 debug 策略, 并在弹窗中点击确认:
/usr/sbin/DevToolsSecurity --enable
远程 debug
待探索...
- 远程使用 debugserver 启动:
debugserver 0.0.0.0:12355 ./xxx.app
- 在本地的 lldb 启动后, 连接:
process connect connect://localhost:12355
参考: https://technoteshelp.com/macos-remote-debugging-using-lldb-xcode/