【发布时间】:2015-01-21 19:42:29
【问题描述】:
最近,我一直在工作场所处理 PE 文件,并对 Windows 加载程序在幕后的工作产生了兴趣。
我知道加载PE文件时,加载器需要将PE部分复制到分配的PE内存中,一些加载器提交SizeOfRawData字节,一些提交VirtualSize字节,有时SectionAlignment(当SizeOfRawData等于0 ,对于未初始化的数据)。
我的问题是我怎么知道SectionAlignment 字节足以容纳所有部分的未初始化数据?也许我有一个比SectionAlignment 大得多的未初始化缓冲区,那么我如何确定它不会覆盖其他部分?我可以预测需要分配的大小吗?为了安全起见,我可以提交 VirtualSize 字节而不是 SectionAlignment 字节吗?
【问题讨论】:
-
“一些装载机”是什么意思?不同版本的Windows?第三方加载器?引导驱动程序的加载程序与应用程序的加载程序?
-
那么他们可能只是做错了。我认为规范要求您为每个部分分配
VirtualSize字节。 -
但是当 SizeOfRawData 大于 VirtualSize 时应该怎么办(这并不罕见)?将部分内容复制到分配的内存中时,您可能会遇到异常。我找到的解决方案是:1)在 VirtualSize 和 SizeOfRawData 之间执行
max,也就是dwAllocationSize。 2) 分配 dwAllocationSize 字节并将内存设置为零。 3) 将 SizeOfRawData 字节从 PointerToRawData 复制到分配的区域。这些规则对我来说似乎很好用(至少在我发现自己做错之前。目前,我探索过的所有加载程序在该区域都存在一些错误和不一致) -
这很奇怪;您是否能够确定 SizeOfRawData 大于 VirtualSize 的情况? (例如,Microsoft 构建工具是否曾经这样做过,或者只是某些第三方构建工具被破坏了?) FWIW 我认为您的解决方案是唯一明智的解决方案,尽管也许您应该看看 Windows 加载程序做了什么。 (我想,另一种选择是截断数据。)
-
刚刚用VS编译了一个Test DLL,这是从CFF explorer截取的截图。左边是 VirtualSize,右边是 SizeOfRawData。 imgur.com/dwRoUbm。刚刚实现了一个快速的基本加载器,我的解决方案有效。不过,我不知道这是否是正确的解决方案,而且我太累了,无法反转加载器,所以我想我应该处理不确定性。
标签: c windows winapi portable-executable internals