ELF格式式简介
ELF,即Executable and Linkable Format,是类Unix上的二进制文件格式标准。运行在类Unix系统上的二进制可执行文件大部分为这种格式。一个ELF格式文件由文件头ELF header,段Segments和节Sections组成。文件头描述了文件大小,各部分大小与位置,目标平台等关键信息。Segements为加载时视图,为加载器Loader将程序加载到内存的过程提供信息。Sections为链接时视图,链接器Linker通过Sections中的信息对目标文件进行链接与重定位等操作。<–!more–>
使用readelf命令查看ELF文件信息
readelf常用参数
-a –all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I.
-h –file-header 显示elf文件开始的文件头信息.
-l –program-headers –segments 显示程序头(段头)信息(如果有的话)。
-S –section-headers –sections 显示节头信息(如果有的话)。
-t –section-details 显示节的详细信息(-S的)。
-s –syms –symbols 显示符号表段中的项(如果有的话)。
-e –headers 显示全部头信息,等价于: -h -l -S
-r –relocs 显示可重定位段的信息。
-d –dynamic 显示动态段的信息。
使用010Editor查看ELF文件信息
节sections
需要关注的几个sections
.text 代码段,一般为R_X
.data 数据段,一般为RW_
.rodata 只读数据段,一般为R__
.bss 未初始化数据段,一般为RW_,在stack pivot和伪造堆chunk时经常用到
.got.plt 全局函数偏移表,未开启full_relro时为RW_,可以通过改写表项劫持函数
.plt 过程链接表,一般为R_X,存放了外部函数绑定的stub代码,理解了函数延迟绑定机制可以使用ret2dl-resolve技术调用关键函数
.dynsym与.dynstr,动态链接符号与动态链接字符串,与函数绑定相关
.init与.init.array,程序的真正入口点,许多ELF壳会在这里做手脚
段SEGMENTS
Loader不关心ELF文件怎么运行,只关心怎么把ELF文件装载进内存
通过将访问属性(RWX)相同的sections集合成一个segments,可以方便高效地将文件映射进内存中,减少页面内部碎片,节省内存空间。