PE学习(8) 导出表学习与解析

可选PE头的最后一个字段是数据目录表,是大小为16的结构体数组

该表记录了导出的函数,记录当前的PE文件有哪些函数可以被别人使用

一般而言导出表存在于DLL中给EXE使用,但这也不是绝对

通过VirtualAddress找到每一项在内存中的偏移,数据目录第一个结构体就是导出表

导出表的结构

该表项中的值是RVA(加上ImageBase才是函数真正的地址)

以上部分字段对应的关系

 

打印导出表

开头和之前的文章类似,解析DOSNT头,拿到需要的可选PE头

拿到第一个数据目录结构体,对应导出表

将第一个数据目录的VirtualAddress转为FOA地址(文件偏移)

RvaToFileOffset这个函数在PE学习(6)文章中已经详细介绍:如何将内存相对偏移转为文件偏移

通过这个地址即可得到文件中导出表的地址

 

简单格式化打印下

 

文章开头已经提到,导出表的Name以及各种Address都是内存偏移地址,需要使用RvaToFileOffset函数得到FOA文件偏移地址,进一步通过FileBuffer拿到真正的值

拿到相对于FileBuffer的指针,指向文件中导出表的内容

注意:序号表指针必须是PWORD类型,否则后续操作会有问题(上图也有说明宽度是2)

 

遍历函数地址表,根据函数地址索引尝试在序号表里查找

如果成功在序号表里找到该函数的索引,可以进一步去函数名表根据序号索引拿到名称地址dwNameFoa,这是一个RVA地址,进行转换后从FileBuffer开头处计算偏移地址,该处记录了具体的函数字符串

另外函数序号规定,函数导出序号 = 序号表保存的序号 + Base值

如果根据函数地址索引找不到对应的序号,且这个函数地址记录不为空,则这是一个隐藏函数

我从电脑上随便找了一个DLL做实验

 

结尾

整体代码

主函数

 

读者可能看完这篇文章感觉云里雾里,可以参考下一篇文章,或许可以解开疑惑

另外,这里用到的代码,都仅限于32位,在64位中有另外的方式和办法