Skip to main content

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

待探索...

  1. 远程使用 debugserver 启动: debugserver 0.0.0.0:12355 ./xxx.app
  2. 在本地的 lldb 启动后, 连接: process connect connect://localhost:12355

参考: https://technoteshelp.com/macos-remote-debugging-using-lldb-xcode/