【问题标题】:PE File sections - SizeOfRawData or VirtualSizePE 文件部分 - SizeOfRawData 或 VirtualSize
【发布时间】: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


【解决方案1】:

据我了解,Windows 加载器一般不会copy the PE sections to the allocated PE memory。相反,它为 PE 的每个相关部分创建一个文件映射,每个部分都有其虚拟大小,然后让分页系统根据需要将文件内容放入已提交的内存中。

节对齐通常是指节的最小分辨率大小,通常为 4096 字节(传统内存页面的大小)。

原始数据大小是该部分在磁盘上的 PE 映像中实际存在的数据大小。

【讨论】:

  • 你是对的。这正是 Windows 加载程序的做法,而且很容易,因为您在磁盘上有一个文件。从缓冲区加载 DLL 时不能这样做,因此这些部分应该从缓冲区复制到分配的内存并在之后立即提交。看看我对这个问题的最后评论,也许你可以帮助我解决这个问题。
猜你喜欢
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2013-11-05
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
相关资源
最近更新 更多