objdump高级功能实战指南:深入分析目标文件

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. 常用组合命令

  1. 反汇编+符号混合显示

    objdump -S example
    
  2. 详细符号表+地址排序

    objdump -t example | sort -k 2
    
  3. 十六进制查看指定节

    objdump -s -j .rodata example
    

1.5. 注意事项

  1. 调试信息依赖:使用-g编译选项是混合显示的前提
  2. 权限问题:分析系统库时可能需要sudo
  3. 架构差异:不同CPU架构需使用对应版本的objdump
  4. 内存对齐:注意节对齐属性对地址计算的影响

1.6. 总结

objdump作为逆向分析的核心工具,通过灵活组合选项可以实现:

  • 二进制代码审计
  • 符号解析与重定位分析
  • 调试信息挖掘
  • 依赖关系追踪
  • 不同架构的代码研究

建议配合readelfnmgdb等工具形成完整的二进制分析链。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值