1 | objdump
|
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 |
|
19 | objdump -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
|
130 | root@localhost [test]# nl mytest.cpp
|
131 | ```
|
132 |
|
133 | ```shell
|
134 | void printTest() {
|
135 | char a;
|
136 | a = 'a';
|
137 | }
|
138 |
|
139 | void printTest2() {
|
140 | int a = 2;
|
141 | a+=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
|
157 | GNU objdump 2.17.50.0.6-14.el5 20061020
|
158 | Copyright 2005 free Software Foundation, Inc.
|
159 | This program is free software; you may redistribute it under the terms of
|
160 | the GNU General Public License. This program has absolutely no warranty.
|
161 | ```
|
162 |
|
163 | **查看档案库文件中的信息: **
|
164 |
|
165 | ```shell
|
166 | [root@localhost test]# objdump -a libmy2.a
|
167 | In archive libmy2.a:
|
168 | myfile.o: file format elf32-i386
|
169 | rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
|
170 | mytest.o: file format elf32-i386
|
171 | rw-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
|
178 | rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
|
179 | rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
|
180 | ```
|
181 |
|
182 | 显示可用的架构和目标结构列表:
|
183 |
|
184 | ```shell
|
185 | [root@localhost test]# objdump -i
|
186 | BFD header file version 2.17.50.0.6-14.el5 20061020
|
187 | elf32-i386
|
188 | (header little endian, data little endian)
|
189 | i386
|
190 | a.out-i386-linux
|
191 | (header little endian, data little endian)
|
192 | i386
|
193 | efi-app-ia32
|
194 | (header little endian, data little endian)
|
195 | i386
|
196 | elf64-x86-64
|
197 | (header little endian, data little endian)
|
198 | i386
|
199 | elf64-little
|
200 | (header little endian, data little endian)
|
201 | i386
|
202 | elf64-big
|
203 | (header big endian, data big endian)
|
204 | i386
|
205 | elf32-little
|
206 | (header little endian, data little endian)
|
207 | i386
|
208 | elf32-big
|
209 | (header big endian, data big endian)
|
210 | i386
|
211 | srec
|
212 | (header endianness unknown, data endianness unknown)
|
213 | i386
|
214 | symbolsrec
|
215 | (header endianness unknown, data endianness unknown)
|
216 | i386
|
217 | tekhex
|
218 | (header endianness unknown, data endianness unknown)
|
219 | i386
|
220 | binary
|
221 | (header endianness unknown, data endianness unknown)
|
222 | i386
|
223 | ihex
|
224 | (header endianness unknown, data endianness unknown)
|
225 | i386
|
226 | trad-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
|
245 | mytest.o: file format elf32-i386
|
246 | Contents of section .text:
|
247 | 0000 5589e583 ec10c645 ff61c9c3 5589e583 U......E.a..U...
|
248 | 0010 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
|
257 | mytest.o: file format elf32-i386
|
258 | Disassembly of section .text:
|
259 | 00000000 <_Z9printTestv>:
|
260 | void 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 |
|
272 | 000000c <_Z10printTest2v>:
|
273 | void 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
|
293 | mytest.o: file format elf32-i386
|
294 |
|
295 | Disassembly of section .text:
|
296 |
|
297 | 00000000 <_Z9printTestv>:
|
298 | void 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 |
|
310 | 0000000c <_Z10printTest2v>:
|
311 | void 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
|
331 | mytest.o: file format elf32-i386
|
332 |
|
333 | SYMBOL TABLE:
|
334 | 00000000 l df *ABS* 00000000 mytest.cpp
|
335 | 00000000 l d .text 00000000 .text
|
336 | 00000000 l d .data 00000000 .data
|
337 | 00000000 l d .bss 00000000 .bss
|
338 | 00000000 l d .debug_abbrev 00000000 .debug_abbrev
|
339 | 00000000 l d .debug_info 00000000 .debug_info
|
340 | 00000000 l d .debug_line 00000000 .debug_line
|
341 | 00000000 l d .debug_frame 00000000 .debug_frame
|
342 | 00000000 l d .debug_loc 00000000 .debug_loc
|
343 | 00000000 l d .debug_pubnames 00000000 .debug_pubnames
|
344 | 00000000 l d .debug_aranges 00000000 .debug_aranges
|
345 | 00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
|
346 | 00000000 l d .comment 00000000 .comment
|
347 | 00000000 g F .text 0000000c _Z9printTestv
|
348 | 00000000 *UND* 00000000 __gxx_personality_v0
|
349 | 0000000c g F .text 00000013 _Z10printTest2v
|
350 | ```
|
351 |
|
352 | 这里,输出的信息类似`nm -s`命令的输出,相比较之下,nm命令的输出如下:
|
353 |
|
354 | ```shell
|
355 | [root@localhost test]# nm -s mytest.o
|
356 | 0000000c T _Z10printTest2v
|
357 | 00000000 T _Z9printTestv
|
358 | U __gxx_personality_v0
|
359 | ```
|
360 |
|
361 | **显示文件的符号表入口,将底层符号解码并表示成用户级别: **
|
362 |
|
363 | ```shell
|
364 | [root@localhost test]# objdump -t -C mytest.o
|
365 | mytest.o: file format elf32-i386
|
366 | SYMBOL TABLE:
|
367 | 00000000 l df *ABS* 00000000 mytest.cpp
|
368 | 00000000 l d .text 00000000 .text
|
369 | 00000000 l d .data 00000000 .data
|
370 | 00000000 l d .bss 00000000 .bss
|
371 | 00000000 l d .debug_abbrev 00000000 .debug_abbrev
|
372 | 00000000 l d .debug_info 00000000 .debug_info
|
373 | 00000000 l d .debug_line 00000000 .debug_line
|
374 | 00000000 l d .debug_frame 00000000 .debug_frame
|
375 | 00000000 l d .debug_loc 00000000 .debug_loc
|
376 | 00000000 l d .debug_pubnames 00000000 .debug_pubnames
|
377 | 00000000 l d .debug_aranges 00000000 .debug_aranges
|
378 | 00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
|
379 | 00000000 l d .comment 00000000 .comment
|
380 | 00000000 g F .text 0000000c printTest()
|
381 | 00000000 *UND* 00000000 __gxx_personality_v0
|
382 | 0000000c g F .text 00000013 printTest2()
|
383 | ```
|
384 |
|
385 | 这里,和没-C相比,printTest2函数可读性增加了。
|
386 |
|
387 | **反汇编目标文件的特定机器码段: **
|
388 |
|
389 | ```shell
|
390 | [root@localhost test]# objdump -d mytest.o
|
391 | mytest.o: file format elf32-i386
|
392 | Disassembly of section .text:
|
393 |
|
394 | 00000000 <_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 |
|
402 | 0000000c <_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
|
418 | mytest.o: file format elf32-i386
|
419 | Disassembly of section .text:
|
420 |
|
421 | 00000000 <_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 |
|
433 | 0000000c <_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
|
454 | mytest.o: file format elf32-i386
|
455 |
|
456 | Sections:
|
457 | Idx 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
|
478 | 10 .comment 0000002e 00000000 00000000 000002b3 2**0
|
479 | CONTENTS, READONLY
|
480 | 11 .note.GNU-stack 00000000 00000000 00000000 000002e1 2**0
|
481 | CONTENTS, READONLY
|
482 | ```
|
483 |
|
484 | 这里,更多的内容参见`man objdump`中的这个选项。
|
485 |
|
486 |
|