如何手动创建可执行的.exe PE文件?

时间:2011-10-31 18:25:13

标签: windows compiler-construction linker executable portable-executable

有关如何创建编译器的所有文本在解释词法分析器和解析器后停止。他们没有解释如何创建机器代码。我想了解端到端流程。

目前我的理解是,Windows exe文件格式称为Portable Executable。我阅读了它所拥有的标题,但我还没有找到一个能够轻松解释这个问题的资源。

我的下一个问题是,我没有看到任何解释机器代码如何存储在文件中的资源。是否像在.text部分中一个接一个地存储了32位固定长度指令?

是否有任何地方至少解释如何创建一个什么都不做的exe文件(它有一个No Op指令)。然后我的下一步是链接到dll文件以打印到控制台。

7 个答案:

答案 0 :(得分:8)

好问题!我对这个具体问题没有太多专业知识,但这就是我的开始:

  1. PE或ELF不会创建纯机器代码。它还包含一些标题信息等。阅读更多:Writing custom data to executable files in Windows and Linux

  2. 我假设您正在寻找ELF / PE文件如何保存机器代码,您可以从这个问题中获得(使用objdump):How do you extract only contents of an ELF section

  3. 现在,如果你想知道内容部分是如何生成的,那么机器代码是如何生成的,那就是compiler's code generation的任务。

  4. 尝试使用ResourceEditor之类的资源编辑器来理解exe或只是ildasm

  5. PS:这些主要是Unix解决方案,但我确信,PE应该做一些基本相似的事情。

    我认为接近它的最佳方法是首先尝试分析现有的PE / ELF如何工作,基本上是逆向工程。要做到这一点,Unix机器将是一个很好的起点。然后做你的魔术:)

    不一样,但问题类似here

    <强>更新

    我从示例c代码中生成了一个对象转储。现在,我认为你的目标正确吗?您需要知道生成此文件(a.out)吗?

    https://gist.github.com/1329947

    看看这张图片,c代码的续航时间。

    enter image description here

    Source 现在,为了清楚起见,您正在寻求实现最后一步,即将目标代码转换为可执行代码?

答案 1 :(得分:3)

正如他的许多文章一样,我写道Matt Pietrek's piece about PE internals仍然是写完这篇文章十多年来最好的内容。

答案 2 :(得分:2)

对于Linux,可以阅读并运行示例 乔纳森巴特利特的“从头开始编程”:

http://www.cs.princeton.edu/courses/archive/spr08/cos217/reading/ProgrammingGroundUp-1-0-lettersize.pdf

当然,人们可能更愿意破解Windows程序。但也许是前者 提供了一种更好的方式来理解真正发生的事情。

答案 3 :(得分:1)

毫不奇怪,有关编写PE格式文件的最佳信息站点都是关于创建病毒的。

搜索VX Heavens的“PE”提供了大量修改PE文件的教程

答案 4 :(得分:1)

我多年来一直使用“Wotsit的文件格式”......一直回到MS-Dos的日子:-)然后回到它只是你可以从大多数BBS系统下载的文本文件的集合称为“游戏程序员文件类型百科全书”

它现在由运行Gamedev.Net的人所拥有,可能是互联网上保存最好的秘密之一。

您可以在此页面找到EXE格式:http://www.wotsit.org/list.asp?fc=5

享受。

答案 5 :(得分:1)

有关使PE文件尽可能小的一些信息:Tiny PE

如果您只是想尝试一些简单的事情,那么混乱代码生成的简约方法是输出MS-DOS .COM files,它没有标题或元数据。遗憾的是,您被限制为16位代码。这种格式在demos仍然有点受欢迎。

至于指令格式,我记得x86指令集是可变长度的,包括1字节指令。 RISC CPU可能有固定长度的指令。

答案 6 :(得分:0)

可执行文件格式取决于操作系统。对于 Windows,它是 PE32(32 位)或 PE32+(64 位)。

最终可执行文件的样子取决于操作系统的 ABI(应用程序二进制接口)。 ABI 告诉操作系统加载程序应该如何加载 exe 以及它应该如何重新定位它,它是 dll 还是普通的可执行文件等。

每个目标文件(可执行文件或 dll 或驱动程序)都包含一个称为部分的部分。这是我们所有代码、数据、跳转表等所在的位置。

现在,要创建目标文件,这是编译器所做的,您不仅要创建可执行的机器代码,还要创建标头、符号表、重定位记录、导入/导出表等。

纯机器代码生成部分完全取决于您希望代码进行多少优化。但是要在 PC 中实际运行代码,您必须创建一个包含所有标头和相关数据的文件(检查 MSDN 以获得精确的 PE32+ 格式),然后将所有可执行机器代码(由您的编译器生成)放入一个文件中的部分(通常代码驻留在称为 .text 的部分中)。如果您已经创建了符合 PE32+ 格式的文件,那么您现在已经在 windows 中成功创建了一个可执行文件。