objdump
显示二进制文件信息
补充说明
objdump命令 是用查看目标文件或者可执行的目标文件的构成的gcc工具。
选项
1-a --archive-headers
2# 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。
3
4-b bfdname --target=bfdname
5# 指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如:
6
7objdump -b oasys -m vax -h fu.o
8# 显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。objdump -i将给出这里可以指定的目标码格式列表。
9
10-C --demangle
11# 将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。
12--debugging
13-g
14# 显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。
15
16-e --debugging-tags
17# 类似-g选项,但是生成的信息是和ctags工具相兼容的格式。
18--disassemble
19-d
20# 从objfile中反汇编那些特定指令机器码的section。
21
22-D --disassemble-all
23# 与 -d 类似,但反汇编所有section.
24
25--prefix-addresses
26# 反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。
27
28-EB
29-EL
30--endian={big|little}
31# 指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records.
32
33-f
34--file-headers
35显示objfile中每个文件的整体头部摘要信息。
36
37-h
38--section-headers
39--headers
40显示目标文件各个section的头部摘要信息。
41
42-H
43--help
44简短的帮助信息。
45
46-i
47--info
48显示对于 -b 或者 -m 选项可用的架构和目标格式列表。
49
50-j name
51--section=name
52仅仅显示指定名称为name的section的信息
53
54-l
55--line-numbers
56用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
57
58-m machine
59--architecture=machine
60指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构.
61
62--reloc
63-r
64显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
65
66--dynamic-reloc
67-R
68显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。
69
70-s
71--full-contents
72显示指定section的完整内容。默认所有的非空section都会被显示。
73
74-S
75--source
76尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
77
78--show-raw-insn
79反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。
80
81--no-show-raw-insn
82反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。
83
84--start-address=address
85从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。
86
87--stop-address=address
88显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。
89
90-t
91--syms
92显示文件的符号表入口。类似于nm -s提供的信息
93
94-T
95--dynamic-syms
96显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。
97
98-V
99--version
100版本信息
101
102--all-headers
103-x
104显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。
105
106-z
107--disassemble-zeroes
108一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。
109
110@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
实例
首先,在给出后面大部分测试所基于的源代码以及编译指令。 源代码如下:
1root@localhost [test]# nl mytest.cpp
1void printTest() {
2 char a;
3 a = 'a';
4}
5
6void printTest2() {
7int a = 2;
8a+=2;
9}
对以上源代码进行编译,如下:
1[root@localhost test]# g++ -c -g mytest.cpp
这里,生成的文件是mytest.o,为了方便测试包含了调试的信息,对可执行文件的测试,显示的结果类似。
**查看当前使用的objdump的版本号: **
1[root@localhost test]# objdump -V
2GNU objdump 2.17.50.0.6-14.el5 20061020
3Copyright 2005 free Software Foundation, Inc.
4This program is free software; you may redistribute it under the terms of
5the GNU General Public License. This program has absolutely no warranty.
**查看档案库文件中的信息: **
1[root@localhost test]# objdump -a libmy2.a
2In archive libmy2.a:
3myfile.o: file format elf32-i386
4rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
5mytest.o: file format elf32-i386
6rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
*这里,libmy2.a是一个使用ar命令将多个.o目标文件打包而生成的静态库。命令的输出类似ar -tv
,相比较ar -tv
输出如下: **
1[root@localhost test]# ar -tv libmy2.a
2rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
3rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
显示可用的架构和目标结构列表:
1[root@localhost test]# objdump -i
2BFD header file version 2.17.50.0.6-14.el5 20061020
3elf32-i386
4(header little endian, data little endian)
5 i386
6a.out-i386-linux
7(header little endian, data little endian)
8 i386
9efi-app-ia32
10(header little endian, data little endian)
11 i386
12elf64-x86-64
13(header little endian, data little endian)
14 i386
15elf64-little
16(header little endian, data little endian)
17 i386
18elf64-big
19(header big endian, data big endian)
20 i386
21elf32-little
22(header little endian, data little endian)
23 i386
24elf32-big
25(header big endian, data big endian)
26 i386
27srec
28(header endianness unknown, data endianness unknown)
29 i386
30symbolsrec
31(header endianness unknown, data endianness unknown)
32 i386
33tekhex
34(header endianness unknown, data endianness unknown)
35 i386
36binary
37(header endianness unknown, data endianness unknown)
38 i386
39ihex
40(header endianness unknown, data endianness unknown)
41 i386
42trad-core
43(header endianness unknown, data endianness unknown)
44
45 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
46 i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
47
48 elf64-little elf64-big elf32-little elf32-big srec symbolsrec
49 i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec
50
51 tekhex binary ihex trad-core
52 i386 tekhex binary ihex ---------
这里,显示的信息是相对于 -b 或者 -m 选项可用的架构和目标格式列表。
**显示mytest.o文件中的text段的内容: **
1[root@localhost test]# objdump --section=.text -s mytest.o
2mytest.o: file format elf32-i386
3Contents of section .text:
40000 5589e583 ec10c645 ff61c9c3 5589e583 U......E.a..U...
50010 ec10c745 fc020000 008345fc 02c9c3 ...E......E....
这里注意,不能单独使用-j或者--section,例如objdump --section=.text mytest.o
是不会运行成功的。
**反汇编mytest.o中的text段内容,并尽可能用源代码形式表示: **
1[root@localhost test]# objdump -j .text -S mytest.o
2mytest.o: file format elf32-i386
3Disassembly of section .text:
400000000 <_Z9printTestv>:
5void printTest()
6 0: 55 push %ebp
7 1: 89 e5 mov %esp,%ebp
8 3: 83 ec 10 sub $0x10,%esp
9{
10 char a;
11 a = 'a';
12 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
13}
14 a: c9 leave
15 b: c3 ret
16
17000000c <_Z10printTest2v>:
18void printTest2()
19 c: 55 push %ebp
20 d: 89 e5 mov %esp,%ebp
21 f: 83 ec 10 sub $0x10,%esp
22{
23 int a = 2;
24 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
25 a+=2;
26 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
27}
28 1d: c9 leave
29 1e: c3 ret
这里注意,不能单独使用-j或者--section,例如objdump -j .text mytest.o是不会运行成功的
。另外-S命令对于包含调试信息的目标文件,显示的效果比较好,如果编译时没有指定g++的-g选项,那么目标文件就不包含调试信息,那么显示效果就差多了。
**反汇编出mytest.o的源代码: **
1[root@localhost test]# objdump -S mytest.o
2mytest.o: file format elf32-i386
3
4Disassembly of section .text:
5
600000000 <_Z9printTestv>:
7void printTest()
8 0: 55 push %ebp
9 1: 89 e5 mov %esp,%ebp
10 3: 83 ec 10 sub $0x10,%esp
11{
12 char a;
13 a = 'a';
14 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
15}
16 a: c9 leave
17 b: c3 ret
18
190000000c <_Z10printTest2v>:
20void printTest2()
21 c: 55 push %ebp
22 d: 89 e5 mov %esp,%ebp
23 f: 83 ec 10 sub $0x10,%esp
24{
25 int a = 2;
26 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
27 a+=2;
28 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
29}
30 1d: c9 leave
31 1e: c3 ret
这里,尤其当编译的时候指定了-g这种调试参数时,反汇编的效果比较明显。隐含了-d参数。
**显示文件的符号表入口: **
1[root@localhost test]# objdump -t mytest.o
2mytest.o: file format elf32-i386
3
4SYMBOL TABLE:
500000000 l df *ABS* 00000000 mytest.cpp
600000000 l d .text 00000000 .text
700000000 l d .data 00000000 .data
800000000 l d .bss 00000000 .bss
900000000 l d .debug_abbrev 00000000 .debug_abbrev
1000000000 l d .debug_info 00000000 .debug_info
1100000000 l d .debug_line 00000000 .debug_line
1200000000 l d .debug_frame 00000000 .debug_frame
1300000000 l d .debug_loc 00000000 .debug_loc
1400000000 l d .debug_pubnames 00000000 .debug_pubnames
1500000000 l d .debug_aranges 00000000 .debug_aranges
1600000000 l d .note.GNU-stack 00000000 .note.GNU-stack
1700000000 l d .comment 00000000 .comment
1800000000 g F .text 0000000c _Z9printTestv
1900000000 *UND* 00000000 __gxx_personality_v0
200000000c g F .text 00000013 _Z10printTest2v
这里,输出的信息类似nm -s
命令的输出,相比较之下,nm命令的输出如下:
1[root@localhost test]# nm -s mytest.o
20000000c T _Z10printTest2v
300000000 T _Z9printTestv
4 U __gxx_personality_v0
**显示文件的符号表入口,将底层符号解码并表示成用户级别: **
1[root@localhost test]# objdump -t -C mytest.o
2mytest.o: file format elf32-i386
3SYMBOL TABLE:
400000000 l df *ABS* 00000000 mytest.cpp
500000000 l d .text 00000000 .text
600000000 l d .data 00000000 .data
700000000 l d .bss 00000000 .bss
800000000 l d .debug_abbrev 00000000 .debug_abbrev
900000000 l d .debug_info 00000000 .debug_info
1000000000 l d .debug_line 00000000 .debug_line
1100000000 l d .debug_frame 00000000 .debug_frame
1200000000 l d .debug_loc 00000000 .debug_loc
1300000000 l d .debug_pubnames 00000000 .debug_pubnames
1400000000 l d .debug_aranges 00000000 .debug_aranges
1500000000 l d .note.GNU-stack 00000000 .note.GNU-stack
1600000000 l d .comment 00000000 .comment
1700000000 g F .text 0000000c printTest()
1800000000 *UND* 00000000 __gxx_personality_v0
190000000c g F .text 00000013 printTest2()
这里,和没-C相比,printTest2函数可读性增加了。
**反汇编目标文件的特定机器码段: **
1[root@localhost test]# objdump -d mytest.o
2mytest.o: file format elf32-i386
3Disassembly of section .text:
4
500000000 <_Z9printTestv>:
6 0: 55 push %ebp
7 1: 89 e5 mov %esp,%ebp
8 3: 83 ec 10 sub $0x10,%esp
9 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
10 a: c9 leave
11 b: c3 ret
12
130000000c <_Z10printTest2v>:
14 c: 55 push %ebp
15 d: 89 e5 mov %esp,%ebp
16 f: 83 ec 10 sub $0x10,%esp
17 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
18 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
19 1d: c9 leave
20 1e: c3 ret
这里,对text段的内容进行了反汇编。
**反汇编特定段,并将汇编代码对应的文件名称和行号对应上: **
1[root@localhost test]# objdump -d -l mytest.o
2mytest.o: file format elf32-i386
3Disassembly of section .text:
4
500000000 <_Z9printTestv>:
6_Z9printTestv():
7/root/test/04_libraryTest/mytest.cpp:1
8 0: 55 push %ebp
9 1: 89 e5 mov %esp,%ebp
10 3: 83 ec 10 sub $0x10,%esp
11/root/test/04_libraryTest/mytest.cpp:4
12 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
13/root/test/04_libraryTest/mytest.cpp:5
14 a: c9 leave
15 b: c3 ret
16
170000000c <_Z10printTest2v>:
18_Z10printTest2v():
19/root/test/04_libraryTest/mytest.cpp:6
20 c: 55 push %ebp
21 d: 89 e5 mov %esp,%ebp
22 f: 83 ec 10 sub $0x10,%esp
23/root/test/04_libraryTest/mytest.cpp:8
24 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
25/root/test/04_libraryTest/mytest.cpp:9
26 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
27/root/test/04_libraryTest/mytest.cpp:10
28 1d: c9 leave
29 1e: c3 ret
这里,项"-d"从objfile中反汇编那些特定指令机器码的section,而使用"-l"指定用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
**显示目标文件各个段的头部摘要信息: **
1[root@localhost test]# objdump -h mytest.o
2mytest.o: file format elf32-i386
3
4Sections:
5Idx Name Size VMA LMA File off Algn
6 0 .text 0000001f 00000000 00000000 00000034 2**2
7 CONTENTS, ALLOC, LOAD, readonly, CODE
8 1 .data 00000000 00000000 00000000 00000054 2**2
9 CONTENTS, ALLOC, LOAD, DATA
10 2 .bss 00000000 00000000 00000000 00000054 2**2
11 ALLOC
12 3 .debug_abbrev 00000046 00000000 00000000 00000054 2**0
13 CONTENTS, READONLY, DEBUGGING
14 4 .debug_info 000000ed 00000000 00000000 0000009a 2**0
15 CONTENTS, RELOC, READONLY, DEBUGGING
16 5 .debug_line 0000003e 00000000 00000000 00000187 2**0
17 CONTENTS, RELOC, READONLY, DEBUGGING
18 6 .debug_frame 00000044 00000000 00000000 000001c8 2**2
19 CONTENTS, RELOC, READONLY, DEBUGGING
20 7 .debug_loc 00000058 00000000 00000000 0000020c 2**0
21 CONTENTS, READONLY, DEBUGGING
22 8 .debug_pubnames 0000002f 00000000 00000000 00000264 2**0
23 CONTENTS, RELOC, READONLY, DEBUGGING
24 9 .debug_aranges 00000020 00000000 00000000 00000293 2**0
25 CONTENTS, RELOC, READONLY, DEBUGGING
2610 .comment 0000002e 00000000 00000000 000002b3 2**0
27 CONTENTS, READONLY
2811 .note.GNU-stack 00000000 00000000 00000000 000002e1 2**0
29 CONTENTS, READONLY
这里,更多的内容参见man objdump
中的这个选项。
来源:https://github.com/jaywcjlove/linux-command
版权申明:
- 未标注来源的内容全部为原创,未经授权请勿转载(因转载后排版往往错乱、内容不可控、无法持续更新等);
- 非营利为目的,演绎本博客任何内容,请以'原文出处'或者'参考链接'等方式给出本站相关网页地址(方便读者)。