Mac OS X查看应用系统调用:dtruss无输出及非关闭SIP替代方案
macOS下dtruss无法捕获系统调用的问题及替代方案
问题描述
编译了一段直接使用svc指令发起系统调用的汇编程序,执行sudo dtruss ./a.out跟踪时,仅输出SIP提示和程序运行结果,看不到预期的write或exit系统调用记录。同时希望找到无需关闭SIP(系统完整性保护)的温和解决方案。
环境与现象
编译命令:clang hello.s
跟踪命令输出:
dtrace: system integrity protection is on, some features will not be available
SYSCALL(args) = return
Hello
汇编代码:
.global _main .align 2 _main: mov X0, #1 adr X1, hello mov X2, #13 mov X16, #4 svc 0 mov X0, #0 mov X16, #1 svc 0 hello: .ascii "Hello\n"
原因分析
- SIP的限制:macOS的系统完整性保护会限制dtrace(dtruss基于dtrace)的底层跟踪能力,无法捕获直接通过
svc指令发起的原始系统调用,仅能跟踪经过libc封装的系统调用。 - 系统调用方式差异:编写的汇编程序直接使用系统调用号+
svc指令触发调用,没有经过libc封装,而dtruss在SIP启用状态下对这类调用的支持受限。
解决方案
无需关闭SIP的温和方案
1. 给二进制添加调试权限
通过代码签名给程序添加允许调试的权限,让dtrace可以正常跟踪:
# 生成临时权限配置并完成签名 echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.get-task-allow</key> <true/> </dict> </plist>' | codesign -s - -f --entitlements - ./a.out
签名完成后再执行sudo dtruss ./a.out,即可看到完整的系统调用记录。
2. 使用LLDB跟踪系统调用
LLDB不受SIP的此类限制,可以直接跟踪所有系统调用:
# 启动LLDB调试目标程序 lldb ./a.out # 开启系统调用全跟踪 (lldb) process trace start -s all # 运行程序 (lldb) run
程序运行后会输出所有触发的系统调用,包括代码中的write和exit。
关闭SIP的方案(仅临时使用)
如果必须使用dtruss且上述方案无效,可以临时关闭SIP:
- 重启Mac,按住
Command+R进入恢复模式 - 打开终端,执行
csrutil disable - 重启系统后,即可正常使用dtruss跟踪所有系统调用
- 使用完成后,重复步骤1-2,执行
csrutil enable重新开启SIP
内容的提问来源于stack exchange,提问作者Stan
相关产品推荐
相关产品推荐

