推荐y博士视频:ELF文件和链接
推荐博客:C语言的ELF文件格式学习
程序举例:
#include <stdio.h>
#include <stdlib.h>
int data[100] ={0};
int bss[100];
int main()
{
int i=0;
for(i=0; i<100; i++)
bss[i] = i;
printf("the bss[3]= %d\n", bss[3]);
return 0;
}
利用命令 readelf -h 读取生成的可执行文件
对应的我们可以打开man elf 查看
上述两图是相互对应的。
上述图片是elf文件格式的排布,我们能够看到程序头表以及Section头表,利用如下命令得到elf文件:
readelf -a 可执行文件 | vim -
我们这里不讨论程序头表,讨论section头表,section头表的初始位置以及每个表元素的大小以及个数在ELF_enhd结构体中都存在,可以解析出来。
例如我们此时解析出 symtab 以及 strtab中的初始地址以及大小,首先我们继续看文档,section header包含哪些信息:
首先sh_name为section序号
sh_type为section的总类:包括:SHT_NULL、SHT_PROGBITS、SHT_STRTAB、SHT_SYMTAB等,我们发现我们可以通过这个遍历这个参数得到我们要的表头,
sh_offeset: 该成员的值保存了从文件开始到section中第一个字节的字节偏移量。
sh_size:该成员以字节为单位保存了section的大小。
sh_entsize:有些section保存一个固定大小的表,比如符号表。对于这样的section,该成员给出每个条目的字节大小。如果section中没有固定大小的表,则该成员为0条目。
上述三个参数能够让我们对SYMTAB以及STRTAB两个表进行定位。
随后我们找到SYMTAB中带有TYPE为FUNC的符号头,通过相同的方法,遍历SYM,sym的头结构体如下所示:
要遍历的symtab如图所示: