PE格式解析-导出表分析

导出表:PE文件中保存导出函数的导出表,常见导出表位于DLL文件中。

示例 MyDll.dll
这里写图片描述

1、找出导出表(又名输出表)位置
(1)使用WINHEX打开Dll文件,根据PE文件的可选头(Image_Optional_Header)找到输出表位置(查找方法链接),或者使用LoadPE查看
这里写图片描述
前4个字节表示输出表RVA,后四个字节表示输出表大小
输出表RVA:0017D40
输出表大小:1A0

(2)计算输出表在文件中的偏移
这里写图片描述
(关于RVA与文件偏移的计算,前面有提到,这里通通省略计算)
计算出输出表的文件偏移量:00006B40


2、根据导出表(输出表)结构分析二进制
(1)导出表结构
导出表
保留字:用于以后PE文件的拓展使用
时间日期记录:Dll创建的日期
函数的总数:共导出了几个API
FAT表RVA值(AddressOfFunctions):导出函数的地址表(保存的是导出函数的模块被加载到内存后,所导出的函数在内存中的地址)
FAT表RVA值(AddressOfNames):导出函数的函数名表(保存的是导出函数的函数名的RVA值)

(2)在WINHEX中,跳到6B40位置
这里写图片描述
保留字:00000000
时间日期记录:5A369320
Dll的首版本号:0000
Dll的次版本号:0000
Dll的模块名(RVA):00017D90->文件偏移量(6B90),图片中可以看到,6B90处对应的就是我们Dll的名字 MyDll.dll
基数:00000010
函数的总数:00000004
有名函数的总数:00000004
FAT表RVA值(AddressOfFunctions):00017D68->文件偏移量(6B68),从图片中得出6B68地址处的值 00011032 该值为第一个导出函数的RVA值,依次往下的 0001102D、000111DB、00011131 分别为其余三个函数地址的RVA值
这里写图片描述
FAT表RVA值(AddressOfNames):00017D78->文件偏移量(6B78),从图片中得出6B78地址处的值 00017D9A(文件偏移:6B9A) 该值为第一个导出函数的RVA值,依次往下的
00017DAA(文件偏移:6BAA)
00017DC0(文件偏移:6BC0)
00017DBA(文件偏移:6BBA)
分别为其余三个函数名的RVA值(查看 对应文件偏移量处的 函数名)
这里写图片描述

总结:导出表的结构类似一个多级指针数组的结构。
例如:查找函数名,首先是查找到保存“导出函数的函数名的数组的地址”的指针(AddressOfNames),该指针的值保存着“导出函数的函数名的RVA值的数组”,找到导出函数的函数名的RVA值的数组后,根据数组中保存的RVA值,再找到每个导出函数的函数名的文件偏移,再获取函数名即可。


3、导出表的使用
(1)用于DLL的拦截
例如:有个应用程序text.exe运行的时候需要调用程序文件夹下的MyDll.dll,该Dll中有4个导出函数
1)拦截的Hack可以先将MyDll.dll改名为yourDll.dll
2)自己实现一个DLL,使得该Dll导出函数名称与原始的MyDll.dll同名,且导出函数要相同
3)将自己实现的DLL改名为MyDll.dll,并放到需要拦截的程序文件夹下
此时我们就可以在我们实现的MyDll.dll中实现我们需要拦截的内容,拦截完成后再在MyDll.dll中转发调用yourDll.dll(避免程序无法运行)

(2)用于逆向的分析相关算法(使用得比较少)

本文难免有所错误,如有问题欢迎留言

这个源码没记错的话是去年9月份写的,当时本来是打算写一个功能齐全一点的PE工具,例如解析导入导出、重定位及节等功能,后来只写了一个解析导出就放弃了,为什么呢,主要是因为声明结构体比较烦,是一个体力活,所以后面转用VS开发这款工具去了,毕竟头文件里都将结构体定义好了,省事,现在把这个 易语言 版本的解析导出代码开源。 它可以解析导出里正常导出的函数,还能解析导出里的中转函数,见下图: 写这个工具的过程中发现PEID解析导出有点问题,见下图 注意这个图里3个红框里的内容,第一个是LORDPE解析的,中间是我自己写的代码解析的,最右边是PEID解析的,可以发现PEID解析导出时只能正常解析以符号名导出的函数,一旦遇到以序号导出的函数就会导致错位,图中user32.dll导出的前两个函数是以序号0x5DC和0x5DD导出的并没有导出函数名,而PEID不能正常解析,LORDPE、STUDYPE还有我自己写的代码都能正常解析,至于为什么导出序号那里,我的是从0开始的,而LORDPE和STUDYPE是以0x5DC开始的,那是因为我没有加上序号基数,中间那个蓝色箭头指向就是基数,函数真正的导出序号是要加上这个基数的,只不过我习惯这样达而已。另外开源前特意把里面变量的名字改成了一看就明白的意思,所以看起来有点奇怪。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值