编写PE文件解析器(一)

本文介绍了如何编写一个PE(Portable Executable)文件解析器,包括理解RVA和RA的区别,解析IMAGE_DOS_HEADER和IMAGE_NT_HEADERS,以及处理IMAGE_SECTION_HEADER和数据目录。通过解析导出表,展示了导出函数地址的获取方法。
摘要由CSDN通过智能技术生成

第一篇先写一个PE格式解析器,学了那么久了写出来防止自己忘记,顺便练练手。PE格式解析是比较基础的内容,后面再越写越深。我写这个不是介绍pe格式,而是说编写解析代码,解释定义什么的网上一堆就不粘了,重要的定义我尽量简洁的描述清楚就行,如果想知道每一个定义或者字段是用来干嘛的,在pecoff文档里写的很清楚。业余时间写的,时间不充裕写得很慢,写错请斧正,转载请注明,高手轻批。


解析前需要弄清楚的是RVA相对虚拟地址和RA相对地址,RVA是系统的loader加载到内存中用的,RA是解析文件用的。PE里存的偏移地址大部分都是RVA,因为它是要加载到内存中使用的,所以pe里存rva会快一些。

写解析代码的时候如果想让RVA和RA通用, 需要对载入的方式进行区分,因为后面文章会讲到修改PE内容往里面塞东西和其它一些什么的,所以为了方便我写成通用的。

用读文件或者用GetModuleHandle之类的函数载入,读文件方式解析时需要做rva2ra转换,GetModuleHandle载入的是运行中的进程,已经映射好了,就不用做转换了,把得到的地址作为基址,直接把它转成PCHAR就行。

几乎所有的定义都在winnt.h里,一般使用时只要导入这个就行,只有一些不太常用的定义在其它头文件里。

下面开始:


1、IMAGE_DOS_HEADER【Dos头】

这个段应该是历史遗留问题,需要到的只有e_magic和e_lfanew两个字段。e_magic直接判断等于IMAGE_DOS_SIGNATURE就行,一般pe是以0x4D5A开始的,看定义有其它的值,但是我没见过有其它值的pe。e_lfanew是用来跳过dos stub的,就是用21中断显示那一段英文的代码,删掉这段代码也没关系,以后再写。其它字段可以全部无视。


2、IMAGE_NT_HEADERS【Nt头】

通过base+dosHeader->e_lfanew偏移得到。这个结构分为32版本和64位版本,包含Signature(PE的为IMAGE_NT_SIGNATURE,就是PE\0\0)、FileHeader和OptionalHeader,其中只有OptionalHeader有32和64的区别,其它都是一样,解析到这里的时候需要注意区分是否为32或64位的pe,其信息记录在OptionalHeader字段中,字段中的Magic记录了该pe类型,因为Magic所在位置是一样的,所以可以用PIMAGE_NT_HEADERS32(base + DosHeader->e_lfanew)->OptionalHeader.Magic判断值,再确定使用IMAGE_NT_HEADERS32还是IMAGE_NT_HEADERS64来定这个结构的类型,声明的时候直接用union就行,直接以32位版本赋值后也不用改。

IMAGE_FILE_HEADER FileHeader相对有用的地方是NumberOfSections和SizeOfOptionalHeader。其它有用的信息都记录在OptionalHeader里。(叫做可选,实际上非常重要)


2.1、IMAGE_FILE_HEADER【文件头】

Machine记录机器类型,后面会用到。FileHeader里的NumberOfSections记录了PE节的数量,SizeOfOptionalHeader记录了可选头的大小,第一个节头是紧跟着可选头的&#x

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值