LE 可执行修复记录表格式

逆向工程 x86 可执行
2021-06-22 00:56:43

所以我开始对旧的 LE 可执行文件进行逆向工程。所以为了更好地理解格式。我首先为这种格式编写了一个解析器。使用以下资源,我取得了相当大的进步。

vexilium

文本文件

但是现在我在解析修复记录表时遇到了格式描述中的错误,因为它被 vexillium.org 链接调用。

在解析这个特定的二进制文件 Fixup Record Table 时,每个条目似乎多出了 2 个字节。所以我想知道是我对格式的理解有问题还是格式描述不完整。

附注。我知道我应该使用 Fixup Page Table 来提取与每个页面对应的修复,我在代码中这样做了,但这与我遇到的问题无关。除了根据Fixup Page Table确实有Fixup Record Table条目。

在修复记录表的偏移量上的二进制中是以下字节。

07 00 AB 09 02 54 85 07 00 DB 0A 02 40 85 07 00
D2 0A 02 40 85 07 00 AF 0A 02 40 85 07 00 66 0A
02 80 85 07 00 4D 0B 02 83 18 07 00 E3 0B 02 80
85 07 00 FA 0C 02 83 18 07 10 92 0C 01 AC 0F 01
00 07 00 5F 0C 02 83 18 07 00 73 0D 02 8C 00 07
10 53 0E 01 B4 0E 01 00 07 10 F6 0D 01 B4 0E 01
00 07 00 F5 0E 02 8C 00 07 10 A6 0E 01 AC 0F 01
00 07 10 9F 0E 01 30 0F 01 00 07 10 89 0F 02 FA

因此,如果我们查看 Vexillium.org 上的 Fixup Record Table 的格式描述,我会按如下方式对其进行解析。

Reloc_addres_type 为 0x07 Reloc_type 为 0x00

由于未设置 Reloc_addres_type 位 5,我们正在解析“非列表”条目

重定位偏移量应该始终被解析并且是 0x09AB

因为 Reloc_type = 0,最低 2 位是 '0',因此这是一个内部修正。

所以我们解析了一个一字节的Target段号,这个是0x02

我们现在应该完成并解析下一个条目。但是如果我们查看二进制的结构,我们可以看到当前字节之后的 2 个字节是另一个 0x07 条目。如果我们继续解析,它将在 2 次解析操作中失败,因为 reloc_type 的低 2 位都变为“1”,并且这种类型没有格式描述,因为它被标记为 OSFIXUP???。

这是我的解析器的一些示例输出。它在第 2 个条目之后停止,因为第 3 个条目遇到了以“11”结尾的 reloc 类型

reloc_addres_type: 7
reloc_type: 0
data:
    offset: 09ab
    data:
        segment_number: 2

reloc_addres_type: 84
reloc_type: 133
data:
    offset: 0007
    data:
        imported_module_name_index: 219
        ordinal_value: 10
        abs_add_value:  16386
        extra: --
2个回答

额外的 16 位是目标偏移量(TRGOFF在文本文件文档中)。

我建议您根据 Hex-Rays 的Extensive File Dumper检查您的解析器

因此,在建议使用十六进制射线交叉验证我的解析器之后,我开始寻找 LE 格式的额外来源,结果是 InternalFixup 类型的修正中有一个额外的字段,称为目标偏移量,但它可以是 16 -bits 或 32-bits 取决于“32-bit target offset”标志。这是条目的第二个字节中的第 4 位(从 0=LSB 开始)

来源:LX 格式,更具体地说是该论文的图 2

请注意,据我所知,LE 和 LX 是相同的格式,但 LE 混合了 16 位和 32 位指令,而 LX 只有 32 位指令。

请注意,此描述还描述了我的问题中提到的“11”案例,该案例指的是“InternalEntry”。

编辑:再次阅读文本文件解释时,它似乎传达了与我发现的新来源相同的想法,尽管文本文件的呈现方式感觉很奇怪,我无法理解它。