2009-04-16 47 views
11

我不熟悉编译器的魔力。对我而言,将人类可读代码(或不可读的组装指令)转换成机器代码的行为对于我来说是火箭科学与巫术的结合。如何手动读取/写入.exe机器码?

我会缩小这个问题的Win32可执行文件(.exe)的主题。当我在专门的查看器中打开这些文件时,我可以找到散布在各个地方的字符串(通常为每个字符16b),但剩下的只是垃圾。我认为不可读部分(多数)是机器代码(或者可能是资源,比如图像等)。

是否有阅读的机器代码的任何直接的方式?打开exe作为文件流并逐字节读取它,如何将这些单独的字节转换为Assembly?在这些指令字节和汇编指令之间是否有直接映射?

.exe是如何编写的?每条指令有四个字节?更多?减?我注意到一些应用程序可以像这样创建可执行文件:例如,在ACD中请参阅您可以将一系列图像导出为幻灯片。但这不一定是SWF幻灯片,ACD See也可以制作EXEcutable演示文稿。这是如何完成的?

我怎么能理解一个EXE文件里面发生什么事情?

+1

ACDSee技巧将使用预编译程序并编辑其资源。请参阅http://www.silurian.com/win32/peformat.htm并使用Process Explorer(http://live.sysinternals.com/procexp.exe)进行操作。 – Mark 2009-04-16 14:39:54

+0

谢谢,这看起来不错。和进程浏览器真棒。几个月前开始使用它,这真是太神奇了。每次我运行它,我都不禁想知道他们是怎么做的? – 2009-04-16 14:48:06

+0

这里只是一个延迟的评论;你最终怎么设法继续?你设法走得很远吗? – dreamlax 2009-08-21 05:48:52

回答

15

OllyDbg是一个真棒工具拆卸的EXE成可读的指令,让您一个接一个来执行指令。它还告诉你程序使用什么API函数,如果可能的话,它提供的参数(只要参数在堆栈中找到)。

一般来说,CPU的指令是可变长的,有些是一个字节,其他两种,有三种,大约四等,这主要取决于数据的种类指令的期望。一些指令是通用的,如“mov”,它告诉CPU将数据从CPU寄存器移动到内存中的某个位置,反之亦然。实际上,有许多不同的“mov”指令,用于处理8位,16位,32位数据,用于移动来自不同寄存器的数据的指令等等。

你可以拿起博士保罗·卡特的PC Assembly Language Tutorial这是谈论组装免费的入门级的书,以及如何在Intel 386 CPU运行。它大部分适用于现代消费类英特尔CPU。

的EXE格式是特定于Windows。入口点(即,第一可执行指令)通常在EXE文件内的相同地方找到。一次很难全部解释,但我提供的资源应该至少可以帮助你治愈一​​些好奇心! :)

4

您可以使用debug命令行,但是这很难。

C:\WINDOWS>debug taskman.exe 
-u 
0D69:0000 0E   PUSH CS 
0D69:0001 1F   POP  DS 
0D69:0002 BA0E00  MOV  DX,000E 
0D69:0005 B409   MOV  AH,09 
0D69:0007 CD21   INT  21 
0D69:0009 B8014C  MOV  AX,4C01 
0D69:000C CD21   INT  21 
0D69:000E 54   PUSH SP 
0D69:000F 68   DB  68 
0D69:0010 69   DB  69 
0D69:0011 7320   JNB  0033 
0D69:0013 7072   JO  0087 
0D69:0015 6F   DB  6F 
0D69:0016 67   DB  67 
0D69:0017 7261   JB  007A 
0D69:0019 6D   DB  6D 
0D69:001A 206361  AND  [BP+DI+61],AH 
0D69:001D 6E   DB  6E 
0D69:001E 6E   DB  6E 
0D69:001F 6F   DB  6F 
+0

今天学到了新东西。我希望我不会很快破坏我的操作系统。当我过度兴奋地调整注册表项时发生过一次......从未再次看到我的桌面。 – 2009-04-16 14:41:45

+0

您也可以编写新代码并将其保存回文件。只有一个疯子(或黑客)会使用调试 – 2009-04-16 14:54:34

+0

算上我仍然使用调试的少数人之中。仅供参考:微软的DEBUG只能拆卸16位实模式。如果您需要支持32位DPMI的调试,请尝试japheth的版本:http://www.japheth.de/debxxf.html – 2009-10-21 12:29:44

6

您需要一个反汇编程序,它将机器码转换为汇编语言。这个Wikipedia link描述了这个过程并提供了免费反汇编的链接。当然,正如你所说,你不懂汇编语言,这可能不是很有用的信息 - 你究竟想在这里做什么?

+0

不链接到Windbg http://www.microsoft.com/whdc/devtools/调试/ installx86.mspx – Mark 2009-04-16 14:37:48

1

Win32 exe format MSDN上

我建议采取的Windows的C源代码的位和建立,并开始在Visual Studio调试它。切换到反汇编视图并逐步执行命令。您可以看到C代码是如何编译成机器代码的 - 并且一步一步地观察它。

5

您看到的可执行文件是Microsofts PE(便携式可执行文件)格式。它本质上是一个容器,它容纳一些关于程序的特定于操作系统的数据,并且程序数据本身分成几个部分。例如代码,资源,静态数据存储在单独的部分。

该部分的格式取决于它的内容。代码部分根据可执行的目标体系结构保存机器代码。在最常见的情况下,对于Microsoft PE二进制文件,这是Intel x86或AMD-64(与EM64T相同)。机器代码的格式是CISC,并返回到8086及更早的版本。 CISC的重要方面是它的指令规模不是固定的,你必须从正确的地方开始阅读,从中获得有价值的东西。英特尔在x86/x64指令集上发布了很好的手册。

您可以使用反汇编程序直接查看机器代码。结合手册,您可以在大多数时间猜测源代码。

然后是MSIL EXE:.NET可执行文件持有微软中间语言,这些不包含机器特定的代码,但.NET CIL代码。这些规格可在ECMA在线获得。

这些可以用反射器等工具查看。

5

Portable Executable中描述了EXE文件的内容。它包含代码,数据和操作系统关于如何加载文件的说明。

机器代码和程序集之间有1:1映射。反汇编程序将执行反向操作。

i386上的每条指令没有固定的字节数。有些是单字节,有些则长得多。

2

如果对你来说看起来很陌生,我不认为调试器或反汇编器会提供帮助 - 你需要先学习汇编程序设计;研究处理器的体系结构(大量可从英特尔下载的文档)。然后,由于大多数机器代码都是由编译器生成的,因此您需要了解编译器如何生成代码 - 编写大量小程序最简单的方法,然后反汇编它们以查看C/C++转换成的内容。

一对夫妇的书籍,将帮助您了解: -

1

就有关这个问题,现在还有人看东西像CD 21?

我在一个节目中记得桑德拉布洛克,实际上是在读一串十六进制数字,并找出节目的功能。有点像当前版本的阅读矩阵码。

如果你确实看过像CD 21这样的东西,你怎么记得不同的各种组合?

1

ACD See可能利用了这样一个事实,即.EXE文件不会对文件长度或任何超出文件预期部分长度的错误进行检查。正因为如此,您可以创建一个.EXE文件来打开自己的文件,并将数据加载到指定点以外的所有文件中。这很有用,因为你可以通过在适当写入的数据上添加一个.EXE来处理给定的数据集.EXE

(我不知道ACD See究竟是如此采取的盐的大粒,但我知道一些程序生成的方式。)

2

为了拿个主意,设置断点上一些有趣的代码,然后去到CPU窗口。

如果您对更多内容感兴趣,使用-al参数编译带有Free Pascal的短片段会更容易。

FPC允许使用-A参数以多种汇编格式(TASM,MASM,GAS)输出生成的汇编程序,并且可以使原始pascal代码在注释(以及更多)中交错使用,以实现轻松的交叉引用。

因为它是编译器生成的汇编程序,而不是汇编程序从反汇编的.exe,它更符号化,更容易遵循。

1

熟悉低级程序集(我指的是低级程序集,而不是“宏”和公牛)可能是必须的。如果您真的想直接读取原始机器码,通常您会使用十六进制编辑器。但是,为了理解指令的作用,大多数人会使用反汇编器将其转换为适当的汇编指令。如果你是少数想要了解机器语言的人,我想你会想要Intel® 64 and IA-32 Architectures Software Developer's Manuals卷2特别涵盖了指令集,它涉及您的关于如何读取机器代码本身以及如何与其组装相关的查询。

相关问题