如何手动编写和执行Windows .exe(使用Hex编辑器的机器代码)?

pet*_*nts 37 windows executable exe machine-code

我想知道如何通过使用十六进制编辑器来编写像Hello World程序这样简单的东西是可能的.我知道我可以在近机器级别使用汇编语言和汇编语言,但我只想尝试在Hello World这样的玩具示例中编写机器代码.

这可能是一个简单的DOS .COM文件,我可以在DOSBox上运行.但是,如果有人可以提供.EXE文件的示例,直接在我的Windows PC上运行它会很好.

这只是纯粹的好奇心.不......我不打算直接用二进制机器代码编写程序(我甚至不编写汇编代码,我只是在大多数时候使用C/C++作为我最低级的工具).我只是想知道是否可以这样做,因为可能有人必须在计算机的早期阶段做到这一点.

PS:我知道关于这个话题有类似的问题,但没有提供一个有效的例子.我只想要一个简单的例子,以便它可以帮助我理解编译器和汇编器如何生成可执行文件.我的意思是......在过去的第一个项目中,有人必须亲手完成.此外,对于Windows EXE格式,Microsoft必须有人编写第一个生成格式的工具以及Windows本身读取它然后执行它的方式.

har*_*old 16

corkami/wiki/PE101上有一个相当简约但完全正常工作(在Win7上也是如此)的exe ,它的每一个字节都在漂亮的图形中解释.您可以在十六进制编辑器中手动输入所有内容,但填充可能会使这有点单调乏味.

至于历史,是的,微软的某人发明了exe格式(旧的DOS MZ exe格式),他(或微软的其他人)为它和链接器编写了一个加载器,这是传统的转换输出编译器("目标文件")成可执行文件.可能(甚至可能,我会说)第一个exe程序是手工编写的,毕竟它们只是为了测试新的加载器.

后来,AT&T的COFF格式被微软扩展为PE格式,它仍然具有MZ标题,并且通常(但可选地,它不在corkami示例中,它可以是任何真正的)包括一个小的DOS程序只是为了打印消息"此程序无法在DOS模式下运行".


old*_*mer 9

1).com文件是最简单的启动位置,将在dosbox上运行,基本上程序从文件中的偏移0x100开始,我认为第一个0x100可以是任何东西,不记得了

2)虽然第一个程序通常是手工编写并汇编到机器代码中,但我们正在谈论当你添加两个数字时将它们保存在内存中并且非常高兴你可以休息一天.将内容打印到视频卡的"hello world"程序要复杂得多.现在你可以使用dos系统调用来制作一个非常简单的调用,也许这不是你感兴趣的,也许是.

3)基于2,在20世纪60年代或70年代进行测试时,一次比一个或几个指令更复杂,甚至在编写手工组装程序时,用手工编写汇编程序,然后将其组装成机器代码,然后加载它.首先学习汇编语言,然后学习如何为它生成机器代码,然后开始将这些字节输入到十六进制编辑器中.它不是20世纪60年代,除非你喜欢过度痛苦,通过编写asm来学习上述内容,使用汇编程序生成机器代码,然后使用反汇编程序对其进行反汇编并检查汇编语言和机器代码并进行显着改进获得工作计划所需的时间.如果您在拥有操作系统和指令集之前曾在一家芯片公司工作过,那么您仍然可以利用团队中的其他成员,芯片设计人员等来了解如何制作机器代码并进行安排.只有高水平的语言经验才能实现这一目标,并且希望自己能够成功完成所有这些工作.

4)x86是一个可怕的指令集,如果你不知道汇编我强烈反对你不要先学习它.拥有x86是我听过学习x86的最糟糕的借口.你已经提到了dosbox,所以我们已经计划模拟/模拟,所以使用一个好的指令集并模拟它或者购买那些硬件(低于50美元甚至低于20美元就会给你买一块具有更好指令集的板).如果您选择购买,我建议首先模拟/模拟并与硬件并行.如果你真的想要教育写自己的模拟器,那就不难了.也许发明你自己的指令集.

5)这些都不会帮助您理解编译器的功能.了解汇编语言然后反汇编编译器输出是您获取该知识的最佳途径,不涉及机器代码,无需实际运行程序.编译器从较高级语言转到较低级语言(例如,C到asm或C++到asm).然后了解汇编程序的作用,有许多不同的解决方案,这些解决方案既有历史原因,也有其他原因.今天典型的解决方案是一个单独的编译器,汇编器和链接器(你的编译器会为你调用汇编器和链接器,除非你不告诉它,这三个步骤是隐藏的,实际上编译过程可能不止一个是运行以完成该任务).输出二进制文件的汇编程序必须解析整个程序,输出到对象的汇编程序将在机器代码中留下漏洞,供链接器填写.例如分支或调用另一个对象中的项目,直到链接器放置它才能编码二进制中的东西,知道间距/寻址.还访问其他对象中的变量.

你可能没有看到关于十六进制编辑程序的实际例子,因为首先它是一个如此广泛的问题,没有一个简单的答案(什么操作,系统,什么系统调用或你在创建那些,什么文件格式,什么十六进制编辑器等).另外,因为它是一个高级别的问题和问题,真正的问题是我在哪里学习汇编,我在哪里了解汇编和机器代码之间的关系,我在哪里学习系统调用(这不是汇编问题,他们与学习asm无关,你学习汇编语言本身,然后你学会使用它作为执行系统调用的工具,如果你不能使用更高的语言直接执行系统调用),我在哪里学习可执行文件格式,如.com, .exe,coff,elf等.在xyz操作系统或环境中运行的什么是好的或简单的或形容词,十六进制编辑器.单独询问这些问题,您将找到答案和示例,一旦获得这些答案,您将知道如何使用十六进制编辑器输入机器代码来制作程序.一个较短的例子是,当您看到在SO上发布的程序的反汇编时,您会看到完整程序的十六进制示例,其中一些是以十六进制显示的完整程序.如果你知道文件格式,你可以直接在十六进制编辑器中输入.

  • 它不会从文件中的0x100开始; 代码从文件的最开始开始执行.它被加载到*memory*中的地址0100中,但是,无论选择哪个段作为代码段. (2认同)

Ang*_*nge 5

我手工创建二进制文件,但我认为它在汇编本身比简单的十六进制编辑器更容易,更新任何东西都很困难.

大多数二进制文件应该以PE,EXE和COM的形式提供.


Cha*_*tål 4

不太准确,但本教程应该让您更好地了解汇编如何映射到机器代码(x86 ELF):http://timelessname.com/elfbin/(特别是查看页面的下半部分)

本页是关于我尝试创建最小的 x86 ELF 二进制文件,该二进制文件将在 Ubuntu Linux 上执行“Hello World”。我的第一次尝试从 C 开始,然后进展到 x86 汇编,最后到十六进制编辑器。

分析像这样的非常小的可执行文件是很棒的,因为汇编代码和机器代码之间的映射将更容易发现。这也是一篇关于该主题的非常有趣的文章(尽管与您的问题并不完全相关):http://www.phreedom.org/research/tinype/(x86 PE)