Linux系统调用反汇编:如何查看strace追踪的ls调用的机器指令?
刚好做过类似的操作,给你几个实用的方法,分情况来看怎么查看系统调用对应的机器指令:
方法1:直接反汇编ls二进制文件,定位触发系统调用的指令
strace已经帮你找出了ls用到的系统调用(比如openat、read、write这些),接下来可以直接反汇编ls的二进制代码,找到触发这些系统调用的机器指令:
- 首先,x86_64架构下,用户态触发系统调用用的是
syscall指令,32位系统则是int 0x80。你可以用objdump直接搜索这些指令:
这个命令会列出所有包含objdump -d /bin/ls | grep -A5 -B5 'syscall'syscall指令的代码段,前后各5行上下文,方便你看完整调用逻辑。 - 如果要精准定位某个特定系统调用(比如
openat),先查它的系统调用号(x86_64下openat是257,对应十六进制0x101),然后搜索把这个值存入rax寄存器的代码:
这样就能直接找到触发objdump -d /bin/ls | grep -B2 -A2 'mov $0x101,%rax'openat系统调用的那段机器指令了。
方法2:用GDB结合strace,实时追踪并反汇编
如果想在ls运行过程中,精准捕捉到某个系统调用触发的瞬间,查看当时的指令,用GDB调试是最直观的:
- 启动GDB加载ls:
gdb /bin/ls - 设置断点:
- 如果你想拦截所有系统调用,可以直接给
syscall指令设断点:b syscall - 要是只关心特定系统调用(比如
openat),可以设置条件断点,当rax寄存器等于对应系统调用号时中断:b *$rip if $rax == 257
- 如果你想拦截所有系统调用,可以直接给
- 运行程序:
run - 程序触发目标系统调用时会自动中断,这时用反汇编命令查看当前位置附近的代码:
就能看到触发系统调用的具体机器指令了。disas $rip-10 $rip+5
方法3:用perf工具追踪系统调用并关联指令
perf工具也能帮你把系统调用和对应的用户态指令关联起来:
- 先记录ls运行时的目标系统调用事件(比如
syscalls:sys_enter_openat):perf record -e syscalls:sys_enter_openat /bin/ls - 查看记录的详细信息,里面会包含触发该系统调用的用户态指令指针(IP):
perf report -D - 拿到IP地址后,用
objdump定位对应的指令:objdump -d /bin/ls | grep <你的IP地址>
补充:查看内核态的系统调用实现指令
如果你的需求是看内核里处理该系统调用的机器指令,需要先获取内核的调试符号:
- 先找到系统调用对应的内核处理函数(比如x86_64下
openat对应的是__x64_sys_openat,不同内核版本可能有差异)。 - 用
objdump反汇编内核镜像:
就能看到内核里处理这个系统调用的完整机器指令了。objdump -d /usr/lib/debug/boot/vmlinux-$(uname -r) | grep -A20 '__x64_sys_openat'
内容的提问来源于stack exchange,提问作者Tuomas Toivonen
相关产品推荐
相关产品推荐

