【Linux】一步一步学Linux——objdump命令(254)

00. 目录

01. 命令概述

objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具。

objdump有点像快速查看之类的工具,就是以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。

02. 命令格式

用法:objdump <选项> <文件>

03. 常用选项


-l
--line-numbers 
用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 

-m machine 
--architecture=machine 
指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构. 

--reloc 
-r 
显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。 

--dynamic-reloc 
-R 
显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。 

-s 
--full-contents 
显示指定section的完整内容。默认所有的非空section都会被显示。 

-S 
--source 
尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。 

--show-raw-insn 
反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。 

--no-show-raw-insn 
反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。 

--start-address=address 
从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。 

--stop-address=address 
显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。 

-t 
--syms 
显示文件的符号表入口。类似于nm -s提供的信息 

-T 
--dynamic-syms 
显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。 

-V 
--version 
版本信息 

--all-headers 
-x 
显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。 

-z 
--disassemble-zeroes 
一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。 

@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。

04. 参考示例

4.1 查看当前使用的objdump的版本号

[deng@localhost 5share_lib]$ objdump -V
GNU objdump version 2.27-27.base.el7
Copyright (C) 2016 Free Software Foundation, Inc.
这个程序是自由软件;您可以遵循 GNU 通用公共授权版本 3 或
(您自行选择的) 稍后版本再发布它。
这个程序不含任何担保。
[deng@localhost 5share_lib]$ 

4.2 查看档案库文件中的信息

[deng@localhost 3static_lib]$ objdump -a libtest.a 
在归档文件 libtest.a 中:

add.o:     文件格式 elf64-x86-64
rw-r--r-- 0/0   1232 Jan  1 08:00 1970 add.o


sub.o:     文件格式 elf64-x86-64
rw-r--r-- 0/0   1224 Jan  1 08:00 1970 sub.o


mul.o:     文件格式 elf64-x86-64
rw-r--r-- 0/0   1224 Jan  1 08:00 1970 mul.o

[deng@localhost 3static_lib]$ 
[deng@localhost 3static_lib]$ ar -tv libtest.a 
rw-r--r-- 0/0   1232 Jan  1 08:00 1970 add.o
rw-r--r-- 0/0   1224 Jan  1 08:00 1970 sub.o
rw-r--r-- 0/0   1224 Jan  1 08:00 1970 mul.o
[deng@localhost 3static_lib]$ 

4.3 显示可用的架构和目标结构列表

[deng@localhost 3static_lib]$ objdump -i
BFD 头文件版本 version 2.27-27.base.el7
elf64-x86-64
 (header 小端序, data 小端序)
  i386
elf32-i386
 (header 小端序, data 小端序)
  i386
elf32-iamcu
 (header 小端序, data 小端序)
  iamcu
elf32-x86-64
 (header 小端序, data 小端序)
  i386
a.out-i386-linux
 (header 小端序, data 小端序)
  i386
pei-i386
 (header 小端序, data 小端序)
  i386
pei-x86-64
 (header 小端序, data 小端序)
  i386
elf64-l1om
 (header 小端序, data 小端序)
  l1om
elf64-k1om
 (header 小端序, data 小端序)
  k1om
elf64-little
 (header 小端序, data 小端序)
  i386
  l1om
  k1om
  iamcu
  plugin
elf64-big
 (header 大端序, data 大端序)
  i386
  l1om
  k1om
  iamcu
  plugin
elf32-little
 (header 小端序, data 小端序)
  i386
  l1om
  k1om
  iamcu
  plugin
elf32-big
 (header 大端序, data 大端序)
  i386
  l1om
  k1om
  iamcu
  plugin
plugin
 (header 小端序, data 小端序)
srec
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin
symbolsrec
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin
verilog
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin
tekhex
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin
binary
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin
ihex
 (header 未知的端序, data 未知的端序)
  i386
  l1om
  k1om
  iamcu
  plugin

               elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 
          i386 elf64-x86-64 elf32-i386 ----------- elf32-x86-64 
          l1om ------------ ---------- ----------- ------------ 
          k1om ------------ ---------- ----------- ------------ 
         iamcu ------------ ---------- elf32-iamcu ------------ 
        plugin ------------ ---------- ----------- ------------ 

               a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om 
          i386 a.out-i386-linux pei-i386 pei-x86-64 ---------- ---------- 
          l1om ---------------- -------- ---------- elf64-l1om ---------- 
          k1om ---------------- -------- ---------- ---------- elf64-k1om 
         iamcu ---------------- -------- ---------- ---------- ---------- 
        plugin ---------------- -------- ---------- ---------- ---------- 

               elf64-little elf64-big elf32-little elf32-big plugin srec 
          i386 elf64-little elf64-big elf32-little elf32-big ------ srec 
          l1om elf64-little elf64-big elf32-little elf32-big ------ srec 
          k1om elf64-little elf64-big elf32-little elf32-big ------ srec 
         iamcu elf64-little elf64-big elf32-little elf32-big ------ srec 
        plugin elf64-little elf64-big elf32-little elf32-big ------ srec 

               symbolsrec verilog tekhex binary ihex 
          i386 symbolsrec verilog tekhex binary ihex 
          l1om symbolsrec verilog tekhex binary ihex 
          k1om symbolsrec verilog tekhex binary ihex 
         iamcu symbolsrec verilog tekhex binary ihex 
        plugin symbolsrec verilog tekhex binary ihex 
[deng@localhost 3static_lib]$ 

这里,显示的信息是相对于 -b 或者 -m 选项可用的架构和目标格式列表。

4.4 示test.o文件中的text段的内容

[deng@localhost 1gcc]$ objdump --section=.text -s test.o

test.o:     文件格式 elf64-x86-64

Contents of section .text:
 0000 554889e5 bf000000 00e80000 0000b800  UH..............
 0010 0000005d c3                          ...].           
[deng@localhost 1gcc]$ 

这里注意,不能单独使用-j或者–section,例如objdump --section=.text mytest.o是不会运行成功的。

4.5 反汇编test.o中的text段内容,并尽可能用源代码形式表示

[deng@localhost 1gcc]$ objdump -j .text -S test.o

test.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   
[deng@localhost 1gcc]$ 

这里注意,不能单独使用-j或者–section,例如objdump -j .text test.o是不会运行成功的。另外-S命令对于包含调试信息的目标文件,显示的效果比较好,如果编译时没有指定g++的-g选项,那么目标文件就不包含调试信息,那么显示效果就差多了。

4.6 反汇编出test.o的源代码

[deng@localhost 1gcc]$ objdump -S test.o

test.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   
[deng@localhost 1gcc]$ 

尤其当编译的时候指定了-g这种调试参数时,反汇编的效果比较明显。隐含了-d参数。

4.7 显示文件的符号表入口

[deng@localhost 1gcc]$ objdump -t test.o

test.o:     文件格式 elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata        0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 g     F .text  0000000000000015 main
0000000000000000         *UND*  0000000000000000 puts


[deng@localhost 1gcc]$ 

输出的信息类似nm -s命令的输出,相比较之下,nm命令的输出如下:

[deng@localhost 1gcc]$ nm -s test.o
0000000000000000 T main
                 U puts
[deng@localhost 1gcc]$ 

4.8 显示文件的符号表入口,将底层符号解码并表示成用户级别

[deng@localhost 1gcc]$ objdump -t -C test.o

test.o:     文件格式 elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata        0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 g     F .text  0000000000000015 main
0000000000000000         *UND*  0000000000000000 puts


[deng@localhost 1gcc]$ 

4.9 反汇编目标文件

[deng@localhost 1gcc]$ objdump -d test.o

test.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   
[deng@localhost 1gcc]$ 

对text段的内容进行了反汇编。

4.10 反汇编特定段,并将汇编代码对应的文件名称和行号对应上

[deng@localhost 1gcc]$ objdump -d -l test.o

test.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
main():
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   
[deng@localhost 1gcc]$ 

这里,项"-d"从objfile中反汇编那些特定指令机器码的section,而使用"-l"指定用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。

4.11 显示目标文件各个段的头部摘要信息

[deng@localhost 1gcc]$ objdump -h test.o 

test.o:     文件格式 elf64-x86-64

节:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000015  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  00000055  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000055  2**0
                  ALLOC
  3 .rodata       0000000d  0000000000000000  0000000000000000  00000055  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002e  0000000000000000  0000000000000000  00000062  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  00000090  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000038  0000000000000000  0000000000000000  00000090  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
[deng@localhost 1gcc]$ 

4.12 反汇编所有

[deng@localhost 1gcc]$ objdump -D test.o 

test.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   

Disassembly of section .rodata:

0000000000000000 <.rodata>:
   0:   68 65 6c 6c 6f          pushq  $0x6f6c6c65
   5:   20 69 74                and    %ch,0x74(%rcx)
   8:   63 61 73                movslq 0x73(%rcx),%esp
   b:   74 00                   je     d <main+0xd>

Disassembly of section .comment:

0000000000000000 <.comment>:
   0:   00 47 43                add    %al,0x43(%rdi)
   3:   43 3a 20                rex.XB cmp (%r8),%spl
   6:   28 47 4e                sub    %al,0x4e(%rdi)
   9:   55                      push   %rbp
   a:   29 20                   sub    %esp,(%rax)
   c:   34 2e                   xor    $0x2e,%al
   e:   38 2e                   cmp    %ch,(%rsi)
  10:   35 20 32 30 31          xor    $0x31303220,%eax
  15:   35 30 36 32 33          xor    $0x33323630,%eax
  1a:   20 28                   and    %ch,(%rax)
  1c:   52                      push   %rdx
  1d:   65 64 20 48 61          gs and %cl,%fs:0x61(%rax)
  22:   74 20                   je     44 <main+0x44>
  24:   34 2e                   xor    $0x2e,%al
  26:   38 2e                   cmp    %ch,(%rsi)
  28:   35 2d 32 38 29          xor    $0x2938322d,%eax
        ...

Disassembly of section .eh_frame:

0000000000000000 <.eh_frame>:
   0:   14 00                   adc    $0x0,%al
   2:   00 00                   add    %al,(%rax)
   4:   00 00                   add    %al,(%rax)
   6:   00 00                   add    %al,(%rax)
   8:   01 7a 52                add    %edi,0x52(%rdx)
   b:   00 01                   add    %al,(%rcx)
   d:   78 10                   js     1f <.eh_frame+0x1f>
   f:   01 1b                   add    %ebx,(%rbx)
  11:   0c 07                   or     $0x7,%al
  13:   08 90 01 00 00 1c       or     %dl,0x1c000001(%rax)
  19:   00 00                   add    %al,(%rax)
  1b:   00 1c 00                add    %bl,(%rax,%rax,1)
  1e:   00 00                   add    %al,(%rax)
  20:   00 00                   add    %al,(%rax)
  22:   00 00                   add    %al,(%rax)
  24:   15 00 00 00 00          adc    $0x0,%eax
  29:   41 0e                   rex.B (bad) 
  2b:   10 86 02 43 0d 06       adc    %al,0x60d4302(%rsi)
  31:   50                      push   %rax
  32:   0c 07                   or     $0x7,%al
  34:   08 00                   or     %al,(%rax)
        ...
[deng@localhost 1gcc]$ 

05. 附录

参考:【Linux】一步一步学Linux系列教程汇总

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值