objdump命令解析

一、名称
    objdump-显示目标文件的工具
    
二、简介

       objdump [-a|--archive-headers]
               [-b bfdname|--target=bfdname]
               [-C|--demangle[=style] ]
               [-d|--disassemble[=symbol]]
               [-D|--disassemble-all]
               [-z|--disassemble-zeroes]               
               [-f|--file-headers]
               [-F|--file-offsets]               
               [-g|--debugging]
               [-e|--debugging-tags]
               [-h|--section-headers|--headers]
               [-i|--info]
               [-j section|--section=section]
               [-l|--line-numbers]
               [-S|--source]               
               [-r|--reloc]
               [-R|--dynamic-reloc]
               [-s|--full-contents]               
               [-t|--syms]
               [-T|--dynamic-syms]
               [-x|--all-headers]
               [-w|--wide]               
               [-V|--version]
               [-H|--help]
               objfile...
三、说明
  objdump可以显示一个或多个目标文件的信息。选项决定显示的具体信息。这些信息对于编译工具程序员以及希望程序编译和执行的程序员都特别有用。
  objfile...是需要显示的目标文件。当你指定存档文件时,objdump显示每个成员对象文件的信息。

四、选项
    这里显示的选项的长格式和短格式都是可以的,他们是等效的。以下选项中至少一项需要给出:-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-P,-r,-R,-s,-S,-t,-T,-V,-x。

    -a
    --archive-header
    如果objfile里任一个文件是归档文件,命令将显示归档文件的头信息(和ls -l方式一样)。除了ar tv列出的信息,objdump -a还显示归档文件中所有目标文件的格式。

    示例:
    add.h

    int Add(int a, int b);

    add.cpp

    #include "add.h"
    int Add(int a, int b){
        return a+b;
    }

    sub.h

    int Sub(int a, int b);

    sub.cpp

    #include "sub.h"
    int Sub(int a, int b){
        return a-b;
    }

    生成add.o
    g++ -c add.cpp -o add.o
    生成sub.o
    g++ -c sub.cpp -o sub.o

    合成静态库
    ar rcs libalg.a ./*.o

    输出结果:
    显示add.o
    $ objdump -a add.o
      add.o:     file format elf64-x86-64
      add.o

    显示libalg.a
    $ objdump -a libalg.a
    In archive libalg.a:

    add.o:     file format elf64-x86-64
    rw-r--r-- 0/0   1240 Jan  1 08:00 1970 add.o

    sub.o:     file format elf64-x86-64
    rw-r--r-- 0/0   1240 Jan  1 08:00 1970 sub.o

    对比ls -l结果:
    ls -l ./
    total 28
    -rw-rw-r-- 1 u3s u3s   57  4月 14 11:22 add.cpp
    -rw-rw-r-- 1 u3s u3s   25  4月 14 11:02 add.h
    -rw-rw-r-- 1 u3s u3s 1240  4月 14 11:31 add.o
    -rw-rw-r-- 1 u3s u3s 2698  4月 14 11:32 libalg.a
    -rw-rw-r-- 1 u3s u3s   57  4月 14 11:25 sub.cpp
    -rw-rw-r-- 1 u3s u3s   25  4月 14 11:17 sub.h
    -rw-rw-r-- 1 u3s u3s 1240  4月 14 11:31 sub.o

    objdump -a 比ls -l 多了file format信息,也就是文件是32位还是64位,上面显示64位。

    -C
    --demangle[=style]
    去掉名字修饰,显示为用户可读信息

    以上面生成的add.o为例
    $ objdump -t add.o

    add.o:     file format elf64-x86-64

    SYMBOL TABLE:
    0000000000000000 l    df *ABS*    0000000000000000 add.cpp
    0000000000000000 l    d  .text    0000000000000000 .text
    0000000000000000 g     F .text    0000000000000018 _Z3Addii

    _Z3Addii是函数Add修饰后的名称。

    加上-C选项后
    $ objdump -Ct add.o

    add.o:     file format elf64-x86-64

    SYMBOL TABLE:
    0000000000000000 l    df *ABS*    0000000000000000 add.cpp
    0000000000000000 l    d  .text    0000000000000000 .text
    0000000000000000 g     F .text    0000000000000018 Add(int, int)

    函数Add名称显示为可读的

    -d
    --disassemble
    --disassemble=symbol    
    反汇编,只显示包含指令的部分

    $ objdump -d add.o

    add.o:     file format elf64-x86-64


    Disassembly of section .text:

    0000000000000000 <_Z3Addii>:
       0:    f3 0f 1e fa              endbr64 
       4:    55                       push   %rbp
       5:    48 89 e5                 mov    %rsp,%rbp
       8:    89 7d fc                 mov    %edi,-0x4(%rbp)
       b:    89 75 f8                 mov    %esi,-0x8(%rbp)
       e:    8b 55 fc                 mov    -0x4(%rbp),%edx
      11:    8b 45 f8                 mov    -0x8(%rbp),%eax
      14:    01 d0                    add    %edx,%eax
      16:    5d                       pop    %rbp
      17:    c3                       ret 

    上面的内容就是函数Add的汇编代码

  -D
  --disassemble-all
  和-d选项类似,不仅包括指令部分,还包括所有非bss部分。-j可以指定段。

  --no-addresses
  反汇编时,不打印每行的地址以及符号、重定位的偏移。

  -f
  --file-headers
  显示每个 objfile 文件的整体头部摘要信息

  示例:
  $objdump -f a.out 
  输出:
  a.out:     file format elf64-x86-64
  architecture: i386:x86-64, flags 0x00000150:
  HAS_SYMS, DYNAMIC, D_PAGED
  start address 0x0000000000001040
 
  -h
  --section-headers
  --headers
  显示目标文件节头部摘要信息

  -H
  --help
  显示帮助信息

  -j name
  --section=name
  显示节name的信息,该选项可以出现多次

  -l
  --line-numbers
  显示代码行号,只能和-d, -D, 或者 -r 一起使用

  -S
  --source
  汇编和源代码交叉显示

  示例:
  $ objdump -S a.out
  输出:
  0000000000001141 <main>:

  int main(){
      1141: f3 0f 1e fa           endbr64 
      1145: 55                    push   %rbp
      1146: 48 89 e5              mov    %rsp,%rbp
      1149: 48 83 ec 10           sub    $0x10,%rsp
  int a = 10, b = 11;
      114d: c7 45 f4 0a 00 00 00  movl   $0xa,-0xc(%rbp)
      1154: c7 45 f8 0b 00 00 00  movl   $0xb,-0x8(%rbp)
  int sum = Add(a, b);
      115b: 8b 55 f8              mov    -0x8(%rbp),%edx
      115e: 8b 45 f4              mov    -0xc(%rbp),%eax
      1161: 89 d6                 mov    %edx,%esi
      1163: 89 c7                 mov    %eax,%edi
      1165: e8 bf ff ff ff        call   1129 <_Z3Addii>
      116a: 89 45 fc              mov    %eax,-0x4(%rbp)

  return 0;
      116d: b8 00 00 00 00        mov    $0x0,%eax
  }
      1172: c9                    leave  
      1173: c3                    ret 

  -t
  --syms
  打印文件的符号表。这类似于 nm 程序提供的信息,尽管显示格式有所不同。
  
  -T
  --dynamic-syms
  打印文件的动态符号表

  学习过程中发现-t 是包含-T结果的

  关于符号的详细内容,参见https://blog.youkuaiyun.com/SimpleForest/article/details/138373339?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22138373339%22%2C%22source%22%3A%22SimpleForest%22%7D

  本文测试代码:https://download.youkuaiyun.com/download/SimpleForest/89251966

  

<think>嗯,用户想知道如何使用objdump进行反汇编以及解析生成的代码。首先,我需要回忆一下objdump的常用命令和参数。根据引用中的信息,用户可能需要基本的反汇编步骤,比如如何指定文件、如何查看特定函数等。 首先,我应该列出常用的objdump命令,比如-d用于反汇编,-S混合源代码和汇编可能需要调试信息。然后,可能需要提到如何查看特定函数的汇编代码,使用--disassemble=选项,这在引用1里提到过。用户可能还想知道如何解析输出,比如地址、操作码、指令和操作数这些部分。 另外,引用3提到在Windows下使用objdump的步骤,可能需要说明不同系统下的用法差异。比如在Windows中,可能需要指定编译器路径和输出文件。而Linux下则更直接,如objdump -d file.o。 用户可能还需要了解如何分析输出,比如如何识别函数入口、跳转目标等。引用4提到objdump对系统程序员的重要性,可以建议用户结合nm工具查看符号表,或者使用gdb进行动态分析。 还需要注意常见问题,比如反汇编整个二进制文件或动态链接库时的注意事项,可能需要使用-M参数指定架构,或者处理位置无关代码。此外,优化后的代码可能难以对应源代码,这时候混合显示-S会有帮助,但需要编译时加上-g选项。 最后,生成相关问题时要围绕objdump的进阶使用、解析技巧、工具结合以及实际应用场景,确保覆盖用户可能感兴趣的扩展内容。</think>### 使用 objdump 进行反汇编及解析代码的步骤 #### **1. 基本反汇编命令** 使用 `objdump -d` 对目标文件或可执行文件进行反汇编: ```bash objdump -d <目标文件> # Linux/MacOS x86_64-sylixos-elf-objdump -d <目标文件> > output.dis # Windows示例[^3] ``` 此命令会输出所有可执行段的汇编代码,格式包含**指令地址、机器码、汇编指令**,例如: ``` 0000000000001149 <main>: 1149: 55 push %rbp 114a: 48 89 e5 mov %rsp,%rbp ``` #### **2. 反汇编特定函数** 通过 `--disassemble=<函数名>` 指定函数: ```bash objdump --disassemble=my_function <目标文件> # 仅输出my_function的汇编代码[^1] ``` #### **3. 混合源代码与汇编** 添加 `-S` 参数可**穿插显示源代码与汇编代码**(需编译时包含调试信息 `-g`): ```bash objdump -S <目标文件> ``` 输出示例: ```asm int main() { 1149: 55 push %rbp int x = 10; 114a: 48 89 e5 mov %rsp,%rbp 114d: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp) ``` #### **4. 解析关键信息** - **指令地址**:左侧十六进制值(如 `1149`)表示指令在内存中的位置。 - **机器码**:中间列(如 `55`)是二进制指令的十六进制表示。 - **跳转目标**:如 `callq 1130 <func>` 表示调用地址 `0x1130` 处的函数 `func`。 - **符号表关联**:结合 `nm <目标文件>` 查看符号地址[^4],辅助理解函数/变量位置。 #### **5. 跨平台反汇编** 若目标文件为其他架构(如ARM),需指定**架构类型**: ```bash objdump -b binary -m arm -D <二进制文件> # 反汇编ARM指令[^2] ``` #### **6. 输出控制** - `-M intel` 切换为Intel汇编语法(默认AT&T语法) - `-j .text` 仅反汇编.text段(代码段) - `-l` 显示源代码文件名(需调试信息) --- ### 常见问题解析场景 1. **分析函数调用关系** 通过 `call` 指令定位函数跳转目标,结合符号表确认函数名。 2. **验证编译器优化** 对比有无 `-O2` 编译选项的汇编代码,观察指令简化(如循环展开)。 3. **调试崩溃地址** 若程序崩溃地址为 `0x4005a1`,在反汇编结果中搜索该地址,定位崩溃指令。 --- ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值