UNPKG

16.5 kBMarkdownView Raw
1objdump
2===
3
4显示二进制文件信息
5
6## 补充说明
7
8**objdump命令** 是用查看目标文件或者可执行的目标文件的构成的gcc工具。
9
10### 选项
11
12```shell
13-a --archive-headers
14# 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。
15
16-b bfdname --target=bfdname
17# 指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如:
18
19objdump -b oasys -m vax -h fu.o
20# 显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。objdump -i将给出这里可以指定的目标码格式列表。
21
22-C --demangle
23# 将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。
24--debugging
25-g
26# 显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。
27
28-e --debugging-tags
29# 类似-g选项,但是生成的信息是和ctags工具相兼容的格式。
30--disassemble
31-d
32# 从objfile中反汇编那些特定指令机器码的section。
33
34-D --disassemble-all
35# 与 -d 类似,但反汇编所有section.
36
37--prefix-addresses
38# 反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。
39
40-EB
41-EL
42--endian={big|little}
43# 指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records.
44
45-f
46--file-headers
47显示objfile中每个文件的整体头部摘要信息。
48
49-h
50--section-headers
51--headers
52显示目标文件各个section的头部摘要信息。
53
54-H
55--help
56简短的帮助信息。
57
58-i
59--info
60显示对于 -b 或者 -m 选项可用的架构和目标格式列表。
61
62-j name
63--section=name
64仅仅显示指定名称为name的section的信息
65
66-l
67--line-numbers
68用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
69
70-m machine
71--architecture=machine
72指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构.
73
74--reloc
75-r
76显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
77
78--dynamic-reloc
79-R
80显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。
81
82-s
83--full-contents
84显示指定section的完整内容。默认所有的非空section都会被显示。
85
86-S
87--source
88尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
89
90--show-raw-insn
91反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。
92
93--no-show-raw-insn
94反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。
95
96--start-address=address
97从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。
98
99--stop-address=address
100显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。
101
102-t
103--syms
104显示文件的符号表入口。类似于nm -s提供的信息
105
106-T
107--dynamic-syms
108显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。
109
110-V
111--version
112版本信息
113
114--all-headers
115-x
116显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。
117
118-z
119--disassemble-zeroes
120一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。
121
122@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
123```
124
125### 实例
126
127首先,在给出后面大部分测试所基于的源代码以及编译指令。 源代码如下: 
128
129```shell
130root@localhost [test]# nl mytest.cpp
131```
132
133```shell
134void printTest() {
135 char a;
136 a = 'a';
137}
138
139void printTest2() {
140int a = 2;
141a+=2;
142}
143```
144
145对以上源代码进行编译,如下: 
146
147```shell
148[root@localhost test]# g++ -c -g mytest.cpp
149```
150
151这里,生成的文件是mytest.o,为了方便测试包含了调试的信息,对可执行文件的测试,显示的结果类似。 
152
153 **查看当前使用的objdump的版本号: **
154
155```shell
156[root@localhost test]# objdump -V
157GNU objdump 2.17.50.0.6-14.el5 20061020
158Copyright 2005 free Software Foundation, Inc.
159This program is free software; you may redistribute it under the terms of
160the GNU General Public License. This program has absolutely no warranty.
161```
162
163 **查看档案库文件中的信息: **
164
165```shell
166[root@localhost test]# objdump -a libmy2.a
167In archive libmy2.a:
168myfile.o: file format elf32-i386
169rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
170mytest.o: file format elf32-i386
171rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
172```
173
174 **这里,libmy2.a是一个使用ar命令将多个*.o目标文件打包而生成的静态库。命令的输出类似`ar -tv`,相比较`ar -tv`输出如下: **
175
176```shell
177[root@localhost test]# ar -tv libmy2.a
178rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
179rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
180```
181
182显示可用的架构和目标结构列表: 
183
184```shell
185[root@localhost test]# objdump -i
186BFD header file version 2.17.50.0.6-14.el5 20061020
187elf32-i386
188(header little endian, data little endian)
189 i386
190a.out-i386-linux
191(header little endian, data little endian)
192 i386
193efi-app-ia32
194(header little endian, data little endian)
195 i386
196elf64-x86-64
197(header little endian, data little endian)
198 i386
199elf64-little
200(header little endian, data little endian)
201 i386
202elf64-big
203(header big endian, data big endian)
204 i386
205elf32-little
206(header little endian, data little endian)
207 i386
208elf32-big
209(header big endian, data big endian)
210 i386
211srec
212(header endianness unknown, data endianness unknown)
213 i386
214symbolsrec
215(header endianness unknown, data endianness unknown)
216 i386
217tekhex
218(header endianness unknown, data endianness unknown)
219 i386
220binary
221(header endianness unknown, data endianness unknown)
222 i386
223ihex
224(header endianness unknown, data endianness unknown)
225 i386
226trad-core
227(header endianness unknown, data endianness unknown)
228
229 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
230 i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
231
232 elf64-little elf64-big elf32-little elf32-big srec symbolsrec
233 i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec
234
235 tekhex binary ihex trad-core
236 i386 tekhex binary ihex ---------
237```
238
239这里,显示的信息是相对于 -b 或者 -m 选项可用的架构和目标格式列表。 
240
241 **显示mytest.o文件中的text段的内容: **
242
243```shell
244[root@localhost test]# objdump --section=.text -s mytest.o
245mytest.o: file format elf32-i386
246Contents of section .text:
2470000 5589e583 ec10c645 ff61c9c3 5589e583 U......E.a..U...
2480010 ec10c745 fc020000 008345fc 02c9c3 ...E......E....
249```
250
251这里注意,不能单独使用-j或者--section,例如`objdump --section=.text mytest.o`是不会运行成功的。 
252
253 **反汇编mytest.o中的text段内容,并尽可能用源代码形式表示: **
254
255```shell
256[root@localhost test]# objdump -j .text -S mytest.o
257mytest.o: file format elf32-i386
258Disassembly of section .text:
25900000000 <_Z9printTestv>:
260void printTest()
261 0: 55 push %ebp
262 1: 89 e5 mov %esp,%ebp
263 3: 83 ec 10 sub $0x10,%esp
264{
265 char a;
266 a = 'a';
267 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
268}
269 a: c9 leave
270 b: c3 ret
271
272000000c <_Z10printTest2v>:
273void printTest2()
274 c: 55 push %ebp
275 d: 89 e5 mov %esp,%ebp
276 f: 83 ec 10 sub $0x10,%esp
277{
278 int a = 2;
279 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
280 a+=2;
281 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
282}
283 1d: c9 leave
284 1e: c3 ret
285```
286
287这里注意,不能单独使用-j或者--section,例如`objdump -j .text mytest.o是不会运行成功的`。另外-S命令对于包含调试信息的目标文件,显示的效果比较好,如果编译时没有指定g++的-g选项,那么目标文件就不包含调试信息,那么显示效果就差多了。 
288
289 **反汇编出mytest.o的源代码: **
290
291```shell
292[root@localhost test]# objdump -S mytest.o
293mytest.o: file format elf32-i386
294
295Disassembly of section .text:
296
29700000000 <_Z9printTestv>:
298void printTest()
299 0: 55 push %ebp
300 1: 89 e5 mov %esp,%ebp
301 3: 83 ec 10 sub $0x10,%esp
302{
303 char a;
304 a = 'a';
305 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
306}
307 a: c9 leave
308 b: c3 ret
309
3100000000c <_Z10printTest2v>:
311void printTest2()
312 c: 55 push %ebp
313 d: 89 e5 mov %esp,%ebp
314 f: 83 ec 10 sub $0x10,%esp
315{
316 int a = 2;
317 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
318 a+=2;
319 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
320}
321 1d: c9 leave
322 1e: c3 ret
323```
324
325这里,尤其当编译的时候指定了-g这种调试参数时,反汇编的效果比较明显。隐含了-d参数。 
326
327 **显示文件的符号表入口: **
328
329```shell
330[root@localhost test]# objdump -t mytest.o
331mytest.o: file format elf32-i386
332
333SYMBOL TABLE:
33400000000 l df *ABS* 00000000 mytest.cpp
33500000000 l d .text 00000000 .text
33600000000 l d .data 00000000 .data
33700000000 l d .bss 00000000 .bss
33800000000 l d .debug_abbrev 00000000 .debug_abbrev
33900000000 l d .debug_info 00000000 .debug_info
34000000000 l d .debug_line 00000000 .debug_line
34100000000 l d .debug_frame 00000000 .debug_frame
34200000000 l d .debug_loc 00000000 .debug_loc
34300000000 l d .debug_pubnames 00000000 .debug_pubnames
34400000000 l d .debug_aranges 00000000 .debug_aranges
34500000000 l d .note.GNU-stack 00000000 .note.GNU-stack
34600000000 l d .comment 00000000 .comment
34700000000 g F .text 0000000c _Z9printTestv
34800000000 *UND* 00000000 __gxx_personality_v0
3490000000c g F .text 00000013 _Z10printTest2v
350```
351
352这里,输出的信息类似`nm -s`命令的输出,相比较之下,nm命令的输出如下: 
353
354```shell
355[root@localhost test]# nm -s mytest.o
3560000000c T _Z10printTest2v
35700000000 T _Z9printTestv
358 U __gxx_personality_v0
359```
360
361 **显示文件的符号表入口,将底层符号解码并表示成用户级别: **
362
363```shell
364[root@localhost test]# objdump -t -C mytest.o
365mytest.o: file format elf32-i386
366SYMBOL TABLE:
36700000000 l df *ABS* 00000000 mytest.cpp
36800000000 l d .text 00000000 .text
36900000000 l d .data 00000000 .data
37000000000 l d .bss 00000000 .bss
37100000000 l d .debug_abbrev 00000000 .debug_abbrev
37200000000 l d .debug_info 00000000 .debug_info
37300000000 l d .debug_line 00000000 .debug_line
37400000000 l d .debug_frame 00000000 .debug_frame
37500000000 l d .debug_loc 00000000 .debug_loc
37600000000 l d .debug_pubnames 00000000 .debug_pubnames
37700000000 l d .debug_aranges 00000000 .debug_aranges
37800000000 l d .note.GNU-stack 00000000 .note.GNU-stack
37900000000 l d .comment 00000000 .comment
38000000000 g F .text 0000000c printTest()
38100000000 *UND* 00000000 __gxx_personality_v0
3820000000c g F .text 00000013 printTest2()
383```
384
385这里,和没-C相比,printTest2函数可读性增加了。 
386
387 **反汇编目标文件的特定机器码段: **
388
389```shell
390[root@localhost test]# objdump -d mytest.o
391mytest.o: file format elf32-i386
392Disassembly of section .text:
393
39400000000 <_Z9printTestv>:
395 0: 55 push %ebp
396 1: 89 e5 mov %esp,%ebp
397 3: 83 ec 10 sub $0x10,%esp
398 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
399 a: c9 leave
400 b: c3 ret
401
4020000000c <_Z10printTest2v>:
403 c: 55 push %ebp
404 d: 89 e5 mov %esp,%ebp
405 f: 83 ec 10 sub $0x10,%esp
406 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
407 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
408 1d: c9 leave
409 1e: c3 ret
410```
411
412这里,对text段的内容进行了反汇编。 
413
414 **反汇编特定段,并将汇编代码对应的文件名称和行号对应上: **
415
416```shell
417[root@localhost test]# objdump -d -l mytest.o
418mytest.o: file format elf32-i386
419Disassembly of section .text:
420
42100000000 <_Z9printTestv>:
422_Z9printTestv():
423/root/test/04_libraryTest/mytest.cpp:1
424 0: 55 push %ebp
425 1: 89 e5 mov %esp,%ebp
426 3: 83 ec 10 sub $0x10,%esp
427/root/test/04_libraryTest/mytest.cpp:4
428 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
429/root/test/04_libraryTest/mytest.cpp:5
430 a: c9 leave
431 b: c3 ret
432
4330000000c <_Z10printTest2v>:
434_Z10printTest2v():
435/root/test/04_libraryTest/mytest.cpp:6
436 c: 55 push %ebp
437 d: 89 e5 mov %esp,%ebp
438 f: 83 ec 10 sub $0x10,%esp
439/root/test/04_libraryTest/mytest.cpp:8
440 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
441/root/test/04_libraryTest/mytest.cpp:9
442 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
443/root/test/04_libraryTest/mytest.cpp:10
444 1d: c9 leave
445 1e: c3 ret
446```
447
448这里,项"-d"从objfile中反汇编那些特定指令机器码的section,而使用"-l"指定用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 
449
450 **显示目标文件各个段的头部摘要信息: **
451
452```shell
453[root@localhost test]# objdump -h mytest.o
454mytest.o: file format elf32-i386
455
456Sections:
457Idx Name Size VMA LMA File off Algn
458 0 .text 0000001f 00000000 00000000 00000034 2**2
459 CONTENTS, ALLOC, LOAD, readonly, CODE
460 1 .data 00000000 00000000 00000000 00000054 2**2
461 CONTENTS, ALLOC, LOAD, DATA
462 2 .bss 00000000 00000000 00000000 00000054 2**2
463 ALLOC
464 3 .debug_abbrev 00000046 00000000 00000000 00000054 2**0
465 CONTENTS, READONLY, DEBUGGING
466 4 .debug_info 000000ed 00000000 00000000 0000009a 2**0
467 CONTENTS, RELOC, READONLY, DEBUGGING
468 5 .debug_line 0000003e 00000000 00000000 00000187 2**0
469 CONTENTS, RELOC, READONLY, DEBUGGING
470 6 .debug_frame 00000044 00000000 00000000 000001c8 2**2
471 CONTENTS, RELOC, READONLY, DEBUGGING
472 7 .debug_loc 00000058 00000000 00000000 0000020c 2**0
473 CONTENTS, READONLY, DEBUGGING
474 8 .debug_pubnames 0000002f 00000000 00000000 00000264 2**0
475 CONTENTS, RELOC, READONLY, DEBUGGING
476 9 .debug_aranges 00000020 00000000 00000000 00000293 2**0
477 CONTENTS, RELOC, READONLY, DEBUGGING
47810 .comment 0000002e 00000000 00000000 000002b3 2**0
479 CONTENTS, READONLY
48011 .note.GNU-stack 00000000 00000000 00000000 000002e1 2**0
481 CONTENTS, READONLY
482```
483
484这里,更多的内容参见`man objdump`中的这个选项。
485
486