objdump
核心前置概念:BFD 库与 objdump 的底层逻辑
要深入理解 objdump,必须先明确它与 readelf 的核心差异:BFD (Binary File Descriptor) 库依赖。
-
readelf: 专为 ELF 格式设计,直接解析 ELF 文件头。即使 ELF 头部被恶意篡改(如去除了 Section Header 导致文件损坏,常见于逆向题目的反分析混淆),它往往也能强行解析 Program Headers。 -
objdump: 基于 BFD 库运行。这意味着它是一个通用型工具,不仅能处理 ELF,还能处理 Windows PE、Mac Mach-O 等各种架构和格式的二进制文件。但代价是,如果二进制文件的文件头被恶意破坏,BFD 库可能会解析失败,导致objdump拒绝工作。
常用参数速查表
| 短参数 | 长参数 | 核心作用 |
|---|---|---|
-d |
--disassemble |
反汇编所有包含指令的节(如 .text) |
-D |
--disassemble-all |
反汇编所有的节(无论是否为代码) |
-M |
--disassembler-options |
指定反汇编选项(如切换 Intel 语法) |
-S |
--source |
将源代码与反汇编代码交织显示(需带 -g 编译) |
-h |
--section-headers |
显示目标文件各个节的头部摘要信息 |
-s |
--full-contents |
以十六进制和 ASCII 形式转储所有非空节的内容 |
-t |
--syms |
显示静态符号表 |
-T |
--dynamic-syms |
显示动态符号表(常用于分析 .so 库) |
核心参数深度解析与实战场景
1. 反汇编双雄:-d vs -D
这是 objdump 最常用的功能:将机器码(Machine Code)翻译成人类可读的汇编代码(Assembly)。
-
-d(Disassemble):-
行为: 仅对标记为可执行(Executable)的节进行反汇编。通常只有
.text节。 -
应用: 常规的控制流分析、函数逻辑逆向。
-
-
-D(Disassemble All):-
行为: 强制将文件中的所有节(包括
.data、.bss甚至.rodata)当作机器指令进行反汇编。 -
应用: 当恶意代码或 Shellcode 被隐藏在数据段(非正常可执行段)中时,或者二进制文件被加壳(Packed)导致节属性混乱时,
-D是强制提取指令的唯一方式。对于数据段,它会翻译出大量无意义的垃圾指令,需要人工甄别。
-
2. 汇编风味切换:-M (Disassembler Options)
默认情况下,objdump 在 x86/amd64 架构下输出的是 AT&T 语法(寄存器带 %,立即数带 $,源操作数在前)。
-
切换为 Intel 语法:
objdump -d -M intel <binary> -
应用: 绝大多数反汇编引擎(如 IDA Pro, Ghidra)和底层开发都偏好 Intel 语法。强制使用
-M intel能大幅降低阅读汇编代码时的认知负担。
3. 源码与汇编映射:-S (Source)
将高级语言(如 C 语言)的源代码与底层的汇编指令混合显示。
-
前提条件: 二进制文件在编译时必须包含调试信息(例如使用了
gcc -g)。 -
应用: 非常适合在学习《汇编语言设计》或底层系统编程时,验证特定的 C 语言控制流(如
switch-case、for循环)或数据结构到底被编译器翻译成了什么样的机器码序列。
4. 节头部信息:-h (Section Headers)
虽然 readelf -S 也能看,但 objdump -h 提供了一种更紧凑的 BFD 视角的摘要。
-
核心关注 VMA 与 LMA:
-
VMA (Virtual Memory Address): 运行时的虚拟地址。
-
LMA (Load Memory Address): 加载时的物理地址(主要在嵌入式开发、裸机编程和编写 Bootloader 时极其重要;在普通的 Linux 用户态程序中,VMA 和 LMA 通常是一致的)。
-
5. 十六进制全量转储:-s (Full Contents)
转储文件的原始字节内容。
- 应用:
objdump -s -j .rodata <binary>(-j指定特定的节)。当你不只需要字符串(用strings)或简单的查看,而是需要精确提取某个偏移量处的硬编码密钥、魔法字节(Magic Bytes)或跳转表数据时,这是一个非常直观的命令。
6. 符号表解析:-t 与 -T
解析程序内部的符号引用。
-
应用:
-
找目标: 在编写 Exploit 时,如果二进制文件没有被 strip,可以通过
objdump -t快速找到隐藏的后门函数(如get_shell)的虚拟地址。 -
查库引用:
objdump -T专门看动态符号表,能迅速确认程序导入了哪些 libc 函数(如是否有system、execve供利用)。
-