在 Linux 下进行反汇编并分析函数调用关系,可以从“静态反汇编”和“动态调试”两个角度入手。下面用通俗方式说明常见做法和要看什么。
objdump:最基础gdb + disassembleIDA(最强,图形化)Ghidra(免费、强大)radare2 / rizinobjdump -d ./a.out > disasm.txt
看调用主要找:
call 指令(x86)bl 指令(ARM)示例(x86-64):
call 400526 <func_a>
call 400540 <printf@plt>
说明:
func_a:本地函数printf@plt:PLT 调用(动态库函数)参数顺序:
rdi, rsi, rdx, rcx, r8, r9, 栈
例如:
mov edi, 1
call func
说明 func(1)
bl func
参数通常在:
r0, r1, r2, r3
函数通常以:
push rbp
mov rbp, rsp
开始(栈帧)
结束:
pop rbp
ret
这帮你确认“这是一个函数”。
gdb ./a.out
(gdb) break main
(gdb) run
(gdb) disassemble
(gdb) stepi
看:
call 执行前后rip / pc 变化(gdb) break *0x400526
或直接:
(gdb) catch syscall
(gdb) backtrace
能看到:
#0 func_a
#1 main
这是“谁调用了谁”。
提取所有 call:
objdump -d ./a.out | grep call
nm 看符号:nm ./a.out
printf@plt → 动态没有 call
直接展开在调用处
jmp func
不是 call,但语义是调用
看调用 = 找 call/bl → 看目标地址 → 看参数寄存器 → 用 gdb 验证栈
如果你愿意,可以:
我可以直接帮你逐行分析。