欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

readelf 和 objdump 例子详解及区别

程序员文章站 2022-07-01 23:26:28
...

这里以 simple.c 的目标文件为例子说明

#include<stdio.h>

int g_init_var = 100;
int g_uinit_var;

void func1(int i)
{
	printf("%d\n",i);
}

int main()
{
	static int iStaticVar = 101;
	static int iStaticVar2;
	
	int a = 1;
	int b;
	func1(iStaticVar + iStaticVar2 + a + b);
	return 0;
}

1. readelf - 查看elf文件的信息

readelf - Displays information about ELF files.
readelf 只能看elf文件的信息

1. readelf 命令+代码例子详解

1.1 readelf -s simple.o //–symbols 显示符号表段中的项

–syms --symbols
显示符号表段中的项

[email protected]:/home# readelf -s simple.o

Symbol table '.symtab' contains 16 entries:
Num:    Value          Size Type    Bind   Vis      Ndx Name
	0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS simple.c
	2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
	3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
	4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
	5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
	6: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    3 iStaticVar.2290
	7: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 iStaticVar2.2291
	8: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
	9: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
	10: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
	11: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 g_init_var
	12: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM g_uinit_var
	13: 0000000000000000    34 FUNC    GLOBAL DEFAULT    1 func1
	14: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
	15: 0000000000000022    53 FUNC    GLOBAL DEFAULT    1 main
[email protected]:/home#

1.2 readelf -h simple.o //显示elf文件开始的文件头信息.

-h :–file-header
显示elf文件开始的文件头信息.

[email protected]:/home# readelf -h simple.o
ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              REL (Relocatable file)
Machine:                           Advanced Micro Devices X86-64
Version:                           0x1
Entry point address:               0x0
Start of program headers:          0 (bytes into file)
Start of section headers:          1056 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           0 (bytes)
Number of program headers:         0
Size of section headers:           64 (bytes)
Number of section headers:         13
Section header string table index: 10
[email protected]:/home# 

1.3 readelf -S simple.o //显示节头信息

–section-headers ;–sections 显示节头信息(如果有的话)。

[email protected]:/home# readelf -S simple.o
There are 13 section headers, starting at offset 0x420:

Section Headers:
[Nr] Name              Type             Address           Offset
	Size              EntSize          Flags  Link  Info  Align
[ 0]                   NULL             0000000000000000  00000000
	0000000000000000  0000000000000000           0     0     0
[ 1] .text             PROGBITS         0000000000000000  00000040
	0000000000000057  0000000000000000  AX       0     0     1
[ 2] .rela.text        RELA             0000000000000000  00000310
	0000000000000078  0000000000000018   I      11     1     8
[ 3] .data             PROGBITS         0000000000000000  00000098
	0000000000000008  0000000000000000  WA       0     0     4
[ 4] .bss              NOBITS           0000000000000000  000000a0
	0000000000000004  0000000000000000  WA       0     0     4
[ 5] .rodata           PROGBITS         0000000000000000  000000a0
	0000000000000004  0000000000000000   A       0     0     1
[ 6] .comment          PROGBITS         0000000000000000  000000a4
	0000000000000035  0000000000000001  MS       0     0     1
[ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000d9
	0000000000000000  0000000000000000           0     0     1
[ 8] .eh_frame         PROGBITS         0000000000000000  000000e0
	0000000000000058  0000000000000000   A       0     0     8
[ 9] .rela.eh_frame    RELA             0000000000000000  00000388
	0000000000000030  0000000000000018   I      11     8     8
[10] .shstrtab         STRTAB           0000000000000000  000003b8
	0000000000000061  0000000000000000           0     0     1
[11] .symtab           SYMTAB           0000000000000000  00000138
	0000000000000180  0000000000000018          12    11     8
[12] .strtab           STRTAB           0000000000000000  000002b8
	0000000000000054  0000000000000000           0     0     1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
[email protected]:/home# 

1.4 readelf -a simple.o //elf显示全部信息

-a :–all
显示全部信息,等价于 -h -l -S -s -r -d -V -A -I

[email protected]:/home# readelf -a simple.o
ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              REL (Relocatable file)
Machine:                           Advanced Micro Devices X86-64
Version:                           0x1
Entry point address:               0x0
Start of program headers:          0 (bytes into file)
Start of section headers:          1056 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           0 (bytes)
Number of program headers:         0
Size of section headers:           64 (bytes)
Number of section headers:         13
Section header string table index: 10

Section Headers:
[Nr] Name              Type             Address           Offset
	Size              EntSize          Flags  Link  Info  Align
[ 0]                   NULL             0000000000000000  00000000
	0000000000000000  0000000000000000           0     0     0
[ 1] .text             PROGBITS         0000000000000000  00000040
	0000000000000057  0000000000000000  AX       0     0     1
[ 2] .rela.text        RELA             0000000000000000  00000310
	0000000000000078  0000000000000018   I      11     1     8
[ 3] .data             PROGBITS         0000000000000000  00000098
	0000000000000008  0000000000000000  WA       0     0     4
[ 4] .bss              NOBITS           0000000000000000  000000a0
	0000000000000004  0000000000000000  WA       0     0     4
[ 5] .rodata           PROGBITS         0000000000000000  000000a0
	0000000000000004  0000000000000000   A       0     0     1
[ 6] .comment          PROGBITS         0000000000000000  000000a4
	0000000000000035  0000000000000001  MS       0     0     1
[ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000d9
	0000000000000000  0000000000000000           0     0     1
[ 8] .eh_frame         PROGBITS         0000000000000000  000000e0
	0000000000000058  0000000000000000   A       0     0     8
[ 9] .rela.eh_frame    RELA             0000000000000000  00000388
	0000000000000030  0000000000000018   I      11     8     8
[10] .shstrtab         STRTAB           0000000000000000  000003b8
	0000000000000061  0000000000000000           0     0     1
[11] .symtab           SYMTAB           0000000000000000  00000138
	0000000000000180  0000000000000018          12    11     8
[12] .strtab           STRTAB           0000000000000000  000002b8
	0000000000000054  0000000000000000           0     0     1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

There are no program headers in this file.

Relocation section '.rela.text' at offset 0x310 contains 5 entries:
Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000011  00050000000a R_X86_64_32       0000000000000000 .rodata + 0
00000000001b  000e00000002 R_X86_64_PC32     0000000000000000 printf - 4
000000000033  000300000002 R_X86_64_PC32     0000000000000000 .data + 0
000000000039  000400000002 R_X86_64_PC32     0000000000000000 .bss - 4
00000000004c  000d00000002 R_X86_64_PC32     0000000000000000 func1 - 4

Relocation section '.rela.eh_frame' at offset 0x388 contains 2 entries:
Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
000000000040  000200000002 R_X86_64_PC32     0000000000000000 .text + 22

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 16 entries:
Num:    Value          Size Type    Bind   Vis      Ndx Name
	0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS simple.c
	2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
	3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
	4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
	5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
	6: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    3 iStaticVar.2290
	7: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 iStaticVar2.2291
	8: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
	9: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
	10: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
	11: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 g_init_var
	12: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM g_uinit_var
	13: 0000000000000000    34 FUNC    GLOBAL DEFAULT    1 func1
	14: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
	15: 0000000000000022    53 FUNC    GLOBAL DEFAULT    1 main

No version information found in this file.
[email protected]:/home#

2. objdump - 查看目标文件的信息

objdump - display information from object files.
objdump 可以看目标文件的信息

2. objdump 命令+代码例子详解

2.1 objdump -h simple.o //显示目标文件各个section的头部摘要信息

–section-headers --headers
显示目标文件各个section的头部摘要信息

[email protected]:/home# objdump -h simple.o
simple.o:     file format elf64-x86-64
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .text         00000057  0000000000000000  0000000000000000  00000040  2**0
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data         00000008  0000000000000000  0000000000000000  00000098  2**2
				CONTENTS, ALLOC, LOAD, DATA
2 .bss          00000004  0000000000000000  0000000000000000  000000a0  2**2
				ALLOC
3 .rodata       00000004  0000000000000000  0000000000000000  000000a0  2**0
				CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment      00000035  0000000000000000  0000000000000000  000000a4  2**0
				CONTENTS, READONLY
5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000d9  2**0
				CONTENTS, READONLY
6 .eh_frame     00000058  0000000000000000  0000000000000000  000000e0  2**3
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
[email protected]:/home# 

2.2 objdump -t simple.o //显示文件的符号表入口。

-t --syms
显示文件的符号表入口

[email protected]:/home# objdump -t simple.o
simple.o:     file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 simple.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000004 l     O .data	0000000000000004 iStaticVar.2290
0000000000000000 l     O .bss	0000000000000004 iStaticVar2.2291
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data	0000000000000004 g_init_var
0000000000000004       O *COM*	0000000000000004 g_uinit_var
0000000000000000 g     F .text	0000000000000022 func1
0000000000000000         *UND*	0000000000000000 printf
0000000000000022 g     F .text	0000000000000035 main
[email protected]:/home# 

2.2.1 objdump -t libc.a grep -w printf //查找 printf 在 libc.a 库的哪个目标文件

objdump -t libc.a grep -w printf //查找 printf 在 libc.a 库的哪个目标文件
libc.a 库里面包含了 1400多个目标文件。

	[email protected]:/home/4Chapter# objdump -t /usr/lib/x86_64-linux-gnu/libc.a | grep -w printf
	……
	printf.o:     file format elf64-x86-64
	0000000000000000 g     F .text	000000000000009e printf
	……
	[email protected]:/home/4Chapter# 

2.3 objdump -d simple.o //-d 参数看代码段反汇编结果

-d --disassemble
从objfile中反汇编那些特定指令机器码的section。

[email protected]:/home# objdump -d simple.o
simple.o:     file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <func1>:
0:	55                   	push   %rbp
1:	48 89 e5             	mov    %rsp,%rbp
4:	48 83 ec 10          	sub    $0x10,%rsp
8:	89 7d fc             	mov    %edi,-0x4(%rbp)
b:	8b 45 fc             	mov    -0x4(%rbp),%eax
e:	89 c6                	mov    %eax,%esi
10:	bf 00 00 00 00       	mov    $0x0,%edi
15:	b8 00 00 00 00       	mov    $0x0,%eax
1a:	e8 00 00 00 00       	callq  1f <func1+0x1f>
1f:	90                   	nop
20:	c9                   	leaveq 
21:	c3                   	retq   
0000000000000022 <main>:
22:	55                   	push   %rbp
23:	48 89 e5             	mov    %rsp,%rbp
26:	48 83 ec 10          	sub    $0x10,%rsp
2a:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%rbp)
31:	8b 15 00 00 00 00    	mov    0x0(%rip),%edx        # 37 <main+0x15>
37:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # 3d <main+0x1b>
3d:	01 c2                	add    %eax,%edx
3f:	8b 45 f8             	mov    -0x8(%rbp),%eax
42:	01 c2                	add    %eax,%edx
44:	8b 45 fc             	mov    -0x4(%rbp),%eax
47:	01 d0                	add    %edx,%eax
49:	89 c7                	mov    %eax,%edi
4b:	e8 00 00 00 00       	callq  50 <main+0x2e>
50:	b8 00 00 00 00       	mov    $0x0,%eax
55:	c9                   	leaveq 
56:	c3                   	retq   
[email protected]:/home# 

2.4 objdump -r simple.o //查看重定位表

-r --reloc
显示文件的重定位入口

[email protected]:/home# objdump -r simple.o
simple.o:     file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000011 R_X86_64_32       .rodata
000000000000001b R_X86_64_PC32     printf-0x0000000000000004
0000000000000033 R_X86_64_PC32     .data
0000000000000039 R_X86_64_PC32     .bss-0x0000000000000004
000000000000004c R_X86_64_PC32     func1-0x0000000000000004
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE 
0000000000000020 R_X86_64_PC32     .text
0000000000000040 R_X86_64_PC32     .text+0x0000000000000022
[email protected]:/home# 

2.5 objdump -f simple.o //显示objfile中每个文件的整体头部摘要信息

–file-headers
显示objfile中每个文件的整体头部摘要信息。

[email protected]:/home# objdump -f simple.o

simple.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000

[email protected]:/home#

2.6 objdump -s simple.o //显示指定section的完整内容

-s --full-contents
显示指定section的完整内容。默认所有的非空section都会被显示。

[email protected]:/home# objdump -s simple.o
simple.o:     file format elf64-x86-64
Contents of section .text:
0000 554889e5 4883ec10 897dfc8b 45fc89c6  UH..H....}..E...
0010 bf000000 00b80000 0000e800 00000090  ................
0020 c9c35548 89e54883 ec10c745 f8010000  ..UH..H....E....
0030 008b1500 0000008b 05000000 0001c28b  ................
0040 45f801c2 8b45fc01 d089c7e8 00000000  E....E..........
0050 b8000000 00c9c3                      .......         
Contents of section .data:
0000 64000000 65000000                    d...e...        
Contents of section .rodata:
0000 25640a00                             %d..            
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520352e  .GCC: (Ubuntu 5.
0010 342e302d 36756275 6e747531 7e31362e  4.0-6ubuntu1~16.
0020 30342e34 2920352e 342e3020 32303136  04.4) 5.4.0 2016
0030 30363039 00                          0609.           
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 01781001  .........zR..x..
0010 1b0c0708 90010000 1c000000 1c000000  ................
0020 00000000 22000000 00410e10 8602430d  ...."....A....C.
0030 065d0c07 08000000 1c000000 3c000000  .]..........<...
0040 00000000 35000000 00410e10 8602430d  ....5....A....C.
0050 06700c07 08000000                    .p......        
[email protected]:/home# 

2.7 objdump -x simple.o //显示所可用的头信息

-x --all-headers
显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。

[email protected]:/home# objdump -x simple.o
simple.o:     file format elf64-x86-64
simple.o
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .text         00000057  0000000000000000  0000000000000000  00000040  2**0
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data         00000008  0000000000000000  0000000000000000  00000098  2**2
				CONTENTS, ALLOC, LOAD, DATA
2 .bss          00000004  0000000000000000  0000000000000000  000000a0  2**2
				ALLOC
3 .rodata       00000004  0000000000000000  0000000000000000  000000a0  2**0
				CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment      00000035  0000000000000000  0000000000000000  000000a4  2**0
				CONTENTS, READONLY
5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000d9  2**0
				CONTENTS, READONLY
6 .eh_frame     00000058  0000000000000000  0000000000000000  000000e0  2**3
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 simple.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000004 l     O .data	0000000000000004 iStaticVar.2290
0000000000000000 l     O .bss	0000000000000004 iStaticVar2.2291
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data	0000000000000004 g_init_var
0000000000000004       O *COM*	0000000000000004 g_uinit_var
0000000000000000 g     F .text	0000000000000022 func1
0000000000000000         *UND*	0000000000000000 printf
0000000000000022 g     F .text	0000000000000035 main

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000011 R_X86_64_32       .rodata
000000000000001b R_X86_64_PC32     printf-0x0000000000000004
0000000000000033 R_X86_64_PC32     .data
0000000000000039 R_X86_64_PC32     .bss-0x0000000000000004
000000000000004c R_X86_64_PC32     func1-0x0000000000000004

RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE 
0000000000000020 R_X86_64_PC32     .text
0000000000000040 R_X86_64_PC32     .text+0x0000000000000022
[email protected]:/home# 

2.8 objdump -a simple.o //显示档案库的成员信息

-a --archive-headers
显示档案库的成员信息,类似ls -l将lib*.a的信息列出。

[email protected]:/home# objdump -a simple.o
simple.o:     file format elf64-x86-64
simple.o
[email protected]:/home# 

3. readelf 和 objdump 的区别

3.1 概念的区别

readelf 显示elf文件的信息
objdump 显示目标文件的信息

3.2 readelf 并不提供反汇编功能

objdump 提供反汇编功能

3.3 readelf 可以显示调试信息

objdump 则不能显示调试信息
但是实际上bfd库支持DWARF的处理,通过简单处理objdump也可以显示调试信息

3.4 objdump 使用了bfd库进行文件读取

BFD库(Binary File Descriptor Library),它是一个GNU项目
它的目标就是希望通过一种统一的接口来处理不同的目标文件格式。

而readelf则没有,另外写的一套代码,且对一些条件的判断并不是很严格