1.ELF符号
符号是对某些类型的数据或者代码(全局变量、函数等)的符号引用,例如printf函数会在动态符号表.dynsym中存有一个指向该函数的符号条目。
.dynsym保存了引用来自外部文件符号的全局符号,.symtab中还保存了可执行文件的本地符号,如全局变量等,.dynsym保存的符号是.symtab保存的符号的子集。
.dynsym在程序运行时会被分配并装载进内存,主要用于动态链接可执行文件的执行。而.symtab则不会,它主要用来进行调试和链接的。
ELF文件符号项的结构体如下:
typedef struct {
uint32_t st_name; //保存了指向符号表中字符串表的偏移地址(.dynstr或.strtab)
unsigned char st_info; //制定符号类型及绑定属性
unsigned char st_other; //定义符号的可见性
uint16_t st_shndx; //每个符号表的条目的定义都与某些节对应,该变量保存了相关节头表的索引
Elf64_Addr st_value; //存放符号的值(地址或者位置偏移量)
uint64_t st_size; //存放符号的大小
} Elf64_Sym;
这里我们可以观察一个实例:
1.1.symtab符号表分析
首先用readelf -S查看节信息:
[29] .symtab SYMTAB 0000000000000000 00001070
0000000000000648 0000000000000018 30 47 8
[30] .strtab STRTAB 0000000000000000 000016b8
0000000000000216 0000000000000000 0 0 1
然后再用hexedit来查看程序代码:
.symtab节:(这里没有从0x1070顶头截取,0x1310是第28项的起始)
00001310 01 00 00 00 04 00 F1 FF 00 00 00 00 00 00 00 00 ................
00001320 00 00 00 00 00 00 00 00 0C 00 00 00 01 00 15 00 ................
00001330 20 0E 60 00 00 00 00 00 00 00 00 00 00 00 00 00 .`.............
00001340 19 00 00 00 02 00 0E 00 60 04 40 00 00 00 00 00 ........`.@.....
00001350 00 00 00 00 00 00 00 00 1B 00 00 00 02 00 0E 00 ................
00001360 A0 04 40 00 00 00 00 00 00 00 00 00 00 00 00 00 ..@.............
00001370 2E 00 00 00 02 00 0E 00 E0 04 40 00 00 00 00 00 ..........@.....
.strtab节: