ELF¶
更新于2023-11-24
可执行可链接格式(executable and linkable format, ELF)
使用ELF格式的文件¶
- 可执行文件
- 可重定位文件(Relocatable File),
.o - 共享对象文件(Shared Object File),
.so .a - coredump
组成¶
- ELF头
- 程序头表,描述若干个内存段
- 节头表,描述若干个节
- data entries
- 符号
- 重定位
- 动态链接
- 编码ELF解释器
- 重定向入口
- 数据动态链接信息
ELF头¶
ELF头(ELF Header)是每个ELF文件的第一个部分,包含了文件的基本信息和控制信息。它的结构定义了文件的类型、目标架构、入口点地址、程序头表和节头表的位置和大小等。
ELF头结构¶
ELF头的结构如下:
- e_ident:一个16字节的数组,包含魔数、文件类型、目标架构等信息。
- e_type:文件类型,如可执行文件、重定位文件、共享对象文件等。
- e_machine:目标架构,如x86、x86-64、ARM等。
- e_version:ELF版本。
- e_entry:程序入口点的虚拟地址。
- e_phoff:程序头表在文件中的偏移。
- e_shoff:节头表在文件中的偏移。
- e_flags:与处理器相关的标志。
- e_ehsize:ELF头的大小。
- e_phentsize:程序头表中每个条目的大小。
- e_phnum:程序头表中的条目数。
- e_shentsize:节头表中每个条目的大小。
- e_shnum:节头表中的条目数。
- e_shstrndx:节头字符串表的索引。
示例¶
以下是一个简单的ELF头表示例:
| Bash | |
|---|---|
1 | |
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
程序头¶
程序头表(Program Header Table)描述了一个可执行文件或共享对象文件的内存布局。每个程序头条目(Program Header Entry)定义了一个段(Segment),包括段的类型、文件中的位置、内存中的位置、大小、权限等信息。程序头表在程序加载时被操作系统用来将文件中的各个段映射到内存中。
程序头条目类型¶
常见的程序头条目类型包括:
- PT_NULL:无效的条目
- PT_LOAD:可加载段
- PT_DYNAMIC:动态链接信息
- PT_INTERP:解释器路径
- PT_NOTE:附加信息
- PT_SHLIB:保留类型
- PT_PHDR:程序头表自身
- PT_TLS:线程局部存储段
示例¶
以下是一个简单的程序头表示例:
| Bash | |
|---|---|
1 | |
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
节头¶
符号¶
重定位¶
动态链接¶
编码ELF解释器¶

| 名字 | 类型 | 说明 |
|---|---|---|
| NULL | ||
| .interp | PROGBITS | |
| .note.gnu.pr[...] | NOTE | |
| .note.gnu.bu[...] | NOTE | |
| .note.ABI-tag | NOTE | |
| .gnu.hash | GNU_HASH | |
| .dynsym | DYNSYM | |
| .dynstr | STRTAB | |
| .gnu.version | VERSYM | |
| .gnu.version_r | VERNEED | |
| .rela.dyn | RELA | |
| .rela.plt | RELA | |
| .init | PROGBITS | |
| .plt | PROGBITS | 过程链接表 |
| .plt.got | PROGBITS | |
| .plt.sec | PROGBITS | |
| .text | PROGBITS | 程序代码指令 |
| .fini | PROGBITS | |
| .rodata | PROGBITS | 只读数据 |
| .eh_frame_hdr | PROGBITS | |
| .eh_frame | PROGBITS | |
| .init_array | INIT_ARRAY | |
| .fini_array | FINI_ARRAY | |
| .dynamic | DYNAMIC | |
| .got | PROGBITS | |
| .data | PROGBITS | 已经初始化的全局变量和静态变量 |
| .bss | NOBITS | 未初始化或初始化为0的全局变量和静态变量 |
| .comment | PROGBITS | |
| .symtab | SYMTAB | |
| .strtab | STRTAB | 一个符号表存放程序中定义和引用的函数和全局变量信息;不包含局部变量信息 |
| .shstrtab | STRTAB | |
| .debug | 调试符号表;通过-g添加 |
|
| .rel.text | .text节中位置的列表;链接时,需要将修改这些位置 | |
| .rel.data | 被模块引用和定义的所有全局变量的重定位信息 | |
| .line | 源程序的行号和.text节中机器指令之间的映射,通过-g添加 |
|
| strtab | 字符串表;包含.symtab和.debug节中的符号表 | |
| .ctors | 指向构造函数的指针 | |
| .dtors | 指向析构函数的指针 |
text段¶
.txt .rodata .hash .dynsym .dynstr .plt .rel.got
data段¶
.data .dybanic .got.plt .bss
| Bash | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 | |
符号¶
- 模块定义被其他模块引用的全局符号。非静态函数和全局变量。
- 模块引用其他模块定义的全局符号,这些符号也叫
外部符号。其他模块的非静态函数和全局变量。 - 模块内定义和引用的局部符号。static属性的函数和全局变量。
符号表¶
.systab节中包含ELF符号表