二进制文件之谜

Ema*_*erg 7 compiling binary

这是关于直接来自编译器的文件,比如 g++ 和-o(outfile) 标志。

如果它们是二进制的,它们不应该只是一堆 0 和 1 吗?

当你捕捉它们时,你会得到难以理解的输出,但也会得到完整的单词。

如果你提交它们,你会立即得到答案——似乎没有计算。二进制文件实际上是否具有包含此类信息的标题?

我认为二进制可执行文件只是刚刚编译的程序,只是您的 CPU 可以立即明确理解的机器指令形式。如果是这样,那指令集不就是位模式吗?但是,二进制文件中的所有其他内容是什么?你如何显示位?

另外,如果您以某种方式获得了处理器的手册,您能否手动编写一个二进制文件,一次一个机器指令?这将是非常低效的,但如果你让它甚至为“Hello World!”工作,那将是非常有趣的。演示。

Ren*_*nan 18

这个超级用户问题:为什么用文本编辑器打开二进制文件时看不到二进制代码?很好地解决了你的第一点。

二进制和文本数据没有分开:它们只是数据。这取决于使它们成为其中之一的解释。如果您在文本编辑器中打开二进制数据(例如图像文件),其中大部分将没有意义,因为它不符合您选择的解释(作为文本)。

文件存储为 0 和 1(例如内存上的电压/无电压,硬盘驱动器上的磁化/无磁化)。在cat处理文件时您看不到零和一,因为 0/1 序列对人类没有多大用处;字符更有意义,并且十六进制转储更适合大多数用途(尝试hexdump文件)。

可执行文件确实有一个标头,它描述了参数,例如构建程序的体系结构,以及文件的哪些部分是代码和数据。这file用于识别二进制文件的特征。

最后:是的,您可以直接使用 CPU 操作码以汇编语言编写程序。请查看UNIX 汇编编程简介Intel x86 文档作为起点。


小智 10

所有文件都存储为 1 和 0,cat 只是尝试将每个 BYTE(8 位)解释为一个字符,这就是您看到无法理解的字符的原因。


Gil*_*il' 6

所有文件在底层都是二进制的:它们存储为序列。

文件位实际上按字节分组。每个文件由整数个字节组成。所有的 Unix 系统,实际上几乎所有的计算机,都有由 8 位组成的字节(在网络术语中称为八位字节)。有一种自然的方法可以将字节解释为 8 位数字,即 0 到 2 8 -1 = 255之间的数字。

要将它们视为二进制,您需要一个工具以二进制表示法写出它们。人类不太适合二进制表示法:写任何东西都需要很长时间。使用十六进制表示法更为常见,有 16 个不同的数字。例如,41(十六进制的六十五)比01000001(二进制的六十五)更容易阅读。您可以使用诸如od(“octal dump”) 或hexdump或 之类的命令hd来列出每个字节使用八进制或十六进制表示法的文件(od -t x1切换到十六进制)。

字节可以表示字符。unix 世界中使用了几种字符编码。它们都基于ASCII,它定义了 0 到 127 之间字​​节的解释。请注意,这仅定义了一半可能的字节值的含义。例如,65 代表大写字母A,97 代表小写字母a,30 代表数字0,依此类推。一些字符编码用一个字节表示每个字符;比如latin-1编码中,163代表£,241代表ñ等等。这种方式最多可以表示256个字符,不多;因此,还有其他编码每个字符使用一个以上的字节。现在unix世界事实上的标准编码是UTF-8,它是Unicode字符集的变长编码(不同的字符占用不同的字节数)。

文本文件是恰好包含可理解文本的二进制文件。实际上,对于 unix 程序,只要满足两个条件,文件就是文本文件:

  • 文本文件不能包含任何空字节(数值为 0 的字节)。该字节不代表任何字符,在许多文本操作程序内部用作特殊标记。
  • 文本文件由一系列行组成,每行以换行符(其数值为 10)终止。

机器可执行文件是一种特殊的二进制文件。如果你cat对它们运行命令,你会看到偶尔出现一些文本的垃圾。这些文件也可能恰好包含用于您的终端的命令。您可以使用该程序strings查看二进制文件中的所有文本片段,而忽略不可打印的字符。

机器可执行文件不完全是机器指令序列:它们还包含一些额外的信息,告诉操作系统如何将文件加载到内存中,通常还有一些程序使用的数据,以及可选的调试信息。大多数 Unix 系统对机器可执行文件使用ELF格式。这种格式指定了如何将包含机器代码的文件划分为多个部分,该部分独立于机器架构;某些部分包含代码,该代码的含义特定于特定的机器架构。

您可以使用该命令objdump -D /path/to/machine-executable以人类可读的形式显示可执行文件的列表:汇编语言。好吧,无论如何,受过训练的人都可以阅读。汇编语言特定于处理器架构并直接映射到机器指令。

用汇编语言编写一个完整的程序是可能的,但是对于非平凡的程序很少这样做,因为它需要很长时间。如果你真的很疯狂,你可以直接用二进制编写你的程序。有些人试图想出尽可能短的打印程序Hello world;Ryan Henszey 解释了如何为 PC 处理器编写142 字节的 ELF 可执行文件;Brian Raiter分析了 ELF 格式并提出了一个Linux 愿意执行的 45 字节程序(该程序不打印任何内容)。

还有一些不是二进制文件的可执行文件;它们被称为脚本。相反,有许多二进制文件是不可执行的:图像、视频、压缩文件、文字处理器文档、没有入口点的代码库、其他处理器架构的可执行文件……