天天看點

objdump--反彙編檢視

轉載:objdump指令_Linux objdump 指令用法詳解:顯示二進制檔案資訊 (linuxde.net)

objdump指令

程式設計開發

objdump指令是用檢視目标檔案或者可執行的目标檔案的構成的gcc工具。

選項

--archive-headers 
-a 
顯示檔案庫的成員資訊,類似ls -l将lib*.a的資訊列出。 

-b bfdname 
--target=bfdname 
指定目标碼格式。這不是必須的,objdump能自動識别許多格式,比如: 

objdump -b oasys -m vax -h fu.o 
顯示fu.o的頭部摘要資訊,明确指出該檔案是Vax系統下用Oasys編譯器生成的目标檔案。objdump -i将給出這裡可以指定的目标碼格式清單。 

-C 
--demangle 
将底層的符号名解碼成使用者級名字,除了去掉所開頭的下劃線之外,還使得C++函數名以可了解的方式顯示出來。 

--debugging 
-g 
顯示調試資訊。企圖解析儲存在檔案中的調試資訊并以C語言的文法顯示出來。僅僅支援某些類型的調試資訊。有些其他的格式被readelf -w支援。 

-e 
--debugging-tags 
類似-g選項,但是生成的資訊是和ctags工具相相容的格式。 

--disassemble 
-d 
從objfile中反彙編那些特定指令機器碼的section。 

-D 
--disassemble-all 
與 -d 類似,但反彙編所有section. 

--prefix-addresses 
反彙編的時候,顯示每一行的完整位址。這是一種比較老的反彙編格式。 

-EB 
-EL 
--endian={big|little} 
指定目标檔案的小端。這個項将影響反彙編出來的指令。在反彙編的檔案沒描述小端資訊的時候用。例如S-records. 

-f 
--file-headers 
顯示objfile中每個檔案的整體頭部摘要資訊。 

-h 
--section-headers 
--headers 
顯示目标檔案各個section的頭部摘要資訊。 

-H 
--help 
簡短的幫助資訊。 

-i 
--info 
顯示對于 -b 或者 -m 選項可用的架構和目标格式清單。 

-j name
--section=name 
僅僅顯示指定名稱為name的section的資訊 

-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選項載入。      

執行個體

首先,在給出後面大部分測試所基于的源代碼以及編譯指令。 源代碼如下: 

[root@localhost test]# nl mytest.cpp       
void printTest() {
    char a;
    a = 'a';
}

void printTest2() {
int a = 2;
a+=2;
}       

對以上源代碼進行編譯,如下: 

[root@localhost test]# g++ -c -g mytest.cpp       

這裡,生成的檔案是mytest.o,為了友善測試包含了調試的資訊,對可執行檔案的測試,顯示的結果類似。 

檢視目前使用的objdump的版本号: 

[root@localhost test]# 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@localhost test]# 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@localhost test]# 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@localhost test]# 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@localhost test]# 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@localhost test]# 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    

000000c <_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          

objdump -j .text mytest.o是不會運作成功的

。另外-S指令對于包含調試資訊的目标檔案,顯示的效果比較好,如果編譯時沒有指定g++的-g選項,那麼目标檔案就不包含調試資訊,那麼顯示效果就差多了。 

反彙編出mytest.o的源代碼: 

[root@localhost test]# 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@localhost test]# 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@localhost test]# nm -s mytest.o 
0000000c T _Z10printTest2v 
00000000 T _Z9printTestv 
         U __gxx_personality_v0       

顯示檔案的符号表入口,将底層符号解碼并表示成使用者級别: 

[root@localhost test]# 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@localhost test]# 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@localhost test]# 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          

這裡,項"-d"從objfile中反彙編那些特定指令機器碼的section,而使用"-l"指定用檔案名和行号标注相應的目标代碼,僅僅和-d、-D或者-r一起使用,使用-ld和使用-d的差別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。 

顯示目标檔案各個段的頭部摘要資訊: 

[root@localhost test]# 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

中的這個選項。