ELF 文件结构详解

ELF(Executable and Linkable Format)是类 Unix 系统(如 Linux)广泛使用的一种可执行文件格式。它用于存储可执行文件、目标代码、共享库和核心转储(core dump)。本篇文档将详细介绍 ELF 文件的整体结构、各个部分的作用,以及如何解析 ELF 文件。

一、ELF 文件类型

ELF 文件按照用途可分为:

  • 可重定位文件(Relocatable):例如 .o 目标文件。
  • 可执行文件(Executable):例如程序的可执行文件。
  • 共享目标文件(Shared Object):例如 .so 动态链接库。
  • 核心转储文件(Core Dump):程序崩溃时的内存快照。

二、ELF 文件结构概览

一个 ELF 文件的基本结构如下:

+------------------+
| ELF Header       |
+------------------+
| Program Header   | --> 用于运行时的程序装载
+------------------+
| Section Header   | --> 用于链接器定位代码/数据段
+------------------+
| Segments         |
| (.text/.data etc)|
+------------------+
| Sections         |
| (.symtab/.strtab)|
+------------------+

三、ELF Header(文件头)

这是 ELF 文件的起点,占据 64 字节(在 ELF64 下)。描述整个文件的信息,如类型、架构、入口地址等。

主要字段:

字段 含义
e_ident[16] 魔数、类(32/64位)、字节序等信息
e_type 文件类型(如可执行、共享库等)
e_machine 架构类型(如 x86, ARM, AArch64)
e_version 版本号
e_entry 程序入口地址(如 main 的起始地址)
e_phoff 程序头表偏移(Program Header)
e_shoff 节区头表偏移(Section Header)
e_flags 与平台相关的标志
e_ehsize ELF Header 大小

四、Program Header Table(程序头表)

用于运行时装载程序信息,由操作系统使用,不一定包含所有 section。

每个 Program Header 表项描述了一个 segment,如 .text.data 等在内存中的位置。

关键字段:

字段 含义
p_type segment 类型(LOAD/DYNAMIC/INTERP)
p_offset segment 在文件中的偏移
p_vaddr segment 在内存中的虚拟地址
p_paddr 物理地址(大多数情况未使用)
p_filesz 文件中 segment 大小
p_memsz 运行时 segment 占用内存大小
p_flags 读写执行权限(R/W/X)
p_align 对齐值

五、Section Header Table(节区头表)

主要用于链接器,对应 .text.data.bss.symtab 等节。每个 Section 表项包含一个节的详细信息。

常见节区(Section):

节区名 用途
.text 代码段(只读、可执行)
.data 已初始化的数据段
.bss 未初始化的数据段
.rodata 只读数据段,如字符串常量
.symtab 符号表(包含函数、变量的符号信息)
.strtab 字符串表(为符号名提供字符串)
.rela.text 重定位信息(带显式 addend 的重定位表)
.dynsym 动态符号表(用于动态链接)

六、符号表(Symbol Table)

ELF 中的 .symtab.dynsym 保存函数/变量等符号信息。

一个符号表项包含:

字段 含义
st_name 字符串表中的偏移,指向符号名
st_value 符号的值(地址或偏移)
st_size 符号的大小
st_info 符号类型和绑定(局部、全局等)
st_other 可见性
st_shndx 该符号所在的节的索引

七、重定位表(Relocation Table)

用于链接时或运行时修改目标地址(尤其在动态链接中)。常见节:

  • .rel.text:不带显式 addend。
  • .rela.text:带显式 addend(常用于 64 位系统)。

每个重定位表项通常包含:

  • 重定位偏移地址
  • 所引用的符号
  • 重定位类型(如 R_X86_64_PC32, R_ARM_JUMP24

八、动态链接信息(.dynamic、.got、.plt)

  • .dynamic:动态链接所需的信息表,如依赖库名、符号表位置等。
  • .got(Global Offset Table):用于保存外部符号地址。
  • .plt(Procedure Linkage Table):用于延迟解析函数地址。

九、ELF 文件分析工具

以下是常用的 ELF 分析工具:

工具 用途
readelf -a 查看所有 ELF 结构
objdump -d 反汇编 ELF
nm 查看符号表
file 简要查看文件类型
hexdump 查看二进制内容
gdb 调试可执行文件

十、示意图:ELF64 文件头(前 64 字节)

+------------------+ 0x00
| e_ident[16]      | --> 魔数, 文件类型
+------------------+ 0x10
| e_type           |
| e_machine        |
| e_version        |
| e_entry          |
+------------------+ 0x18
| e_phoff          | --> 程序头偏移
| e_shoff          | --> 节区头偏移
+------------------+

你可能感兴趣的:(ELF 文件结构详解)