该REKO反编译器尝试加载我期待在一个特定的二进制的PE延迟进口目录崩溃。对于 32 位可执行文件,PE 规范指出该目录由一系列记录组成,其中偏移量 4 包含:
[the] 要加载的 DLL 名称的 RVA。该名称位于图像的只读数据部分 (
szName)
当我使用 dumpbin 查看图像时,我看到 PE 标头
185000 [ 2C6] RVA [size] of Delay Import
该.didata部分的原始数据是:
00585000: 00 00 00 00 90 51 58 00 00 00 00 00 A0 50 58 00 .....QX......PX.
00585010: B4 50 58 00 C8 50 58 00 DC 50 58 00 00 00 00 00 �PX.�PX.�PX.....
(etc)
请注意,在 00585004 处,该szName字段在我看来是虚拟地址 (00585190) 而不是RVA(本来应该是 00185190)。尽管如此,dumpbin 还是设法将其解释为:
USER32.DLL
00000000 Characteristics
00000000 Address of HMODULE
005850A0 Import Address Table
005850B4 Import Name Table
005850C8 Bound Import Name Table
005850DC Unload Import Name Table
0 time date stamp
它跟随 00585190 来查找字符串USER32.DLL。
那么延迟导入目录中的条目应该如何解释呢?PE 加载程序是否应该首先尝试将该szName字段作为 RVA读取,并且仅当它发现它不是有效的 RVA 时才尝试将其作为 VA 读取?
请注意,对于在地址 0x0040000 处加载的小型 EXE 文件,有效 RVA 的范围将为 ,[0x00000000..MAX_RVA)而有效虚拟地址的范围将为[0x00400000..MAX_RVA + 0x00400000],因此理论上可以通过查看 RVA 和 VA 的数值来区分它们。但是一旦二进制大小超过 0x00400000 字节(4194304 字节),这些范围就会重叠,您就无法再区分它们了。
更新:有趣的是,许多 PE 查看器和编辑器在此二进制文件上崩溃或脱轨。Dumpbin、IDA 和——最重要的——Windows 加载程序不会崩溃。想知道他们使用什么算法来避免死在这个二进制文件上?