为什么二进制文件编译后我们看不懂里面的内容?

为什么二进制文件编译后我们看不懂里面的内容?

据我所知,每个程序都由一组处理器指令和一些特定的数据变量(float、int、char…)组成,用于处理器寄存器

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

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

在 MS Notepad 中查看 Ping.exe

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

所以,如果我理解正确的话,有人可以解释一下吗?

  1. 为什么二进制代码不能返回到汇编代码,就其深层含义而言,它们是同一件事?
  2. 如果可以理解汇编代码,为什么由该代码编译出的二进制文件不再“可读”呢?

答案1

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

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

但是,求求您,停止使用记事本,改用十六进制编辑器。我推荐 HxD,尽管还有很多其他的。

@David Schwartz 是对的。反汇编程序将遍历文件,并将操作码重新翻译成可读的文本。你想要做的事情完全有可能。

然而,你需要知道文件中的指令从哪里开始因为如果你从错误的地址开始,一些应该是操作码的“操作数”的数据(例如以地址作为操作数或“参数”的指令)可能会被误解为操作码。要知道这一点,需要了解可执行文件的格式,对于 Windows 来说是“可移植可执行文件”或 PE 格式(对于 Linux 系统通常是 ELF)。我相信有反汇编程序可以理解 PE 等,但我不知道有任何现成的。

答案2

如果我理解正确的话

不完全的。

它是一个二进制文件,其数据对于我们人类来说是难以理解的

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

正如其他人所提到的,包含数字的二进制文件应该用十六进制转储程序或十六进制编辑器查看,而不是用文本查看器查看。

这是 ping.exe 程序内容的示例

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

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

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

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

可以对程序文件执行反向操作(反汇编),虽然成功率不高,但会丢失一些符号信息。内存转储或程序映像文件的反汇编需要反复试验,因为需要手动识别代码和数据位置。

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

答案3

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

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

您说二进制文件的内容无法理解,这是错误的。虽然理解起来很难,但在现代计算机架构中极其艰难手动将二进制文件反汇编为 CPU(或模拟/虚拟 CPU)可以识别的正确指令等,以便执行。

您认为模拟器是如何编程的?开发人员需要知道操作码才能对虚拟系统进行编程,使其以某种方式识别和运行真实硬件。文档解释了许多 CPU 架构,甚至 GPU 也有这些架构(尽管更加隐秘)。

还需要注意的另一件事是,在最低级别中,尽管具有相关性,“二进制数据”实际上并不是一堆零和一,而是通过电路以电流形式放大/切换的高低压。

二进制通常与此呈 1:1 关系,因此使用数字系统非常有意义。

相关内容