PE文件解析库 – LibPE v0.1 Preview
最近突然想学习一下PE文件的结构,所以就写了一个PE文件的解析库,纯属好玩。于是经过了1个月的业余时间的折腾,LibPE v0.1 Preview终于诞生了。
项目名称:LibPE
项目地址:https://github.com/r1f/libpe
License:The BSD 2-Clause License
欢迎大家去围观,如果有人参与那就更加的Happy鸟~Licese是BSD的,所以基本上大家可以拿来随便用了。
1. 功能
现在这个库到底能做什么呢?说出来真的是太简单了,所以才把这个版本定位v0.1 Preview,供围观之用。
- 解析磁盘上的PE文件,暂时不支持解析映射好的PE。
- 支持解析32位(PE32)和64位(PE32+)的PE文件。
- RVA,VA,FOA转换
- 解析PE基本头部信息,段表,导出表,导入表,资源表,重定向表和导入函数地址表
- 支持获取PE文件的原始数据结构,并且对结构中的字段提供想对应的getter,如IPEOptionalHeader::GetFieldDllCharacteristics
(注意:这里拿到的是原始数据,在文件中和在映射好后的映像中可能会不一样)
好了,围观完了之后,我们现在再大概描述一下LibPE想做什么吧~
2. 目标和设计原则
LibPE想成为一个容易使用,32位64位兼容,性能不错并且可以跨越平台的PE解析库。虽然里面有一部分内容还没有完成,比如跨平台的迁移,IMAGE相关的结构还真的是多到不行啊,迁移起来还真是需要一些时间。
2.1. 容易使用
- 尽量避免让使用者通过RVA和FOA去操作PE结构,而是直接提供获取PE元素的函数。
- 获取到的每个PE结构都具备有获取RVA,FOA和大小的函数。
- 能编译成lib和dll,方便使用
- 使用引用技术来管理对象的生命周期,接口中只使用基本的数据类型,避免跨dll的问题。
- 能够解析不同状态的PE文件结构,比如在磁盘上的,已经被映射进来之后的。当然这个现在还没有完成。。。。嗯。。。
2.2. 兼容32位和64位的PE格式
-
这个功能简直就是必备的
-
统一32位和64位的接口!!
这个特性个人觉得很有用,网上大部分的PE库,为了支持64位都是使用模版来完成的,这样我们想实现一个批量的PE文件处理的话就会出现很多问题,而LibPE就是想解决这些问题:
- 冗余的代码:除非使用模版,要不然处理的逻辑得32位和64位都写一遍,但是使用模版,又会让代码看起来更加晦涩,这些都是LibPE想避免的问题
- 冗余的IO:由于处理的时候需要先判断文件是32位还是64位,所以就会出现需要一次IO去判断文件类型,再一次IO去解析文件,这样会导致处理大量文件时性能下降,因为这个时候磁盘IO是整个系统的瓶颈。
2.3. 不错但不是极致的性能
LibPE并不追求极致的性能,相对极致的性能,LibPE更加注重是否对程序员友好,整个库是否好用。但是性能也是很重要的!
为了达到不错的性能,我们主要做了两个方便的工作:
- 即用即解析:如果不需要看导入表,那我解析个毛啊!
- 最小化磁盘IO:在现在手机CPU都可以处理登月数据的年代,CPU其实已经非常的强。而大量的文件处理时,磁盘IO才是真正的瓶颈,减少磁盘IO才是真正对整个系统最有帮助的优化。
2.4. 跨平台
跨平台啊,跨平台,相当蛋疼的体力活也相当重要。客户端的代码一般都不会出现大量处理PE文件的情况,而后台一般都是linux,所以支持跨平台很重要。
2.5. 最小外部依赖
为什么不用boost或者其他跨平台的基础库?作出这个蛋疼决定的出发点只有一条:让大家能少checkout一点代码,改libpe时能少学一点东西。
3. 使用
好了,扯了这么多七里八里的东西,看看到底要怎么用这玩意吧~
- 编译LibPE,把生成的LibPE.lib(lib方式编译),LibPEDll.lib,LibPE.dll(Dll方式编译)拷贝到你自己的工程目录中去。
- 开始开心的写代码吧,先来个导入表玩玩:
1 | # |
更多的使用方法,大家可以看看工程中的LibPETest,其实这也不是一个Test工程,就是用来大概试一下新的写的东西。
当然,现在LibPE还有很多问题,还有很多需要做的内容没有做。日后再慢慢完善吧~
原创文章,转载请标明出处:Soul Orbit本文链接地址:PE文件解析库 – LibPE v0.1 Preview