问了问题几天后,我意识到我误解了我的原始发现。似乎文件上的.rdata节直接复制到了内存中,但是随后加载程序使用IAT RVA覆盖了前36个字节。关于增加96个字节的错误问题是由于我没有注意到我在测试中检查的字节序列在文件上重复出现的结果。

我刚才所说的仍然可能不是100%准确。调查将在接下来的几天中继续。

原始问题

我正在尝试编写一个程序来分析Windows可执行文件。我假设可执行文件中的部分直接复制到内存中。我在几个程序中注意到了奇怪的行为。

一个示例是crackme12.exe。当我检查调试器.rdata加载到内存中的部分时,我可以看到由于某种原因在加载到内存中的可执行文件中没有的部分的开头添加了96个字节。我花了2天的时间尝试阅读Windows可执行文件,但找不到解释它为什么发生的原因。在Linux上的Wine下。
我使用的调试器称为OllyDbg。
文件下载链接:http://www.reversing.be/easyfile/file.php?show=20080602192337264

我想用Common Lisp编写程序。这是测试文件的链接:https://github.com/bigos/discompiler/blob/master/test/lisp-unit.lisp

我试图在Windows下加载相同的crackme并得到了另一个惊喜。并排显示Windows和Wine。

从地址x402060中以红色突出显示的屏幕快照中显示了从文件部分复制的数据。在加载操作系统时插入了96个字节。令我惊讶的是,葡萄酒装载机插入了不同的数据。比较Wine和Windows之间的差异时,您会发现前两行有所不同。有人可以启发我发生了什么事吗?

结论

原来,导入表RVA和IAT RVA放在x402000和x402060之间的地址处。因此,看起来加载器将这些表之后的部分复制到内存中。

我在我的小程序中添加了一些代码,并得到以下输出:

RVA:(((320“导入表RVA” 8228)(324“导入表大小” 60) “资源表大小” 1792)
“在内存中,从”“ 404000”“到”“ 404700”)
((408“ IAT RVA” 8192)(412“ IAT大小” 36)“在内存中从“” 402000“
”到“” 402024“))

评论

它可能与加载过程有关:重定位,导入,导出...我们需要样本,或更准确的描述。

#1 楼

这是导入地址表,其中包含导入功能的虚拟地址。

由于DLL已加载到不同的地址(一种情况下为7bxxxxxx,另一种情况下为76xxxxxx),因此导入地址表用不同的DWORD值填充。