如何手动编写和执行Windows .exe(带hex编辑器的机器码)?
我想知道如何使用hex编辑器来编写像Hello World程序一样简单的东西。 我知道我可以在一个接近机器级的地方使用汇编语言和汇编语言,但是我只是想尝试在一个玩具例如Hello World中编写机器代码。
这可能是一个简单的DOS .COM文件,我可以在DOSBox上运行。 但是,如果有人能够提供一个.EXE文件的例子来直接在我的Windows PC上运行它,那将会很好。
这只是纯粹的好奇心。 不,我没有直接用二进制机器代码编写程序(我通常不会编写汇编代码,大多数时候我只是把C / C ++当作我最低级的工具)。 我只是想看看是否有可能做到这一点,因为可能有人必须在电脑的早期做到这一点。
PS:我知道有关于这个话题的类似问题,但没有提供一个工作的例子。 我只是想要一个简单的例子,以便它可以帮助我理解编译器和汇编程序如何生成可执行文件。 我的意思是……在过去的第一个节目中,有人必须亲手做这个事情。 另外,对于Windows EXE格式,微软必须有人写下第一个工具来生成格式,以及Windows自己读取它的方式,然后执行它。
在corkami / wiki / PE101上有一个相当简约但充分的工作(在Win7上)exe,每一个字节都在漂亮的graphics中解释。 你可以在hex编辑器中手工input,但是填充可能会有点麻烦。
至于历史,有人在微软发明了exe格式(旧的DOS MZ exe格式),他(或者微软的其他人)为它和链接器写了一个装载器,这是传统上把输出编译器(“对象文件”)到可执行文件。 这可能(甚至可能,我会说)第一个exe程序是手写的,毕竟他们只是为了testing新的装载机。
后来,AT&T的COFF格式被微软扩展为PE格式,PE格式仍然有MZ头文件,通常(但是可选地,它不是在corkami的例子中,它可以是任何真正的)包括一个小的DOS程序来打印消息“这个程序不能在DOS模式下运行”。
1)一个.com文件是最简单的地方开始,将在一个dosbox上运行,基本上程序开始在偏移0x100文件,我认为第一个0x100可以是什么,不记得
2)虽然第一个程序经常是用手写成机器代码的,但是我们正在谈论当你添加两个数字的时候把它们保存在内存中,并且非常高兴你可以rest一天。 打印video卡的东西的“hello world”程序要复杂得多。 现在你可以使用dos系统调用一个非常简单的,也许这不是你感兴趣的,也许是这样。
3)基于2,任何一个在一个或几个指令的testing时间都比上个世纪六七十年代还要复杂的多,甚至在编写手工汇编程序的时候,你用手工编写你的程序在汇编程序中,然后把它汇编成机器代码,然后加载它。 首先学习汇编语言,然后学习如何为其生成机器代码,然后开始将这些字节input到hex编辑器中。 现在不是20世纪60年代,除非你有过度的痛苦,通过编写asm来学习上面的内容,用汇编器生成机器码,然后用反汇编器拆解它,并且检查汇编语言和机器码,以显着改善它将花费你得到一个工作程序的时间。 如果在操作系统和指令集之前你曾经为一家芯片公司工作过,那么你仍然可以利用团队的其他成员,芯片devise师等来了解如何制作机器代码和安排它们。 你不会仅凭借高水平的语言经验,只凭自己的成功希望就能完成这一切。
4)x86是一个可怕的指令集,如果你不知道程序集,我强烈build议你不要先学习它。 有一个x86是我听到最先学习x86的最糟糕的借口。 你已经提到了dosbox,所以已经计划仿真/模拟,所以使用一个好的指令集并模拟它或者购买那个硬件(即使在$ 20以下,$ 50也会给你一个更好的指令集的板子)。 如果你select购买一些,我build议首先模拟/模拟硬件并行。 如果你真的想要一个教育写你自己的模拟器,这是不难的。 也许创造你自己的指令集。
5)我有一个模拟器和其他裸机资源的集合http://github.com/dwelch67 msp430不坏,如果你觉得有需要,你可以得到5美元以下的硬件。 arm是好的,都是基于32/16(覆盆子pi,sam7s等)和16位拇指(基于cortex-m,mbed,maple mini,stm32f4发现等)。 琥珀色模拟器来自一个opencores处理器,我使用verilator来模拟,所以如果你select的话,你可以在处理器内部看看信号级别发生了什么。 thumbulator不需要任何东西,除了ac / c ++编译器来启动和运行,“二进制”文件格式,你可以在hex中键入“机器代码”,只需要hex编辑器,你会这样做。 我有一些指令集模拟器可供select,另外还有embedded一些板子上的裸机例子,价格在5美元到80美元之间。
6)这些都不会帮助你理解编译器的function。 了解汇编语言,然后反汇编编译器的输出是你的最佳途径,机器代码不涉及,不需要真正运行程序。 编译器从高级语言转换到低级语言(例如C到asm或C ++到asm)。 那么了解汇编程序的作用,有许多不同的解决scheme,由于历史和其他原因。 目前的典型解决scheme是一个单独的编译器,汇编器和链接器(编译器会为你调用汇编器和链接器,除非你不告诉它,这三个步骤是隐藏的,事实上编译过程可能不止一个程序运行以完成该任务)。 输出二进制文件的汇编程序必须parsing整个程序,输出到对象的汇编程序会在机器代码中留下空洞,以便链接器填充。例如分支或调用另一个对象中的项目,直到链接器放置为止在二进制的东西,并知道间距/寻址。 也访问存在于其他对象中的variables。
你可能没有看到hex编辑程序的实际例子,因为首先它是一个广泛的问题,没有一个简单的答案(什么操作,系统,什么系统调用或你创build那些,什么文件格式,什么hex编辑器等)。 另外,因为这是一个高层次的问题和问题,所以真正的问题是我在哪里学习汇编,我在哪里学习汇编和机器代码之间的关系,在哪里学习系统调用(这不是汇编问题,他们与学习asm无关,你学习汇编语言本身,然后你学会使用它作为一个工具来执行系统调用,如果你不能直接使用更高的语言执行系统调用),我在哪里学习可执行文件格式如COM, .exe,coff,elf等。什么是好的或者简单的或者一些形容词,hex编辑器运行在xyz操作系统或环境中。 分别提出这些问题,你会find答案和例子,一旦你有这些答案,你将知道如何使用hex编辑器键入机器代码编写程序。 一个简短的例子是,当你看到在SO上发布的程序的反汇编时,你会看到hex程序的hex例子,其中一些是以hex显示的完整程序。 如果你知道文件格式,你可以简单地把这些东西input到hex编辑器中。
我手工制作二进制文件,但是我觉得在汇编本身上比单纯的hex编辑器更容易,在这种编辑器中更新任何内容都很困难。
-
最简单的就是DOS COM格式,甚至可以input记事本 ,至less,即使是普通的Hello World ,也是非常容易的。
-
EXE(非DOS格式) 在这里不需要太多。
-
如果你想制作一个PE,你可以制作一个TinyPE 。
大多数二进制文件应该可以作为PE , EXE和COM 。
不是现货,但是本教程应该让您更好地了解程序集映射到machinde代码(x86 ELF)的方式: http ://timelessname.com/elfbin/(尤其是看看页面的下半部分)
这个页面是关于我创build最小的x86 ELF二进制文件的尝试,它将在Ubuntu Linux上执行Hello World。我首先尝试从C开始,然后进行到x86汇编,最后到hexeditor。
分析非常小的可执行文件非常好,因为汇编和机器代码之间的映射将更容易被发现。 这也是一个非常有趣的文章(不完全与您的问题相关): http : //www.phreedom.org/research/tinype/ (x86 PE)
您可以进行反汇编,并尝试找出您在汇编程序中使用的操作码的机器码
例如
org 0x100 mov dx,msg mov ah,0x09 int 0x21 ret msg db 'hello$'
用nasm -fbin编译./a.asm -o ./a.com有ndisasm a.com提供以下反汇编:
00000000 BA0801 mov dx,0x108 00000003 B409 mov ah,0x9 00000005 CD21 int 0x21 00000007 C3 ret 00000008 68656C push word 0x6c65 0000000B 6C insb 0000000C 6F outsw 0000000D 24 db 0x24 00000000 to 00000007 are the instructions
所以你可以使用ba0801机器码,使用一些hex编辑器,尝试将其更改为ba0901,只打印“ello”,您可以使用hex编辑器进行游戏,并使用NOP代码,例如:
00000000: ba 50 01 90 90 90 90 90 90 90 90 90 90 90 90 90 .@.............. 00000010: b4 09 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................ 00000020: cd 21 90 90 90 90 90 90 90 90 90 90 90 90 90 90 .!.............. 00000030: c3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................ 00000040: 71 77 65 72 74 79 75 69 61 73 64 66 67 68 6a 24 qwertyuiasdfghj$ 00000050: 61 73 64 66 67 68 6a 6b 61 73 64 66 67 68 6a 24 asdfghjkasdfghj$ 00000060: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------
如果你用扩展名.com保存,你可以在DosBox中运行它
我只是在命令提示符下使用ECHO写了一篇关于创build可执行DOS二进制文件的文章。 没有其他第三方HEX实用程序或x86 IDE需要!
该技术使用键盘组合 – ALT ASCII代码将OPCODES转换为可直接在MSDOS下读取的二进制格式。 输出是完全可运行的二进制* .com文件。
http://colinord.blogspot.co.uk/2015/02/extreme-programming-hand-coded.html
摘录:在DOS提示符下键入以下键盘命令,记住左ALT。
c:\>Echo LALT-178 LALT-36 LALT-180 LALT-2 LALT-205 LALT-33 LALT-205 LALT-32 > $.com
上面的代码实际上是描述一个X86汇编程序在屏幕上打印美元符号的操作码值。
完成后,您的提示应如下所示。 按回车build立!
c:\>Echo ▓$┤☻═!═ > $.com
运行文件'$ .com',你会看到一个美元($)字符显示在屏幕上。
c:\>$.com $ c:\>
恭喜! 您刚刚创build了名为$ .com的第一手编码可执行文件。