ELF文件结构学习
三种类型
可重定位文件(Relocatable File)
包含了代码和数据,可以和其他目标文件链接生成一个可执行文件或共享目标文件。
可执行文件 (Executable File)
包含了可以直接执行的文件。
共享目标文件 (Shared Object File)
包含了用于链接的代码和数据,共分两种情况:
- 静态连接器将其他可重定位文件和共享目标文件链接起来,生成新的目标文件
- 动态链接器将多个共享目标文件与可执行文件结合,作为进程映像的一部分(当静态链接加载的文件不完善时)
加载和动态链接
静态链接
在程序运行时无需装入函数库,而是把需要用到的库函数的目标代码(二进制)从程序库中抽取出来,嵌入到程序的代码中动态链接
是指库函数的代码并不进入程序的代码中,程序在编译/链接阶段并不完成跟库函数的链接,而是把函数库的代码也交给用户,到启动程序 目标代码运行时才把程序库的代码也装入用户空间(并加以定位),再完成程序与库函数的连接。
特殊节区
名称 | 类型 | 属性 | 含义 |
---|---|---|---|
.bss | SHT_NOBITS | SHF_ALLOC+SHF_WRITE | 包含出现在程序的内存映像中的未初始化数据。程序开始执行,系统将把这些数据初始化为0 |
.comment | SHT_PROGBITS | 包含版本控制信息 | |
.data | SHT_PROGBITS | SHF_ALLOC+SHF_WRITE | 包含了初始化了的数据,将出现在程序的内存映像中 |
.dynamic | SHT_DYNAMIC | SHF_ALLOC | 包含了用于动态连接信息,节区的属性将包含SHF_ALLOC位,是否SHF_WRITE位被设置取决于处理器 |
.dynstr | SHT_STRTAB | SHF_ALLOC | 包含了用于动态连接的字符串,大多数情况下这些字符串代表了于符号表项相关的名称 |
.dynsym | SHT_DYNSYM | SHF_ALLOC | 包含了动态连接符号表 |
.got | SHT_PROGBITS | 包含了全局偏移表 | |
.hash | SHT_HASH | SHF_ALLOC | 包含了一个符号哈希表 |
.init | SHT_PROGBITS | SHF_ALLOC+SHF_EXECINSTR | 包含了可执行指令,是进程初始化代码的一部分。在主程序入口(main函数)之前执行这些代码。 |
.plt | SHT_PROGBITS | 包含了过程链接表 | |
.text | SHT_PROGBITS | SHF_ALLOC+SHF_EXECINSTR | 包含程序的可执行指令 |
.rel.dyn
和.rel.plt
.rel.dyn
用于变量重定位
.rel.plt
用于函数重定位,包含了链接C库的函数
例如:wirte
函数
r_offset
=0x401c
r_info
=0x807
.dynsym
包含了动态链接符号表
例如:.dynsym[8]
指向的就是write函数
.dynstr
包含了动态链接的字符串
该节以\x00
为结尾和开始,中间间隔的每个字符串也是以\x00
分隔
而Elf32_Sym[6]
指向的便是这里的内容。
Elf32_Sym[6]->st_name=0x4c(.dynsym + Elf32_Sym_size * num)
Symbol Table
符号表
符号表保存了程序实现或使用的所有(全局)变量
和函数
。
它的主要任务是将一个字符串和一个值关联起来。例如printf
符号表示printf函数在虚拟地址空间中的地址,该函数的绝对地址(程序运行时的地址)就存在于该地址上。
当然该符号也可能是一个未定义的符号,也就是在程序的源代码中没有声明而直接使用的某个函数。这类的引用必须在静态链接期间用其他目标模块或者库解决,或者是在加载期间通过加载动态链接来解决
ExecuTable
文件布局图
GOT
全局偏移表
全局偏移表用来将位置独立的地址计算重定向到绝对地址。
当在程序中引用某个共享库中的符号(函数)时,编译链接阶段并不知道这个符号(函数)的具体位置,只有等到动态链接器将所需要的共享库加载时进内存后,也就是在运行阶段,符号的地址才会最终确定。因此,需要有一个数据结构来保存符号的绝对地址,这就是GOT表的作用,GOT表中每项保存程序中引用其它符号的绝对地址。这样,程序就可以通过引用GOT表来获得某个符号的地址。
如图片中的offset printf
只是在程序中的虚拟地址,当程序在加载相应的函数库时只用将虚拟地址+基地址
便等于绝对地址,也就是真实可用地址。
PLT
过程链接表
过程链接表用于把位置无关的函数调用重定向到绝对地址。
然后通过引用GOT表中的函数的绝对地址,来把控制转移到实际的函数。