解读 Linux 下的反汇编结果,本质是把机器指令 ↔ 汇编语言 ↔ 程序语义三者对应起来。下面从工具 → 结构 → 常见指令 → 实战示例 → 技巧逐步说明。
objdump(最常用)objdump -d ./a.out
常用选项:
-d:反汇编可执行代码-S:混排源码和汇编(需 -g 编译)-M intel:使用 Intel 语法(默认 AT&T)objdump -d -M intel ./a.out
gdbdisassemble main
或:
disas /m main # 带源码
objdump vs gdbobjdump:静态分析gdb:运行时动态查看0000000000401146 <main>:
401146: 55 push rbp
401147: 48 89 e5 mov rbp, rsp
40114a: 48 83 ec 10 sub rsp, 0x10
40114e: c7 45 fc 0a 00 00 00 mov DWORD PTR [rbp-0x4], 0xa
401155: b8 00 00 00 00 mov eax, 0x0
40115a: c9 leave
40115b: c3 ret
| 部分 | 含义 |
|---|---|
401146 |
指令地址 |
55 |
机器码 |
push rbp |
汇编指令 |
main |
函数名 |
push rbp
mov rbp, rsp
sub rsp, N
作用:
leave
ret
等价于:
mov rsp, rbp
pop rbp
ret
| 寄存器 | 用途 |
|---|---|
rsp |
栈指针 |
rbp |
栈帧基址 |
rax |
返回值 |
rdi, rsi, rdx, rcx, r8, r9 |
函数参数 |
rip |
指令指针 |
mov eax, 0x1
eax = 1
mov [rbp-4], eax
把 eax 存到栈上局部变量
add eax, ebx ; eax += ebx
sub eax, 1 ; eax -= 1
imul eax, 2 ; eax *= 2
cmp eax, ebx
je label ; if eax == ebx
jne label ; if eax != ebx
jg label ; if eax > ebx
jl label ; if eax < ebx
call func
funcint add(int a, int b) {
return a + b;
}
add:
push rbp
mov rbp, rsp
mov eax, edi
add eax, esi
pop rbp
ret
edi → aesi → beax = a + beax 作为返回值gcc -g -O0 main.c
objdump -S -M intel a.out
-O0:清晰但啰嗦-O2:紧凑难读如果你有具体一段反汇编代码或某个程序(如 Linux 命令、漏洞样本),可以直接贴出来,我可以逐行帮你解读。