ELF文件格式
ELF文件格式
摘抄自CTF Wiki
ELF Header
:给出整个文件的组织情况
Program Header Table
:向系统描述如何创建进程,重定位文件不需要,但是用于生成进程的目标文件必须具有
Section
:包含了链接视图中要使用的大部分信息:如指令/数据/符号表/重定位信息等
Section Header Table
:包含了描述文件节区的信息,每个节区在表中都有一个表项,会给出节区名称、节区大小等信息
ELF Header
1 |
|
e_ident
占八个字节,每个字节作用如下
EI_MAG
magic头,表示是ELF文件
EI_CLASS
标识文件的类型
EI_DATA
表示文件的编码类型
e_type
e_machine
指定了当前文件可以运行的机器架构
e_version
标识目标文件的版本
e_entry
这一项为系统转交控制权给 ELF 中相应代码的虚拟地址。如果没有相关的入口项,则这一项为 0
e_phoff
这一项给出程序头部表在文件中的字节偏移(Program Header table OFFset)。如果文件中没有程序头部表,则为 0
e_shoff
这一项给出节头表在文件中的字节偏移( Section Header table OFFset )。如果文件中没有节头表,则为 0
e_flags
这一项给出文件中与特定处理器相关的标志,这些标志命名格式为EF_machine_flag
e_ehsize
给出 ELF 文件头部的字节长度(ELF Header Size)
e_phentsize
这一项给出程序头部表中每个表项的字节长度(Program Header ENTry SIZE)。每个表项的大小相同
e_phnum
这一项给出程序头部表的项数( Program Header entry NUMber )。因此,e_phnum
与 e_phentsize
的乘积即为程序头部表的字节长度。如果文件中没有程序头部表,则该项值为 0
e_shentsize
这一项给出节头的字节长度(Section Header ENTry SIZE)。一个节头是节头表中的一项;节头表中所有项占据的空间大小相同
e_shnum
这一项给出节头表中的项数(Section Header NUMber)。因此, e_shnum
与 e_shentsize
的乘积即为节头表的字节长度。如果文件中没有节头表,则该项值为 0
e_shstrndx
这一项给出节头表中与节名字符串表相关的表项的索引值(Section Header table InDeX related with section name STRing table)。如果文件中没有节名字符串表,则该项值为SHN_UNDEF
Program Header Table
Program Header Table 是一个结构体数组,每一个元素的类型是 Elf32_Phdr
,描述了一个段或者其它系统在准备程序执行时所需要的信息。其中,ELF 头中的 e_phentsize
和 e_phnum
指定了该数组每个元素的大小以及元素个数。一个目标文件的段包含一个或者多个节。
Elf32_Phdr
1 |
|
段的类型
p_flags
当系统为可加载的段创建内存镜像时,它会按照 p_flags 将段设置为对应的权限
其中,所有在 PF_MASKPROC 中的比特位都是被保留用于与处理器相关的语义信息
段的内容
一个段可能包括一到多个节区,但是这并不会影响程序的加载。尽管如此,我们也必须需要各种各样的数据来使得程序可以执行以及动态链接等等。下面会给出一般情况下的段的内容。对于不同的段来说,它的节的顺序以及所包含的节的个数有所不同。此外,与处理相关的约束可能会改变对应的段的结构。
程序头部的 PT_DYNAMIC 类型的元素指向 .dynamic 节。其中,got 表和 plt 表包含与地址无关的代码相关信息。尽管在这里给出的例子中,plt 节出现在代码段,但是对于不同的处理器来说,可能会有所变动。
.bss 节的类型为 SHT_NOBITS,这表明它在 ELF 文件中不占用空间,但是它却占用可执行文件的内存镜像的空间。通常情况下,没有被初始化的数据在段的尾部,因此,p_memsz
才会比 p_filesz
大
Section Header Table
在ELF文件尾部,用于定位ELF文件中的每个Section的具体位置
ELF Header
中的e_shoff
项给出了从文件开头到Section Header Table
的偏移,e_shnum
提供了Section Header Table
的项数,e_shentsize
提供了每一项的字节大小
Section Header Table是一个结构体数组,每个元素的类型是ELF32_shdr
ELF32_shdr
1 |
|
索引为0的节区头
特殊下标
系统保留在SHN_LORESERVE
到SHN_HIRESERVE
之间 (包含边界) 的索引值,这些值不在节头表中引用。也就是说,节头表不包含保留索引项。
sh_type
sh_flags
sh_flags
字段的每一个比特位都可以给出其相应的标记信息,其定义了对应的节区的内容是否可以被修改、被执行等信息。如果一个标志位被设置,则该位取值为 1,未定义的位都为 0
sh_link & sh_info
根据sh_type
改变