Linux学习|Gentoo/Arch/FreeBSDLinuxLinux学习之路

Linux命令学习手册-objdump

2020-03-15  本文已影响0人  QuietHeart
objdump [选项] objfile...

功能

显示二进制文件信息

描述

objdump 用来显示一个或者多个目标文件的信息。使用选项控制具体显示哪些信息。参数 objfile... 可以是静态库归档文件。

下面是一些常见的选项:

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

举例

首先,在给出后面大部分测试所基于的源代码以及编译指令。

源代码如下:

[root@lv-k 04_libraryTest]# nl mytest.cpp 
     1  void printTest() 
     2  { 
     3          char a; 
     4          a = 'a'; 
     5  } 
     6  void printTest2() 
     7  { 
     8          int a = 2; 
     9          a+=2; 
    10  }

对以上源代码进行编译,如下:

[root@lv-k 04_libraryTest]# g++ -c -g mytest.cpp

这里,生成的文件是 mytest.o ,为了方便测试包含了调试的信息,对可执行文件的测试,显示的结果类似。

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

[root@lv-k 04_libraryTest]# objdump -V

输入之后输出如下:

GNU objdump 2.17.50.0.6-14.el5 20061020 
Copyright 2005 Free Software Foundation, Inc. 
This program is free software; you may redistribute it under the terms of 
the GNU General Public License.  This program has absolutely no warranty.

查看档案库文件中的信息

[root@lv-k 04_libraryTest]# objdump -a libmy2.a

输入之后输出如下:

In archive libmy2.a: 

myfile.o:     file format elf32-i386 
rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 

mytest.o:     file format elf32-i386 
rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o

这里, libmy2.a 是一个使用 ar 命令将多个 *.o 目标文件打包而生成的静态库。命令的输出类似 ar -tv ,相比较 ar -tv 输出如下:

[root@lv-k 04_libraryTest]# ar -tv libmy2.a 
rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 
rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o

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

[root@lv-k 04_libraryTest]# objdump -i

输入之后输出如下:

BFD header file version 2.17.50.0.6-14.el5 20061020 
elf32-i386 
(header little endian, data little endian) 
  i386 
a.out-i386-linux 
(header little endian, data little endian) 
  i386 
efi-app-ia32 
(header little endian, data little endian) 
  i386 
elf64-x86-64 
(header little endian, data little endian) 
  i386 
elf64-little 
(header little endian, data little endian) 
  i386 
elf64-big 
(header big endian, data big endian) 
  i386 
elf32-little 
(header little endian, data little endian) 
  i386 
elf32-big 
(header big endian, data big endian) 
  i386 
srec 
(header endianness unknown, data endianness unknown) 
  i386 
symbolsrec 
(header endianness unknown, data endianness unknown) 
  i386 
tekhex 
(header endianness unknown, data endianness unknown) 
  i386 
binary 
(header endianness unknown, data endianness unknown) 
  i386 
ihex 
(header endianness unknown, data endianness unknown) 
  i386 
trad-core 
(header endianness unknown, data endianness unknown) 

               elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 
          i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 

               elf64-little elf64-big elf32-little elf32-big srec symbolsrec 
          i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec 

               tekhex binary ihex trad-core 
          i386 tekhex binary ihex ---------

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

显示 mytest.o 文件中的 text 段的内容

[root@lv-k 04_libraryTest]# objdump --section=.text -s mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Contents of section .text: 
0000 5589e583 ec10c645 ff61c9c3 5589e583  U......E.a..U... 
0010 ec10c745 fc020000 008345fc 02c9c3    ...E......E....

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

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

[root@lv-k 04_libraryTest]# objdump -j .text -S mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z9printTestv>: 
void printTest() 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
{ 
        char a; 
        a = 'a'; 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
} 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
void printTest2() 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
{ 
        int a = 2; 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
        a+=2; 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
} 
  1d:   c9                      leave  
  1e:   c3                      ret

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

反汇编出 mytest.o 的源代码

[root@lv-k 04_libraryTest]# objdump -S mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z9printTestv>: 
void printTest() 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
{ 
        char a; 
        a = 'a'; 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
} 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
void printTest2() 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
{ 
        int a = 2; 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
        a+=2; 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
} 
  1d:   c9                      leave  
  1e:   c3                      ret

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

显示文件的符号表入口

[root@lv-k 04_libraryTest]# objdump -t mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

SYMBOL TABLE: 
00000000 l    df *ABS*  00000000 mytest.cpp 
00000000 l    d  .text  00000000 .text 
00000000 l    d  .data  00000000 .data 
00000000 l    d  .bss   00000000 .bss 
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
00000000 l    d  .debug_info    00000000 .debug_info 
00000000 l    d  .debug_line    00000000 .debug_line 
00000000 l    d  .debug_frame   00000000 .debug_frame 
00000000 l    d  .debug_loc     00000000 .debug_loc 
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
00000000 l    d  .debug_aranges 00000000 .debug_aranges 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
00000000 l    d  .comment       00000000 .comment 
00000000 g     F .text  0000000c _Z9printTestv 
00000000         *UND*  00000000 __gxx_personality_v0 
0000000c g     F .text  00000013 _Z10printTest2v

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

[root@lv-k 04_libraryTest]# nm -s mytest.o 
0000000c T _Z10printTest2v 
00000000 T _Z9printTestv 
         U __gxx_personality_v0

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

[root@lv-k 04_libraryTest]# objdump -t -C mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

SYMBOL TABLE: 
00000000 l    df *ABS*  00000000 mytest.cpp 
00000000 l    d  .text  00000000 .text 
00000000 l    d  .data  00000000 .data 
00000000 l    d  .bss   00000000 .bss 
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
00000000 l    d  .debug_info    00000000 .debug_info 
00000000 l    d  .debug_line    00000000 .debug_line 
00000000 l    d  .debug_frame   00000000 .debug_frame 
00000000 l    d  .debug_loc     00000000 .debug_loc 
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
00000000 l    d  .debug_aranges 00000000 .debug_aranges 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
00000000 l    d  .comment       00000000 .comment 
00000000 g     F .text  0000000c printTest() 
00000000         *UND*  00000000 __gxx_personality_v0 
0000000c g     F .text  00000013 printTest2()

这里,和没 -C 相比, printTest2 函数可读性增加了。

反汇编目标文件的特定机器码段

[root@lv-k 04_libraryTest]# objdump -d mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z9printTestv>: 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
  1d:   c9                      leave  
  1e:   c3                      ret

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

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

[root@lv-k 04_libraryTest]# objdump -d -l mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z9printTestv>: 
_Z9printTestv(): 
/root/test/04_libraryTest/mytest.cpp:1 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
/root/test/04_libraryTest/mytest.cpp:4 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
/root/test/04_libraryTest/mytest.cpp:5 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
_Z10printTest2v(): 
/root/test/04_libraryTest/mytest.cpp:6 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
/root/test/04_libraryTest/mytest.cpp:8 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
/root/test/04_libraryTest/mytest.cpp:9 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
/root/test/04_libraryTest/mytest.cpp:10 
  1d:   c9                      leave  
  1e:   c3                      ret

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

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

[root@lv-k 04_libraryTest]# objdump -h mytest.o

输入之后输出如下:

mytest.o:     file format elf32-i386 

Sections: 
Idx Name          Size      VMA       LMA       File off  Algn 
  0 .text         0000001f  00000000  00000000  00000034  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
  1 .data         00000000  00000000  00000000  00000054  2**2 
                  CONTENTS, ALLOC, LOAD, DATA 
  2 .bss          00000000  00000000  00000000  00000054  2**2 
                  ALLOC 
  3 .debug_abbrev 00000046  00000000  00000000  00000054  2**0 
                  CONTENTS, READONLY, DEBUGGING 
  4 .debug_info   000000ed  00000000  00000000  0000009a  2**0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  5 .debug_line   0000003e  00000000  00000000  00000187  2**0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  6 .debug_frame  00000044  00000000  00000000  000001c8  2**2 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  7 .debug_loc    00000058  00000000  00000000  0000020c  2**0 
                  CONTENTS, READONLY, DEBUGGING 
  8 .debug_pubnames 0000002f  00000000  00000000  00000264  2**0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  9 .debug_aranges 00000020  00000000  00000000  00000293  2**0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
10 .comment      0000002e  00000000  00000000  000002b3  2**0 
                  CONTENTS, READONLY 
11 .note.GNU-stack 00000000  00000000  00000000  000002e1  2**0 
                  CONTENTS, READONLY

这里,更多的内容参见 man objdump 中的这个选项。

其它

更多的命令参见 man objdump

参考:

上一篇 下一篇

猜你喜欢

热点阅读