在 Linux 下“看反汇编里的函数调用”,核心就是 找 call 指令 + 看参数怎么传 + 对照符号/地址。下面按常用场景给你一个实用指南。
objdump -d ./a.out > disasm.txt
或针对某个函数:
objdump -d -M intel ./a.out | grep -A 30 "<main>:"
推荐加:
-M intel:Intel 语法(比 AT&T 好读)-S:源码+汇编对照(需要 -g 编译)call 0x401234
call printf@plt
call <foo>
含义:
call <函数名> → 有符号,直接知道调谁call 0x401234 → 无符号,需要查地址call *%rax → 函数指针 / 虚函数(间接调用)objdump -d ./a.out | grep "401234:"
nm ./a.out | grep 401234
或:
addr2line -e ./a.out 0x401234
前 6 个参数:
rdi, rsi, rdx, rcx, r8, r9
第 7 个起:栈
示例:
mov edi, 5
call foo
→ foo(5)
mov rdi, rax
mov rsi, rbx
call memcpy
→ memcpy(dest, src)
push rbp
mov rbp, rsp
sub rsp, 0x10
说明:
rbp-xxx参数位置:
rbp+0x10 → 第 1 个参数
rbp+0x18 → 第 2 个参数
push 0x10
push rax
call func
add rsp, 0x10
→ func(rax, 0x10)
gdb ./a.out
break main
run
stepi
看调用:
x/5i $pc
info registers
单步进函数:
si
bt
无符号时:
bt full
info frame
file ./a.out
nm ./a.out # 有符号?
readelf -s ./a.out
strip 过的:
ltrace / straceltrace ./a.out
strace -f ./a.out
call write@plt → libcsyscall → 直接系统调用✅ 看调用顺序:
call 在哪✅ 看谁调用我:
btobjdump 搜 call <我>✅ 看虚函数:
call *(%rax)如果你愿意,可以:
我可以直接帮你“逐行解释调用关系”。