一、相关意义及说明
当PE文件被执行的时候,Windows装载器将文件装入内存并将导入表中登记的DLL文件一并装入,再根据DLL文件中的函数导出信息对被执行文件的IAT表进行修正。在这些包含导出函数的DLL文件中,导出信息被保存在导出表中,通过导出表,DLL文件向系统提供导出函数的名称、序号和入口地址等信息,以便Windows装载器通过这些信息来完成动态链接的过程。
二、函数导出表结构和关系
(一)首先来看导出示意图:
上图左边是导出表结构IMAGE_EXPORT_DIRECTORY的各个字段,下面来说说各个字段间的关系:
1. nBase:导出函数序号的起始值。将AddressOfFunctions字段指向的入口地址表的索引号加上这个起始值就是对应函数的导出序号。假如nBase字段的值为x,那么入口地址表指定的第一个导出函数的序号就是x,第二个导出函数的序号就是x+1。
2. AddressOfFunctions:指向函数入口地址表,这张表包含了所有的导出函数,无论是有函数名的还是没有函数名的,它的每个字段内容是函数的入口RVA,这是一个双字表,也就是每个RVA都是双字。
3. AddressOfNames:指向一个双字RVA表,这个表中的每个RVA指向一个函数名称字符串。
4. AddressOfNameOrdinals:与函数名称表一一对应的索引表,也就是每一个有函数名的函数都能在这张表中找到对应的索引。也就是说AddressOfNameOrdinals表是一个中间表,一边对应着全部的函数名称,另一边对应着部分的函数入口地址。之所以这样是因为另外有一部分函数是没有名称的,而这部分函数的索引并不在AddressOfNameOrdinals表中。
(二)关于序号和索引
从书本的描述和之前的图中可以看出,无论是AddressOfFunctions还是AddressOfNameOrdinals,索引都是从零开始的,而序号=索引值+nBase。
三、分析书本实例(CHA17-Export文件夹—_ProcessPeFile)
1. _ProcessPeFile子程序参数的意义
(1) 子程序参数1:已经读取到内存中的文件头的地址。通过内存映射读取到整个PE文件在内存中的起始位置。
(2) 子程序参数2:PE文件头在内存中的偏移地址。也就是在MAGE_DOS_HEADER 结构中取出的e_lfanew的值。
(3) 子程序参数3:整个PE文件的长度。通过打开文件后拿到的句柄,用GetFileSize函数拿到文件的长度。</