一,简介
本文主要介绍什么是elf文件,以及查看elf文件内部信息的常用命令。
二,ELF文件介绍
ELF(Executable and Linkable Format) 文件是一种二进制文件格式,用于表示可执行程序、共享库和核心转储文件。
ELF文件格式最初由UNIX系统的继承者之一——UNIX System V Release 4(SVR4)引入,并被广泛应用于各种UNIX和类UNIX系统,包括Linux、FreeBSD、Solaris以及macOS(在macOS 10.6之前)。
2.1 ELF文件格式的主要特点
ELF文件格式的主要特点包括:
- 灵活性和可扩展性: ELF设计得非常灵活,允许添加新的段、段类型、程序头、段头和其他字段,而不会破坏向后兼容性。
- 类型和架构无关性: ELF格式可以表示多种不同的CPU架构和操作系统。这意味着同一个ELF文件可以在不同的架构和操作系统上运行,只要它们都支持相同的ABI(Application Binary Interface)。
- 可执行和链接: ELF文件既可以被当作可执行文件来运行,也可以被当作共享库与其他程序链接。
ELF文件通常分为两个部分:
- 文件头(ELF header): 位于文件的开头,包含文件的基本信息,如文件类型、架构、操作系统ABI等。
- 段(Segments): 包含用于程序执行的数据,如代码、数据和资源。每个段都有一个段头,描述了段的大小、位置和类型。
ELF文件格式还包含一个或多个程序头表(Program Header Table),它定义了程序在内存中的布局。程序头表包含了加载段、动态段等信息,这对于动态链接和加载器非常重要。
在Linux系统中,常见的工具如objdump、readelf、file可以用来查看和分析ELF文件的内容。ld(Linker)用于链接程序,as(Assembler)用于将汇编代码转换为机器代码,gcc(GNU Compiler Collection)是一个编译器套件,用于将不同的源代码编译为可执行文件。
三,常用命令汇总
objdump:
命令 | 功能介绍 |
---|---|
objdump -h SimpleSection.o | 打印elf文件各段的基本信息 |
objdump -x SimpleSection.o | 把elf文件更多的信息打印出来 |
size SimpleSection.o | 查看代码段,数据段,bss段长度 |
objdump -s -d SimpleSection.o | 分析代码段的内容。-s 把所有参数以16进制打印出来,-d 所有包含指令的段反汇编 |
objdump -r SimpleSection.o | 查看elf文件中要重定位的地方,即elf文件中所有引用到外部符号的地址 |
readelf:
命令 | 功能介绍 |
---|---|
readelf -h SimpleSection.o | 查看elf文件头 |
readelf -S SimpleSection.o | 查看elf文件段,它显示的结果才是真正的段表结构 |
readelf -s SimpleSection.o | 查看elf文件的符号 |
readelf -h SimpleSection.o | 查看elf文件头 |
nm:
命令 | 功能介绍 |
---|---|
nm SimpleSection.o | 查看elf符号表 |
四,命令使用示例
本章节以SimpleSection.c为例,在linux环境下执行常用命令查看效果。
SimpleSection.c:
int printf(const char *format, ...);
int global_init_var = 84;
int global_uninit_var;
void func1(int i)
{
printf("%d\n", i);
}
int main()
{
static int static_var = 85;
static int static_var2;
int a = 1;
int b;
func1(static_var + static_var2 + a + b);
return a;
}
使用gcc命令编译成.o文件:
gcc -c SimpleSection.c
4.1 objdump -h SimpleSection.o
objdump -h SimpleSection.o
SimpleSection.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000055 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 00000036 0000000000000000 0000000000000000 000000a4 2**0
CONTENTS, READONLY
5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000da 2**0
CONTENTS, READONLY
6 .eh_frame 00000058 0000000000000000 0000000000000000 000000e0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
4.2 size SimpleSection.o
text data bss dec hex filename
177 8 4 189 bd SimpleSection.o
4.3 objdump -s -d SimpleSection.o
显示信息太多就不贴了。。。
4.4 objdump -r SimpleSection.o
SimpleSection.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
4.5 readelf -h SimpleSection.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: 1072 (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
4.6 readelf -S SimpleSection.o
There are 13 section headers, starting at offset 0x430:
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
0000000000000055 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000320
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
0000000000000036 0000000000000001 MS 0 0 1
[ 7] .note.GNU-stack PROGBITS 0000000000000000 000000da
0000000000000000 0000000000000000 0 0 1
[ 8] .eh_frame PROGBITS 0000000000000000 000000e0
0000000000000058 0000000000000000 A 0 0 8
[ 9] .rela.eh_frame RELA 0000000000000000 00000398
0000000000000030 0000000000000018 I 11 8 8
[10] .shstrtab STRTAB 0000000000000000 000003c8
0000000000000061 0000000000000000 0 0 1
[11] .symtab SYMTAB 0000000000000000 00000138
0000000000000180 0000000000000018 12 11 8
[12] .strtab STRTAB 0000000000000000 000002b8
0000000000000066 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)
4.7 readelf -s SimpleSection.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 SimpleSection.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 static_var.1839
7: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 static_var2.1840
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 global_init_var
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM global_uninit_var
13: 0000000000000000 34 FUNC GLOBAL DEFAULT 1 func1
14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
15: 0000000000000022 51 FUNC GLOBAL DEFAULT 1 main
4.8 readelf -h SimpleSection.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: 1072 (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
五,总结
本文主要讲了elf文件的常用命令,供参考。欢迎一起讨论交流~