【问题标题】:PE Header RequirementsPE 标头要求
【发布时间】:2011-01-06 03:19:14
【问题描述】:

PE 文件 (PE/COFF) 的要求是什么?应该设置哪些字段,哪个值,使其能够在 Windows 上“运行”(即执行“ret”指令然后关闭,没有错误)。

我首先构建的库是链接器:现在,我遇到的问题是 PE 文件 (PE/COFF)。 我不知道 PE 文件在我的平台上实际执行之前“需要”什么。我的测试平台是 Vista。当我通过双击执行它时,我收到一条错误消息,说“这不是有效的 Win32 可执行文件。”,并且我收到“拒绝访问”。使用 CLI cmd 执行它时。我有两个部分,.text 和 .data。

我已经实现了几个在线文档(即 MSDN 和其他一些第三方文档)提供的 PE 标头。如果我使用十六进制编辑器,它看起来几乎就像一个普通的 PE 文件。我不使用任何导入、IAT 和 PE 标头中的任何目录。

编辑:我添加了一个导入表,仍然不是有效的 .exe 文件,我的 Windows 说。我尝试使用最小的 PE 文件指南中也提到的值。没有运气。真的,我似乎无法弄清楚的唯一一件事是什么是必需的,什么不是。一些指南告诉我一切都是必需的,而另一些指南则说贬低:它可以为零。

我希望这是足够的信息。 提前谢谢你。


当前 PE 头的原始数据(根据请求):

4D 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 50 45 00 00 4C 01 02 00 C8 7A 55 4B 00 00 00 00 00 00 00 00 E0 00 82 01 0B 01 0D 25 00 10 00 00 00 10 00 00 00 00 00 00 00 10 00 00 00 10 00 00 00 20 00 00 00 00 40 00 00 10 00 00 00 02 00 00 01 00 0B 00 00 00 00 00 03 00 0A 00 00 00 00 00 00 22 00 00 38 01 00 00 00 00 00 00 03 00 00 00 00 40 00 00 00 40 00 00 00 40 00 00 00 40 00 00 00 00 00 00 0E 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00 00 00 00 00 00 10 00 00 00 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 2E 69 64 61 74 61 00 00 00 00 00 00 00 20 00 00 00 02 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3C 20 00 00 00 00 00 00 00 00 00 00 24 20 00 00 34 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 45 52 4E 45 4C 33 32 2E 64 6C 6C 00 00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00 00 00 00

【问题讨论】:

  • 您当前的标题基于什么?您是否尝试过阅读 Microsoft 的 PE/COFF 规范 (microsoft.com/whdc/system/platform/firmware/PECOFF.mspx)?
  • 这个项目完成后我会感兴趣的。
  • 题外话:其实我正在开发一种编程语言。我想针对Win32。我使用 Java,因为它是一种可爱的语言,可以用作“宏语言”,即我只使用 java.io 和 java.nio。这很有趣,但我仍然被这个问题所困扰。
  • 我也在做同样的事情!我也在研究一种输出 PE 文件的语言,但它仍处于起步阶段。
  • 我知道的不够多,无法提供帮助,但是 mingw 的 objdump 在您的二进制文件中报告“文件格式无法识别”。

标签: java winapi assembly portable-executable coff


【解决方案1】:

将粘贴复制到十六进制编辑器是一件非常痛苦的事情,所以很遗憾,我不能马上说任何太聪明的话。

在 PE 文件中需要注意的事项: 确保您的 DOS 标头有效。 确保 IMAGE_OPTIONAL_HEADER 格式正确,因为尽管它的名称,Windows 不喜欢它不正确地完成。

有关 MS 格式以外的更多信息,请查找 pe.txt,这是我所知道的有关 PE 格式的最佳自制指南之一。

如果您可以只发布字节,我可以尝试将其放入我自己的 PE 解析器中,看看是否可以提供更多帮助。

【讨论】:

  • 我使用该指南(如“第三方”所述)来构建我的实现。我现在会更新它,只包含字节。
  • 不幸的是,我不知道到底出了什么问题。我进一步检查的第一个想法是使用已知的“正确”程序(例如 Visual Studio)创建相同的程序,并使用十六进制编辑器比较输出。
  • 我使用 sed 's/\(....\) \(....\) /\1\2:/' | xxd -r 将 OP 的 hexdump 转回二进制文件。
【解决方案2】:

这个article about creating tiny PE executables 可能很有趣:特别是它提到 Win2k 加载程序需要导入 KERNEL32.DLL,所以这可能值得研究。

【讨论】:

  • 是的,Windows 2000 需要一个导入表。但无论如何,我正在运行 Vista:不知何故,它不会重新识别格式。
【解决方案3】:

您尝试执行的操作取决于您使用的 Windows 版本。例如,在 Windows 2000 上读取 PE 文件的方式与 Windows 7 读取它们的方式不同。我是 OSX 用户,但在我拥有的 Windows 7 上,我无法以在 Windows 2000 和更早版本上工作的方式操作 PE 文件。我还没有测试过 XP 或 Vista(或 2000 年到 Win7 之间的其他版本)来查看 Windows 何时开始以不同的方式读取 PE。在 Windows 7 上,MS-DOS 标头和存根中的每一位内存都被忽略。唯一重要的两部分是“幻数”(一个等于“MZ”的字)和 PE 偏移量,它是一个 DWORD,它定义了 PE 标头在内存中的位置开始。我不确定 Windows 是否真的 100% 地忽略 MS-DOS 标头和存根中的所有其他值,但不包括我刚才提到的两个,如果所有其他值都设置为 0,则有效的可执行程序将正常运行.

在 Windows 2000 和更早的版本中,我不知道我上面提到的是否属实,但当时允许您修改 MS-DOS 存根的长度(或者可能删除它),前提是 PE偏移值仍然指向内存中的正确位置以查找 PE 标头。在 Windows 7 上,如果您完全修改 MS-DOS 存根的长度,即使 PE 偏移指向正确的修改位置,Windows 也不会运行 exe 并声称它不是有效的 Win32 应用程序。

4D 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0

这是 Windows 7 上 PE 文件的 MS-DOS 部分至少可以拥有的,同时仍然具有有效的、正常运行的可执行文件。那一点不能缩短。

希望这能解决一些问题。

【讨论】:

  • 感谢您的回复。你说的没错。我的问题解决了,我的 PE 文件是“有效的 Win32 可执行文件”。我在 VC++ Express Edition 中使用了名为“dumpbin”的实用程序;它表明我在 PE 可选标题中使用了错误的值,即图像的总大小。相反,我使用了图像文件大小,但我应该使用图像内存大小;这解决了问题。
【解决方案4】:

你可以试试 .NET 2.0 IL Assembler 之类的书。本书有一整章专门介绍 PE 格式的可执行文件是什么样的(以及 .Net PE 是什么样的)。

您也可以尝试使用 PE 文件阅读器加载您的 PE 文件并检查结果。 如果 PE 读者对你的 PE 感到困惑,那么你就有了一个指向失败之处的指针。

这是我写的PE File Reading DLL(附来源)。还有一个使用它的 GUI(带有源代码)。

源代码是完全开源的(不受 GPL 限制),因此您可以对它做任何您想做的事情(除了对其施加 GPL,这会阻止它完全开放),包括关闭您的版本。

【讨论】:

  • 谢谢!我想我可以用这个做点什么。我已经运行了使用它的 GUI,它告诉我“文件已损坏”,但由于这是开源的,我可以找出原因!我会接受这个答案,这对我有很大帮助并且间接地回答了我的问题(它导致了解决方案!)。
  • 我已经完全从头重写了所有的生成代码; windows 说,这一次它仍然是一个无效的 PE 标头。然后我将 PE 文件加载到您的文件阅读器 GUI 中,它告诉我完全相同的错误“文件已损坏!”。没有调试信息,没有线索,也没有我能做的任何有用的事情。我该如何解决这个问题?
  • 我不知道。我从来没有生成过 PE 文件,只是编写了读取它们的工具。我会首先尝试编写最简单的 PE 文件——没有部分(或一个部分,如资源文件)的东西。让它工作,然后继续处理更复杂的 PE 文件,这些文件有更多的部分,有重定位信息等。
【解决方案5】:

Microsoft PE/COFF 规范是我所知道的唯一规范。

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多