SectionHeaders:
[Nr]NameTypeAddrOffSizeESFlgLkInfAl
[7].strtabSTRTAB0000000000145800001e00001
|
+--------------++-----------------------+
VV|
000014502000000011000300006164642e630061|........add.c.a||
000014606464006d61696e00616e730074657374|dd.main.ans.test||
000014705f6461746100^^|_data.||
|||
|+-------------+|
|||
+---------------------+||
Symboltable'.symtab'contains10entries:|||
Num:ValueSizeTypeBindVisNdxName|||
5:000000000FILELOCALDEFAULTABS1|||
6:0010008422FUNCGLOBALDEFAULT17---+---+------------------+
7:00100000129FUNCGLOBALDEFAULT111||
8:00100120256OBJECTGLOBALDEFAULT316---+|
9:0010010032OBJECTGLOBALDEFAULT320-------+
一种解决方法已经呼之欲出了:要查找一个函数的地址,就通过这个函数名在符号表中找到一项符合要求的表项(表项
的Type属性是FUNC,并且将Name属性的值作为字符串表中的偏移,所找到的字符串和函数名一致),该表项的Value属
性的值就是函数的地址.
为了方便说明上述内容,这个add程序的ELF文件中包含的信息很少.由于库函数的原因,如果我们去查看一个在GNU
Linux上运行的,哪怕很小的程序,都会包含大量的库函数的信息.在代码目录下执行
就会在prog目录下生成hello可执行文件,你可以通过上述方法查看其ELF信息.
消失的符号
我们在prog/hello.c中定义了宏N,同时也在add()函数中定义了局部变量c和形参a,b,但你会发现在符号
表中找不到和它们对应的表项,为什么会这样?思考一下,什么才算是一个符号(symbol)?
寻找"HelloWorld!"
通过上文介绍的方法找到hello程序的字符串表,你发现"HelloWorld!"字符串在字符串表中的什么位置?为什么会
这样?
寻找正确的入口地址
根据上文提到的方法,在输入的ELF文件中找到main函数的地址.可以通过运行
来人工检查找到的地址是否与readelf中的结果一致.
框架代码提供的load_elf_table()函数已经为你从可执行文件中抽取出符号表和字符串表了,其中strtab是字符
串表,symtab是符号表,nr_symtab_entry是符号表的表项数目,更多的信息请阅读代码.