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

28

所有关于编译器创建的文本都会在解释了词法分析器和语法分析器之后停止。它们没有说明如何创建机器代码。我想要理解端到端的过程。

目前我了解的是,Windows exe文件格式被称为Portable Executable。我阅读了它具有的标头,并且尚未找到一个能够简单解释的资源。

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

是否有任何地方至少说明如何创建一个什么也不做(只有一个No Op指令)的exe文件。然后我的下一步将连接dll文件以打印到控制台。


2
请注意,不同的系统对可执行文件有不同的表示方式。 - Keith Thompson
他提到了Windows...我认为他特别指的是EXE格式。 - qJake
是的,我想先专注于Windows。当我对此感到舒适时,我可以转向ELF。 - AppleGrew
这并不值得回答,但是微软实现了一种 COFF 格式的版本,其描述在此处:http://msdn.microsoft.com/en-us/windows/hardware/gg463119。 - wkl
可能是重复的问题:如何手动读写 .exe 机器代码? - Ciro Santilli OurBigBook.com
7个回答

8

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

  1. PE或ELF不仅包含纯机器码,还包含一些头信息等。阅读更多:在Windows和Linux中向可执行文件编写自定义数据

  2. 我假设您想知道ELF/PE文件如何保存机器码,您可以从这个问题中获取答案(使用objdump):如何仅提取ELF部分的内容

  3. 现在,如果您想知道首先生成内容部分的方式,即如何生成机器码,则需要编译器的代码生成来完成该任务。编译器的代码生成

  4. 尝试使用ResourceEditor等资源编辑器来理解exe,或者简单地使用ildasm

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

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

不同但类似的问题here

更新:

我从示例C代码中生成了一个对象转储。现在,我假设这就是您的目标,对吗?您需要知道如何生成此文件(a.out)吗?

https://gist.github.com/1329947

看看这张图片,一段 C 代码的生命周期。

enter image description here

来源 现在,只是为了明确,你想要实现最后一步,即将目标代码转换为可执行代码吗?


你提供的链接非常有用。唯一缺少的是代码生成部分。当你说它们没有纯机器码时,你具体指的是什么? - AppleGrew
还有一点需要注意。我使用7zip从exe或dll中提取不同的部分。这非常简单。 - AppleGrew
  1. 当你说代码生成部分时,你是指如何创建ELF文件吗?
  2. 嗯,纯机器码不是可读的代码。但是,ELF文件附带了一些“元数据”。我会更新我的答案,然后也许我们可以得出一个答案。
- zengr
是的,我想了解最后一步。我很清楚ELF和PE的含义。通过代码生成,我的意思只是机器码。关于PE的文档对此没有任何启示。 - AppleGrew
一位朋友建议 - http://inst.eecs.berkeley.edu/~cs164/fa11/。看起来相当不错。 - AppleGrew

4

不再可用。此链接他的维基百科条目上仍然可用,但已经过去两个十年... - Andreas Haferburg

2
多年来,我一直在使用“Wotsit's文件格式”……甚至回到MS-Dos的日子 :-) ,当时它只是一个可以从大多数BBS系统下载的文本文件集合,称为“游戏程序员文件类型百科全书”。现在它已经被运行Gamedev.Net的人所拥有,并且可能是互联网上保存最好的秘密之一。您可以在此页面上找到EXE格式:http://www.wotsit.org/list.asp?fc=5。祝您使用愉快。
2020年6月更新-以上链接似乎已经失效,我在wotsit网站的这个Web存档页面上找到了“EXE”页面:https://web.archive.org/web/20121019145432/http://www.wotsit.org/list.asp?al=E 更新2-我保留了早期编辑时的内容,感谢那些想要编辑的人,但我拒绝它是有充分理由的:
1)wotsit.org可能在未来某个时间重新上线,如果您实际尝试访问URL,您会发现它并没有消失,它仍然会响应,只是以错误消息响应。 这告诉我,有人为某种原因保持着该域名的活力。
2)存档链接似乎有些不稳定,有些有效,有些无效,有时它们似乎有效,然后刷新后就无效了,然后它们又变得有效了。 我记得从wotsit仍然在线的经验中,他们有一些非常奇怪的下载/链接检测代码,这可能导致archive.org获得一些非常奇怪的结果,我记得他们采取这种立场是因为大量第三方网站试图通过假装成联盟会员然后直接从广告满载的网站链接到wotsit来从他们的成功中获利。
除非wotsit域完全从互联网上删除,甚至DNS也没有响应,否则将所有内容都包装成单个存档链接将是维护链接的最佳方法。

刚刚我自己试了一下,没错,你说得对。这是我第一次看到这个网站出现问题。不幸的是,我无法提供任何帮助,因为我不是这个网站的管理员。我猜你需要去看看是否有任何帮助/管理员链接来联系网站所有者。正如我所说,这个网站是由“Gamedev.Net”运营的,所以也许值得去那里问问。 - shawty
您仍然可以在web.archive.org上找到它,但下载已不再可用。搜索"Bernd Luevelsmeyer pe 文件格式"可能会更好些。 - Andreas Haferburg
虽然这真是太可惜了,它现在已经不再存在了 :-( 这些年来,我自己也为该项目贡献了一些格式文档。在我的阁楼上,我实际上还保存着一整摞用非常老的点阵打印机打印出来并存放在一个大环形活页夹中的文档。 - shawty
@user3789797,你不觉得这样作为一个独立的回答会更好吗?而不是在我的回答下发表评论。毕竟,你直接回答了问题,而不是在我的评论中添加任何额外的内容。 - shawty
不,恐怕不行。虽然它是关于相同的主题,但我所指的文档是原始的“wottsists文件格式文档”,而不是微型PE项目,因此正如我所说,你最好作为一个独立的答案。 - shawty

1

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

VX Heavens上搜索“PE”会得到一大堆修改PE文件的教程。


我在 VX Heavens 上找不到任何有用的东西。它有一些链接,我猜是俄罗斯的网站。 - AppleGrew
发现需要从框中搜索才能找到链接。更直接的链接可能是http://forum.vxheavens.com/viewtopic.php?id=186。 - AppleGrew

1

关于如何尽可能地减小PE文件的大小:Tiny PE

如果你只是想尝试一些简单的东西,最简单的代码生成方式是输出MS-DOS .COM文件,它们没有头部或元数据。不幸的是,你将被限制在16位代码上。这种格式在demos中仍然有些流行。

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


0

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

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

每个对象文件(可执行文件、dll或驱动程序)都包含一个称为“节”的部分。这是我们所有代码、数据、跳转表等所在的地方。

现在,要创建一个对象文件(编译器所做的),你不仅需要创建可执行机器代码,还需要创建头文件、符号表、重定位记录、导入/导出表等。

纯机器代码生成部分完全取决于你想让你的代码有多少优化。但是,要在PC上实际运行代码,您必须创建一个带有所有标题和相关数据的文件(请参阅MSDN以获取精确的PE32+格式),然后将所有可执行机器代码(您的编译器生成的)放入其中一个节中(通常代码驻留在称为“.text”的节中)。如果您已经创建了符合PE32+格式的文件,则现在已成功在Windows中创建了可执行文件。


0

我没有看到任何与我的问题相关的内容。 - AppleGrew
所有关于如何创建编译器的文本都在解释词法分析器和语法分析器之后就停止了。它们没有解释如何创建机器码。我想要理解整个过程。所引用的书籍(请参阅第3章中类似“Hello World”的程序)解释了如何编写汇编程序,将其编译成机器语言,然后链接它以创建可执行文件。 - John Donn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接