objdump - 维基百科,自由的百科全书

objdump
操作系统Unix类Unix
类型命令
许可协议GNU GPL

objdump是在类Unix操作系统上显示关于目标文件的各种信息的命令行程序。例如,它可用作反汇编器来以汇编代码形式查看可执行文件。它是GNU Binutils的一部分,用于在可执行文件和其他二进制数据上进行精细粒度控制。objdump使用BFD库来读取目标文件的内容。类似工具还有readelfMicrosoft DUMPBIN和Borland TDUMP。

注意在特定平台(比如Mac OS X)上,objdump二进制文件可能实际上被连接到LLVM的objdump,它有着不同的命令选项和表现。

例子

[编辑]

比如对nm条目的例子代码编译成的目标文件test.o

$ gcc -c test.c 

执行如下命令:

$ objdump -t test.o 

显示符号表的内容:

test.o:     file format elf64-x86-64  SYMBOL TABLE: 0000000000000000 l    df *ABS*	0000000000000000 test.c 0000000000000000 l    d  .text	0000000000000000 .text 0000000000000000 l    d  .data	0000000000000000 .data 0000000000000000 l    d  .bss	0000000000000000 .bss 0000000000000004 l     O .bss	0000000000000004 static_var 0000000000000004 l     O .data	0000000000000004 static_var_init 0000000000000000 l     F .text	000000000000000f static_function 0000000000000008 l     O .bss	0000000000000004 local_static_var.1 0000000000000008 l     O .data	0000000000000004 local_static_var_init.0 0000000000000000 g     O .bss	0000000000000004 global_var 0000000000000000 g     O .data	0000000000000004 global_var_init 000000000000000f g     F .text	0000000000000024 global_function 0000000000000033 g     F .text	0000000000000012 global_function2 0000000000000045 g     F .text	000000000000000b non_mangled_function 0000000000000050 g     F .text	0000000000000023 main 

当第3列为O时第5列为对齐,当第3列为F时第5列为大小。

接着执行如下命令:

$ objdump -t test.o | awk '$3=="O" {print $0}' | sort -k4,4 

从符号表中检索出同BSS节数据节有关的内容:

0000000000000000 g     O .bss	0000000000000004 global_var 0000000000000004 l     O .bss	0000000000000004 static_var 0000000000000008 l     O .bss	0000000000000004 local_static_var.1 0000000000000000 g     O .data	0000000000000004 global_var_init 0000000000000004 l     O .data	0000000000000004 static_var_init 0000000000000008 l     O .data	0000000000000004 local_static_var_init.0 

接着执行如下命令:

$ objdump -r -j.text test.o 

显示正文节重定位英语Relocation (computing)记录:

test.o:     file format elf64-x86-64  RELOCATION RECORDS FOR [.text]: OFFSET           TYPE              VALUE 000000000000001f R_X86_64_PC32     .bss+0x0000000000000004 0000000000000025 R_X86_64_PC32     .data+0x0000000000000004 000000000000002b R_X86_64_PC32     .bss+0x0000000000000004 000000000000005a R_X86_64_PC32     global_var-0x0000000000000008 0000000000000064 R_X86_64_PC32     .bss-0x0000000000000004 

这里重定位类型中的PC指示程序计数器

接着执行如下命令:

 $ objdump -d -r -M intel test.o 

这里的-d选项指定反汇编包含指令的章节,而-r选项在此指定在需要重定位的空位处,标示出对应的重定位项目。这里使用-M intel选项选用intel语法展示汇编代码,默认将用AT&T语法展示。结果输出为:

test.o:     file format elf64-x86-64   Disassembly of section .text:  0000000000000000 <static_function>:    0:	f3 0f 1e fa          	endbr64    4:	55                   	push   rbp    5:	48 89 e5             	mov    rbp,rsp    8:	b8 00 00 00 00       	mov    eax,0x0    d:	5d                   	pop    rbp    e:	c3                   	ret  000000000000000f <global_function>:    f:	f3 0f 1e fa          	endbr64   13:	55                   	push   rbp   14:	48 89 e5             	mov    rbp,rsp   17:	89 7d fc             	mov    DWORD PTR [rbp-0x4],edi   1a:	8b 45 fc             	mov    eax,DWORD PTR [rbp-0x4]   1d:	89 05 00 00 00 00    	mov    DWORD PTR [rip+0x0],eax        # 23 <global_function+0x14> 			1f: R_X86_64_PC32	.bss+0x4   23:	8b 15 00 00 00 00    	mov    edx,DWORD PTR [rip+0x0]        # 29 <global_function+0x1a> 			25: R_X86_64_PC32	.data+0x4   29:	8b 05 00 00 00 00    	mov    eax,DWORD PTR [rip+0x0]        # 2f <global_function+0x20> 			2b: R_X86_64_PC32	.bss+0x4   2f:	01 d0                	add    eax,edx   31:	5d                   	pop    rbp   32:	c3                   	ret  0000000000000033 <global_function2>:   33:	f3 0f 1e fa          	endbr64   37:	55                   	push   rbp   38:	48 89 e5             	mov    rbp,rsp   3b:	8b 55 f8             	mov    edx,DWORD PTR [rbp-0x8]   3e:	8b 45 fc             	mov    eax,DWORD PTR [rbp-0x4]   41:	01 d0                	add    eax,edx   43:	5d                   	pop    rbp   44:	c3                   	ret  0000000000000045 <non_mangled_function>:   45:	f3 0f 1e fa          	endbr64   49:	55                   	push   rbp   4a:	48 89 e5             	mov    rbp,rsp   4d:	90                   	nop   4e:	5d                   	pop    rbp   4f:	c3                   	ret  0000000000000050 <main>:   50:	f3 0f 1e fa          	endbr64   54:	55                   	push   rbp   55:	48 89 e5             	mov    rbp,rsp   58:	c7 05 00 00 00 00 01 	mov    DWORD PTR [rip+0x0],0x1        # 62 <main+0x12>   5f:	00 00 00  			5a: R_X86_64_PC32	global_var-0x8   62:	c7 05 00 00 00 00 02 	mov    DWORD PTR [rip+0x0],0x2        # 6c <main+0x1c>   69:	00 00 00  			64: R_X86_64_PC32	.bss-0x4   6c:	b8 00 00 00 00       	mov    eax,0x0   71:	5d                   	pop    rbp   72:	c3                   	ret 

由于需要加上当前指令长度,这里的.text+0x1f.text+0x2b处空位重定位为.bss+0x00000004,它加上0x04对应.bss+0x00000008处的local_static_var.1.text+0x25处空位重定位为.data+0x00000004,它加上0x04对应.data+0x00000008处的local_static_var_init.0.text+0x5a处空位重定位为global_var-0x00000008,它加上0x08对应.bss+0x00000000处的global_var.text+0x64处空位重定位为.bss-0x00000004,它加上0x08对应.bss+0x00000004处的static_var

将例子源文件编译为位置无关代码

$ gcc -fPIC -c test.c 

接着执行如下命令:

$ objdump -r -j.text test.o 

显示正文节的重定位记录:

test.o:     file format elf64-x86-64  RELOCATION RECORDS FOR [.text]: OFFSET           TYPE              VALUE 000000000000001f R_X86_64_PC32     .bss+0x0000000000000004 0000000000000025 R_X86_64_PC32     .data+0x0000000000000004 000000000000002b R_X86_64_PC32     .bss+0x0000000000000004 000000000000005b R_X86_64_REX_GOTPCRELX  global_var-0x0000000000000004 0000000000000067 R_X86_64_PC32     .bss-0x0000000000000004 

这里重定位类型中的GOT指示全局偏移量表英语Global Offset Table

反汇编并提取其中的main函数部份:

$ objdump -d -r -M intel  test.o | grep '<main>' -A12 

结果为:

0000000000000050 <main>:   50:	f3 0f 1e fa          	endbr64   54:	55                   	push   rbp   55:	48 89 e5             	mov    rbp,rsp   58:	48 8b 05 00 00 00 00 	mov    rax,QWORD PTR [rip+0x0]        # 5f <main+0xf> 			5b: R_X86_64_REX_GOTPCRELX	global_var-0x4   5f:	c7 00 01 00 00 00    	mov    DWORD PTR [rax],0x1   65:	c7 05 00 00 00 00 02 	mov    DWORD PTR [rip+0x0],0x2        # 6f <main+0x1f>   6c:	00 00 00  			67: R_X86_64_PC32	.bss-0x4   6f:	b8 00 00 00 00       	mov    eax,0x0   74:	5d                   	pop    rbp   75:	c3                   	ret 

将上述目标文件链接共享库

$ gcc -shared -o test.so test.o 

接着查看GOT节的位置及其内容:

$ objdump -s -j.got test.so 

结果为:

test.so:     file format elf64-x86-64  Contents of section .got:  3fc0 00000000 00000000 00000000 00000000  ................  3fd0 00000000 00000000 00000000 00000000  ................  3fe0 00000000 00000000                    ........ 

这里的全局偏移量表的位置在0x00003fc0,它有5个项目并且其内容在未运行时都为空。

反汇编并提取其中的main函数部份:

$ objdump -d -M intel test.so | grep '<main>' -A10 

结果为:

0000000000001149 <main>:     1149:	f3 0f 1e fa          	endbr64     114d:	55                   	push   rbp     114e:	48 89 e5             	mov    rbp,rsp     1151:	48 8b 05 68 2e 00 00 	mov    rax,QWORD PTR [rip+0x2e68]        # 3fc0 <global_var-0x58>     1158:	c7 00 01 00 00 00    	mov    DWORD PTR [rax],0x1     115e:	c7 05 b4 2e 00 00 02 	mov    DWORD PTR [rip+0x2eb4],0x2        # 401c <static_var>     1165:	00 00 00      1168:	b8 00 00 00 00       	mov    eax,0x0     116d:	5d                   	pop    rbp     116e:	c3                   	ret 

这里的0x1151+0x07+0x00002e68得到0x00003fc0,它是全局偏移量表的第一个项目的地址。

接着查看动态重定位记录:

$ objdump -R test.so 

结果为:

test.so:     file format elf64-x86-64  DYNAMIC RELOCATION RECORDS OFFSET           TYPE              VALUE 0000000000003e60 R_X86_64_RELATIVE  *ABS*+0x00000000000010f0 0000000000003e68 R_X86_64_RELATIVE  *ABS*+0x00000000000010b0 0000000000004000 R_X86_64_RELATIVE  *ABS*+0x0000000000004000 0000000000003fc0 R_X86_64_GLOB_DAT  global_var 0000000000003fc8 R_X86_64_GLOB_DAT  __cxa_finalize 0000000000003fd0 R_X86_64_GLOB_DAT  _ITM_registerTMCloneTable 0000000000003fd8 R_X86_64_GLOB_DAT  _ITM_deregisterTMCloneTable 0000000000003fe0 R_X86_64_GLOB_DAT  __gmon_start__ 

这里指定了GOT表项目对应的动态符号。这里的处在0x00003fc0的全局偏移量表的第一个项目,在运行时需要重定位为global_var的实际地址。

接着查看动态符号表:

$ objdump -T test.so 

结果为:

test.so:     file format elf64-x86-64  DYNAMIC SYMBOL TABLE: 0000000000000000  w   D  *UND*	0000000000000000 __cxa_finalize 0000000000000000  w   D  *UND*	0000000000000000 _ITM_registerTMCloneTable 0000000000000000  w   D  *UND*	0000000000000000 _ITM_deregisterTMCloneTable 0000000000000000  w   D  *UND*	0000000000000000 __gmon_start__ 000000000000112c g    DF .text	0000000000000012 global_function2 000000000000113e g    DF .text	000000000000000b non_mangled_function 0000000000004008 g    DO .data	0000000000000004 global_var_init 0000000000001149 g    DF .text	0000000000000026 main 0000000000001108 g    DF .text	0000000000000024 global_function 0000000000004018 g    DO .bss	0000000000000004 global_var 

这里指定了实际地址对应的动态符号。这里的global_var的地址是0x0000000000004018

接着执行如下命令:

$ objdump -t test.so | grep 'global_var$' 

从符号表中检视global_var的实际地址:

0000000000004018 g     O .bss	0000000000000004 global_var 

动态符号表中global_var的地址也是这个地址。

参见

[编辑]

外部链接

[编辑]