PE文件结构详解--PE导出表
来源:互联网 发布:清除文件 linux 编辑:程序博客网 时间:2024/05/21 07:01
通过函数获取数组中的项可以用RtlImageDirectoryEntryToData函数,DataDirectory中的每一项都可以用这个函数获取,函数原型如下:
PVOID NTAPI RtlImageDirectoryEntryToData(PVOID Base, BOOLEAN MappedAsImage, USHORT Directory, PULONG Size);
Base:模块基地址。
MappedAsImage:是否映射为映象。
Directory:数据目录项的索引。
Size:对应数据目录项的大小,比如Directory为0,则表示导出表的大小。
返回值表示数据目录项的起始地址。
这次来看看第一项:导出表。导出表是用来描述模块中的导出函数的结构,如果一个模块导出了函数,那么这个函数会被记录在导出表中,这样通过GetProcAddress函数就能动态获取到函数的地址。函数导出的方式有两种,一种是按名字导出,一种是按序号导出。这两种导出方式在导出表中的描述方式也不相同。模块的导出函数可以通过Dependency walker工具来查看:
上图中红框位置显示的就是模块的导出函数,有时候显示的导出函数名字中有一些符号,像 ??0CP2PDownloadUIInterface@@QAE@ABV0@@Z,这种是导出了C++的函数名,编译器将名字进行了修饰。
下面看一下导出表的定义吧:
结构还算比较简单,具体每一项的含义如下:
Characteristics:现在没有用到,一般为0。
TimeDateStamp:导出表生成的时间戳,由连接器生成。
MajorVersion,MinorVersion:看名字是版本,实际貌似没有用,都是0。
Name:模块的名字。
Base:序号的基数,按序号导出函数的序号值从Base开始递增。
NumberOfFunctions:所有导出函数的数量。
NumberOfNames:按名字导出函数的数量。
AddressOfFunctions:一个RVA,指向一个DWORD数组,数组中的每一项是一个导出函数的RVA,顺序与导出序号相同。
AddressOfNames:一个RVA,依然指向一个DWORD数组,数组中的每一项仍然是一个RVA,指向一个表示函数名字。
AddressOfNameOrdinals:一个RVA,还是指向一个WORD数组,数组中的每一项与AddressOfNames中的每一项对应,表示该名字的函数在AddressOfFunctions中的序号。
第一次接触这个结构的童鞋被后面的5项搞晕了吧,理解这个结构比结构本身看上去要复杂一些,文字描述不管怎么说都显得晦涩,所谓一图胜千言,无图无真相,直接上图:
在上图中,AddressOfNames指向一个数组,数组里保存着一组RVA,每个RVA指向一个字符串,这个字符串即导出的函数名,与这个函数名对应的是AddressOfNameOrdinals中的对应项。获取导出函数地址时,先在AddressOfNames中找到对应的名字,比如Func2,他在AddressOfNames中是第二项,然后从AddressOfNameOrdinals中取出第二项的值,这里是2,表示函数入口保存在AddressOfFunctions这个数组中下标为2的项里,即第三项,取出其中的值,加上模块基地址便是导出函数的地址。如果函数是以序号导出的,那么查找的时候直接用序号减去Base,得到的值就是函数在AddressOfFunctions中的下标。
用代码实现如下:
- PE文件结构详解--PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE文件结构详解(三)PE导出表
- PE结构导出表详解
- PE文件结构详解-PE导入表
- PE文件结构详解(三)PE导出表(转…
- PE总结9 --PE文件结构之 解析导出表
- PE文件结构详解
- PE文件结构详解
- PE文件结构详解
- PE文件结构详解
- PE文件详解------PE文件结构剖析
- [LCT 边双连通分量缩点] BZOJ 2959 长跑
- leetcode_326. Power of Three
- Android Webview中解决H5的音视频不能自动播放、只有声音没有图像的问题
- json.stringify和json.parse,序列化和反序列化
- 289. Game of Life
- PE文件结构详解--PE导出表
- 【Java 简介】
- 每天一个 Linux 命令(6):rmdir 命令
- Linux下sqlplus远程访问Oracle
- When to use RDDs, Datasets, and DataFrames?
- 常用gulp插件介绍(一)
- ubuntun16.04 +cuda8.0+cudnn5+opencv2.3+python+caffe安装过程中出现的一些问题
- CodeForces-747C
- Python学习笔记,5,字符串和编码问题