1. objdump
高级功能实战指南:深入分析目标文件
1.1. 简介
- objdump 是一个功能强大的反汇编和目标文件分析工具,通常在类 Unix 系统(如 Linux、macOS)上使用,它属于 GNU Binutils 工具集的一部分。
- 基本语法:
objdump [选项] [文件]
- 选项 用于指定不同的操作
- 文件 是要分析的目标文件,通常是可执行文件、目标文件或共享库
1.2. 实验准备
1.2.1. 示例代码
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(3, 4);
printf("The result is: %d\n", result);
return 0;
}
1.2.2. 编译命令
gcc -g -c example.c -o example.o # 生成目标文件
gcc -g example.o -o example # 生成可执行文件
- -g 选项用于在编译时生成调试信息,方便后续使用 objdump 混合显示源代码和反汇编代码。
- -c 选项表示只进行编译,不进行链接,生成目标文件
1.3. 命令举例说明
1.3.1. 文件格式检查(-f
)
objdump -f example
关键信息:
architecture: i386:x86-64
flags: EXEC_P, HAS_SYMS, D_PAGED
start address: 0x0000000000400490
architecture
:目标架构EXEC_P
:可执行文件标记D_PAGED
:支持分页内存
1.3.2. 依赖关系分析(-x + grep
)
objdump -x example | grep NEEDED
输出结果:
NEEDED libc.so.6
- 显示依赖的共享库,libc.so.6
- 配合
ldd
命令可进一步验证
1.3.3. 显示文件头信息(-h
)
objdump -h example.o
输出结果:
example.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000023 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000063 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000063 2**0
ALLOC
3 .rodata 00000013 0000000000000000 0000000000000000 00000063 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment 0000002d 0000000000000000 0000000000000000 00000076 2**0
CONTENTS, READONLY
5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000a3 2**0
CONTENTS, READONLY
6 .eh_frame 00000038 0000000000000000 0000000000000000 000000a8 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
- 从输出中可以看到每个节的名称、大小、虚拟地址(VMA)、加载地址(LMA)等信息。
1.3.4. 混合显示源代码和反汇编代码(-S
)
objdump -S example.o
由于编译时使用了 -g 选项保留了调试信息,执行该命令会将源代码和反汇编代码混合显示,示例输出如下::
example: file format elf64-x86-64
Disassembly of section .text:
0000000000400526 <add>:
int add(int a, int b) {
400526: 55 push %rbp
400527: 48 89 e5 mov %rsp,%rbp
40052a: 89 7d fc mov %edi,-0x4(%rbp)
40052d: 89 75 f8 mov %esi,-0x8(%rbp)
return a + b;
400530: 8b 55 fc mov -0x4(%rbp),%edx
400533: 8b 45 f8 mov -0x8(%rbp),%eax
400536: 01 d0 add %edx,%eax
}
400538: 5d pop %rbp
400539: c3 retq
000000000040053a <main>:
int main() {
40053a: 55 push %rbp
40053b: 48 89 e5 mov %rsp,%rbp
40053e: 48 83 ec 10 sub $0x10,%rsp
int result = add(3, 4);
400542: be 04 00 00 00 mov $0x4,%esi
400547: bf 03 00 00 00 mov $0x3,%edi
40054c: e8 d5 ff ff ff callq 400526 <add>
400551: 89 45 fc mov %eax,-0x4(%rbp)
printf("The result is: %d\n", result);
400554: 8b 45 fc mov -0x4(%rbp),%eax
400557: 89 c6 mov %eax,%esi
400559: bf 54 06 40 00 mov $0x400654,%edi
40055e: b8 00 00 00 00 mov $0x0,%eax
400563: e8 d8 fe ff ff callq 400440 <printf@plt>
return 0;
400568: b8 00 00 00 00 mov $0x0,%eax
}
40056d: c9 leaveq
40056e: c3 retq
- 通过这种方式,可以更直观地看到源代码和汇编代码之间的对应关系。
1.3.5. 动态符号表分析(-T
)
objdump -T example
输出解析:
DYNAMIC SYMBOL TABLE:
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf
DF
:动态符号标记*UND*
:未定义符号GLIBC_2.2.5
:符号依赖的库版本
1.3.6. 动态重定位记录(-R
)
objdump -R example
输出解析:
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
000000201000 R_X86_64_GLOB_DAT _GLOBAL_OFFSET_TABLE_
000000201018 R_X86_64_JUMP_SLOT printf@GLIBC_2.2.5
R_X86_64_JUMP_SLOT
:跳表重定位类型_GLOBAL_OFFSET_TABLE_
:全局偏移表地址
1.3.7. 调试信息查看(-g
)
objdump -g example.o
关键输出片段:
<1><33>: Abbrev Number: 2 (DW_TAG_subprogram)
<34> DW_AT_external : 1
<34> DW_AT_name : add
<38> DW_AT_decl_file : 1
<39> DW_AT_decl_line : 3
DW_TAG_subprogram
:子过程标签decl_line
:函数声明行号
1.3.8. 节内容详细查看(-G
)
objdump -G example.o
.text
节输出示例:
Contents of section .text:
0000 554889e5 897dfc89 75f88b55 fc8b45f8 UH...}.u..U..E.
0010 01d05dc3 554889e5 4883ec10 be040000 ..].UH..H.......
- 左侧为十六进制字节码
- 右侧为ASCII字符表示
1.3.9. 反汇编格式控制(-M intel
)
objdump -d -M intel example
Intel语法示例:
0000000000400526 <add>:
400526: 55 push rbp
400527: 48 89 e5 mov rbp, rsp
- 与默认的AT&T语法形成对比
- 更符合x86汇编常见写法
1.3.10. 其他命令
-l:显示行号信息,当有调试符号时,可以关联源代码行号。
-C:将低级符号名解码为用户级名称,比如 C++ 的名称修饰。
-j:指定要显示的节,比如 - j .text。
-w:不换行显示反汇编代码,适合脚本处理。
-z:忽略非打印字符,在显示节内容时更友好。
–adjust-vma:调整虚拟内存地址,适用于内存映射分析。
–section-alignment:显示节对齐信息。
–relocatable-check:检查重定位信息是否正确。
–all-headers:显示所有头信息,包括符号表、节头等。
–start-address 和 --stop-address:指定反汇编的地址范围。
1.4. 常用组合命令
-
反汇编+符号混合显示
objdump -S example
-
详细符号表+地址排序
objdump -t example | sort -k 2
-
十六进制查看指定节
objdump -s -j .rodata example
1.5. 注意事项
- 调试信息依赖:使用
-g
编译选项是混合显示的前提 - 权限问题:分析系统库时可能需要
sudo
- 架构差异:不同CPU架构需使用对应版本的
objdump
- 内存对齐:注意节对齐属性对地址计算的影响
1.6. 总结
objdump
作为逆向分析的核心工具,通过灵活组合选项可以实现:
- 二进制代码审计
- 符号解析与重定位分析
- 调试信息挖掘
- 依赖关系追踪
- 不同架构的代码研究
建议配合readelf
、nm
、gdb
等工具形成完整的二进制分析链。