readelf 与 ELF 文件格式分析
ELF 格式
可执行与可链接格式(英语:Executable and Linkable Format,缩写为 ELF),常被称为 ELF 格式,在计算机科学中,是一种用于可执行文件、目标文件、共享库和核心转储的标准文件格式。
可以通过 ELF 格式读取 ELF 文件的一些信息。
ELF 文件类型:
- 可重定位的对象文件 (Relocatable file)
由汇编器汇编生成的 .o 文件
- 可执行的对象文件 (Executable file)
可执行应用程序
- 可被共享的对象文件 (Shared object file)
动态库文件,也即 .so 文件
ELF 文件组成:
- ELF 头(ELF header)
- 程序标头表(Program header table)
- Section 标头表(Section header table):链接与重定义需要的数据
- 程序标头与 Section 标头需要的数据:.text(可执行代码),.data(被初始化的数据),.bss(未初始化的数据),.symtab 或 .dynsym(符号信息),strtab 或 dynstr(字符串信息)等
实际的 ELF 文件不一定如下图所示的包含其中的信息和位置顺序。
只有 ELF 头的位置是固定的,其它信息包含在 ELF 头中。
ELF 头(ELF header)
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT]; // 开头 3 个字节固定不变,为 0x7F, 'E', 'L', 'F',其它是与机器无关的信息
Elf32_Half e_type; // 标识该文件的类型
Elf32_Half e_machine; // 运行该程序需要的体系结构
Elf32_Word e_version; // 文件的版本
Elf32_Addr e_entry; // 程序的入口地址
Elf32_Off e_phoff; // Program header table 在文件中的偏移量(以字节计数)
Elf32_Off e_shoff; // Section header table 在文件中的偏移量(以字节计数)
Elf32_Word e_flags; // 其它
Elf32_Half e_ehsize; // ELF header 大小(以字节计数)
Elf32_Half e_phentsize; // Program header table 中每一个条目的大小
Elf32_Half e_phnum; // Program header table 中条目数量
Elf32_Half e_shentsize; // Section header table 中的每一个条目的大小
Elf32_Half e_shnum; // Section header table 中条目数量
Elf32_Half e_shstrndx; // 包含节名称的字符串是第几个节(从零开始计数)
} Elf32_Ehdr;
数据类型说明:
数据类型 | 大小 | 对齐 | 用途 |
---|---|---|---|
Elf32_Addr | 4 | 4 | 无符号程序地址 |
Elf32_Half | 2 | 2 | 无符号中等大小整数 |
Elf32_Off | 4 | 4 | 无符号文件偏移 |
Elf32_Sword | 4 | 4 | 有符号大整数 |
Elf32_Word | 4 | 4 | 无符号大整数 |
unsigned char | 1 | 1 | 无符号小整数 |
程序标头
Program header 描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大小。
typedef struct {
Elf32_Word p_type; // 当前 Program header 所描述的段的类型
Elf32_Off p_offset; // 第一个字节在文件中的偏移
Elf32_Addr p_vaddr; // 一个字节在内存中的虚拟地址
Elf32_Addr p_paddr; // 在物理内存定位相关的系统中,此项是为物理地址保留
Elf32_Word p_filesz;