为什么编译后我们不能理解二进制文件的内容?


11

据我所知,每个程序都由处理器指令包和一些特定的数据变量(float,int,char ...)组成,以在处理器寄存器上工作。

所以,我想到的第一件事(很久以前)是,如果您知道ASCII值%¨#$¨#(只是一个随机示例)可以解释为x86 的堆栈指针寄存器的地址(仅作为示例)处理器。如果是这样,那么每次在读取二进制文件的内容时发现此“不可读”值时,都可以解释为堆栈指针寄存器正在用于管理某些数据变量。

不幸的是,这不会发生。下面是ping.exe打开Windows 的程序内容的示例notepad.exe

在MS记事本中查看的Ping.exe

它是一个二进制文件,它的数据对于我们人类来说是无法理解的(对于机器而言,是难以理解的。)即使对于任何人,即使他们知道汇编代码(最低级别的机器语言),也没有任何意义。

因此,如果我正确理解了所有内容,那么有人可以解释一下吗

  1. 为什么二进制代码不能返回到汇编代码的最深处呢?
  2. 如果可以理解汇编代码,为什么从此代码生成的编译二进制文件不再“可读”?

12
可以,您只需要一个反汇编程序即可
David Schwartz 2012年

因此,我可以取消任何.exe文件???我只是知道它可以与托管代码一起使用...
Diogo 2012年

13
您可以反汇编任何可执行文件。是否可以理解反汇编的输出是另一回事。
大卫·史瓦兹

5
编译或汇编会删除很多对人来说很重要的信息,例如变量名,分支标签等。虽然无法获得指令流,但您仍有很多事情要弄清楚。
mpez0 2012年

1
另外代码混淆可以拆卸阻碍。
数学

Answers:


13

首先,寄存器没有地址。任何汇编语言的每条指令都转换为操作码。x86中的操作码可以是一个,两个,三个或更多字节(在某些其他处理器中,它们是“固定宽度”)。通常,操作码会标识所涉及的指令,寻址模式和寄存器。“寻址模式”确定CPU是否需要比操作码更多的内容,即“立即”寻址模式意味着该指令的指令之后(或“立即”之后)还有其他数据-“绝对”寻址模式意味着存储器地址遵循该指令,并由该指令使用。

您可以找出类似MOV AL,SP或类似内容的操作码,然后进行搜索。x86有许多对堆栈指针进行操作的指令。

但是,退出使用记事本,而使用十六进制编辑器。我建议使用HxD,尽管还有很多其他功能。

@David Schwartz是正确的。反汇编程序将遍历文件,然后将操作码转换回可读的文本。您想要做的完全有可能。

但是,您需要知道指令在文件中的起始位置,因为如果您从错误的地址开始,则某些数据应该是操作码的“操作数”(例如使用操作数或“参数”的地址的指令)被误解为操作码。知道这一点需要了解可执行文件的格式,对于Windows,该格式是“便携式可执行文件”或PE格式(对于Linux系统,通常是ELF)。我敢肯定有了解PE等的反汇编程序,但是我不知道有什么副手。


1
IDA是最常见的PE分解器之一。也适用于Linux和Mac文件。5.0版仍然可以作为免费软件
斯科特张伯伦

1
>如果您从错误的地址开始,...可能会被误解。 这就是为什么所有出现的%¨#$¨#情况不一定都引用堆栈指针的原因。它可能只是两个不同命令的中间:_3p%¨#$¨#b5F_3p   %¨#$¨#   b5F)。
Synetech

12

所以,如果我正确理解了一切

不完全的。

这是一个二进制文件,它的数据对于我们人类来说是无法理解的

通常,二进制文件对人和机器来说都是难以理解的,尤其是在文件的用途未知的情况下。请注意,并非所有二进制文件都是可执行文件。许多二进制文件是不包含任何机器指令的数据文件。这就是为什么在文件命名(在某些OS中)时使用文件扩展名的原因。的。CP / M使用com扩展名表示可执行文件。的。exe扩展名由MS-DOS添加,以表示另一种可执行文件格式。* nixes使用execute属性表示可以执行哪些文件,尽管它既可以是脚本也可以是代码。

正如其他人已经提到的那样,包含数字的二进制文件应由十六进制转储程序或十六进制编辑器而非文本查看器查看。

有一个ping.exe程序的内容示例

该文件实际上是可重定位的程序,并非该文件中的所有数据都代表机器代码。有关于程序的信息,例如它需要哪些动态库,必须链接的例程,对堆栈和程序及数据存储器的要求以及程序的入口点。文件中的地址操作数可以是需要计算为绝对值的相对值,也可以是需要解析的引用。

您可能会想到的“程序文件”称为二进制映像文件或程序内存转储。这样的文件将仅包含机器代码和数据,并且正确设置了所有地址引用以执行。

即使他们知道汇编代码(机器语言的最低级别)。

汇编语言与机器语言不同。典型的CPU(不包括高级语言计算机)接受机器代码作为输入,一次只接受一条指令。操作数是寄存器或数字存储器地址。汇编语言是一种高级语言,可以将符号标签用于指令位置和变量,以及用助记符代替数字操作码。汇编语言程序必须先转换为机器语言/代码,然后才能实际执行(通常由称为汇编程序,链接程序和加载程序的实用程序执行)。

可以对程序文件执行相反的撤消操作,即成功执行和丢失符号信息。由于需要手动识别代码和数据位置,因此反汇编内存转储或程序映像文件的过程更容易出错。

顺便说一句,有人可以读取和编码(数字)机器代码。当然,在8位CPU或微控制器上,这比具有十二种内存地址模式的32位CISC处理器容易得多。


3

您无法通过记事本看到二进制文件的正确的预期编码。请查看此内容以备将来参考。大多数文本编辑程序不解析二进制编码格式,并且应解析ASCII字符代码格式。

因此,在文本编辑器中打开二进制文件将产生等效的ASCII字符,这些字符对文本编辑器解析的二进制数据的原始格式没有任何意义。如前所述,十六进制编辑器(其中一些具有二进制功能)以纯二进制格式查看内容。

您无法理解二进制文件的内容是不正确的。尽管它们会很困难,但在现代计算机体系结构中,很难将它们单独从二进制文件手动分解为CPU识别的用于执行(或仿真/虚拟CPU)等的正确指令等,但这是可以做到的。

您如何看待仿真器的编程方式?开发人员将需要知道操作码,以便能够对虚拟系统进行编程,从而以某种方式识别并表现出真正的硬件。文档解释了CPU的许多体系结构,甚至GPU也拥有它们(尽管更秘密)。

要注意的另一件事是,在最低级别(尽管是相关的)中,“二进制数据”实际上不是一堆零和一,而是高低电压作为电流通过电路放大/切换的电路。

二进制通常是1:1,因此使用数字系统很有意义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.