ELF文件头部是 ELF 文件的元数据核心,位于文件起始位置(前 64 字节)。它定义了文件的基本属性、目标架构和关键数据结构的位置。以下是使用 readelf -h 分析 64 位 "hello world" 可执行文件的示例输出及逐字段解析:
ELF头部输出 (readelf -h hello)
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: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x401040
Start of program headers: 64 (bytes into file)
Start of section headers: 14216 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
ELF 头部内存布局(64字节)
0-3: 7F 45 4C 46 // Magic
4: 02 // ELF64
5: 01 // Little Endian
6: 01 // ELF Version
7: 00 // OS/ABI
8-15: 00 00 00 00 00 00 00 00 // Padding
16-17: 02 00 // e_type (ET_EXEC)
18-19: 3E 00 // e_machine (EM_X86_64)
20-23: 01 00 00 00 // e_version
24-31: 40 10 40 00 00 00 00 00 // e_entry (0x401040)
32-39: 40 00 00 00 00 00 00 00 // e_phoff (64)
40-47: 88 37 00 00 00 00 00 00 // e_shoff (14216)
48-51: 00 00 00 00 // e_flags
52-53: 40 00 // e_ehsize (64)
54-55: 38 00 // e_phentsize (56)
56-57: 0D 00 // e_phnum (13)
58-59: 40 00 // e_shentsize (64)
60-61: 1E 00 // e_shnum (30)
62-63: 1D 00 // e_shstrndx (29)
字段详解(64位系统)
字段 | 值(示例) | 说明 |
---|---|---|
e_ident[EI_MAG0:EI_MAG3] | 7f 45 4c 46 | 魔数标识:固定字节 0x7F + ELF 的 ASCII 码 |
e_ident[EI_CLASS] | 02 | 文件类:02 = ELF64(64位架构) |
e_ident[EI_DATA] | 01 | 字节序:01 = Little Endian(小端) |
e_ident[EI_VERSION] | 01 | ELF 版本:固定为 1 (EV_CURRENT) |
e_ident[EI_OSABI] | 00 | OS/ABI:00 = UNIX System V |
e_ident[EI_ABIVERSION] | 00 | ABI 版本:通常为 0 |
e_type | 0x0002 | 文件类型:2 = ET_EXEC(可执行文件) |
e_machine | 0x003e | 目标架构:62 = EM_X86_64(x86-64) |
e_version | 0x00000001 | ELF 版本:与 e_ident[EI_VERSION] 一致 |
e_entry | 0x401040 | 入口地址:程序第一条指令的虚拟地址(_start ) |
e_phoff | 64 | 程序头表偏移:距文件起始 64 字节处 |
e_shoff | 14216 | 节头表偏移:距文件起始 14216 字节处 |
e_flags | 0x0 | 处理器标志:x86-64 通常为 0 |
e_ehsize | 64 | ELF 头大小:固定 64 字节 |
e_phentsize | 56 | 程序头大小:每个程序头条目占 56 字节 |
e_phnum | 13 | 程序头数量:共 13 个程序头(如 LOAD、INTERP) |
e_shentsize | 64 | 节头大小:每个节头条目占 64 字节 |
e_shnum | 30 | 节头数量:共 30 个节头(如 .text、.data) |
e_shstrndx | 29 | 节名字符串表索引:第 29 个节头是 .shstrtab |
字段的意义
1.Entry point address(入口点地址)
e_entry (0x401040)
程序的入口地址,指向 _start 函数(由 glibc 提供)。
_start 初始化环境后调用 main(),通过 objdump -d hello 可验证:
assembly
401040 <_start>:
401040: f3 0f 1e fa endbr64
401044: 31 ed xor %ebp,%ebp
...
2.Start of program headers(程序头表起始偏移)
e_phoff (64)
程序头表紧跟在 ELF 头后,用于加载器映射程序到内存。
查看程序头:readelf -l hello → 显示 13 个条目(如 LOAD、INTERP、DYNAMIC)。
3.Start of section headers(节头表起始偏移)
e_shoff (14216)
节头表位于文件末尾,用于链接和调试。
查看节头:readelf -S hello → 显示 30 个节(如 .text、.rodata、.data)。
4.Section header string table index(节头字符串表索引)
e_shstrndx(29)
第 29 项是 .shstrtab 节,存储所有节名称的字符串。