第8章 压缩与脱壳
第五节 脱壳高级篇
2、Import表的重建
标题:重建 PE 文件的输入表
原著:TiTi/BLiZZARD
翻译:Sun Bird [CCG]
日期:2000年5月24日
1. 前言 =======
大家好 :) 我之所以写这篇短文,是由于我在 Dump 时发现,很多加压、加密软件都使 得输入表(Import Table)不可用,所以 Dump 出的可执行文件必须要重建输入表。而在普 通的讲授 Win32 汇编的站点上我没有找到这样的介绍,所以如果你对此感兴趣,那么这篇 短文对你会有些帮助。
例如,为了让从内存中 Dump 出的经 PETite v2.1 压缩过的可执行文件正常运行,必 须重建输入表。(对于 ASPack、PEPack、PESentry……也同样)这就是所有 Dump 软件都 具备重建输入表功能的原因(例如 G-RoM/UCF 制作的 Phoenix Engine(ProcDump 内含), 或者由 Virogen/PC 和我制作的 PE Rebuilder)。
鉴于这个问题十分特殊,而且比较复杂,所以我假定你已经了解了 PE 文件结构。(你 需要阅读有关 PE 文件的文档)
2. 预备知识 ===========
首先是一些关于输入表和 RVA/VA 的简介。
输入表的相对虚拟地址(RVA)储存在 PE 文件头部的相应目录入口(它的偏移量为 [ PE 文件头偏移量+80h ])。由于是虚拟偏移量,所以它和文件输入表中的偏移量(VA) 是不匹配的(除非文件纯粹是刚刚从内存中 Dump 出来的)。于是我们首先要做的事情是, 找到 PE 文件的输入表,将 RVA 转换为相应的 VA。为此,我们可以采用不同的办法:你可 以自行编制软件来分析块(Sections)目录并计算 VA,但最简单的办法是使用专门为此设 计的应用程序接口(API)。这个 API 包括在 IMAGEHLP.DLL(Win9X 和 NT 系统都使用的 一个库)中,名为 ImageRvaToVa。下面是对它的描述(完整的内容详见 MSDN 库):
# LPVOID ImageRvaToVa( # IN PIMAGE_NT_HEADERS NtHeaders, # IN LPVOID Base, # IN DWORD Rva, # IN OUT PIMAGE_SECTION_HEADER *LastRvaSection #); # # 参数: # # NtHeaders # # 指示一个 IMAGE_NT_HEADERS 结构。通过调用 ImageNtHeader 函数可以获得这个结构。 # # Base # # 指定通过调用 MapViewOfFile 函数映射入内存的一个映象的基址(Base Address)。 # # Rva # # 指定相对虚拟地址的位置。 # # LastRvaSection # # 指向一个指定的最终 RVA 块的 IMAGE_SECTION_HEADER 结构。这是一个可选参数。当被 #指定时,它指向一个变量,该变量包含指定映象的最后块值,以便将 RVA 转换为 VA。
就这么简单。你只需要将 PE 文件映射入内存,然后调用这个函数就能够得到输入表的正 确 VA。
注意,下面我会忽略所有的 RVA/VA 注释,但是,当你对重建的 PE 文件进行读出或写入 RVAs 操作时,不要忘记它们之间的转换。
1 2 3 下一页 |