9

为什么将字符插入可执行二进制文件会导致它“中断”?

而且,有没有办法在不破坏编译程序的情况下添加字符?

背景

我早就知道可以使用十六进制编辑器来更改已编译的可执行文件中的代码,并且仍然可以正常运行...

例子

作为下面应用程序中的示例,Facebook可以将其更改为Lacebook,并且程序仍然可以正常执行:

在此处输入图像描述

在此处输入图像描述

但它打破了新角色

我也知道,如果添加了新字符,它会破坏程序并且它不会运行,或者它会立即崩溃。例如,My在前面添加Facebook将实现此目的:

在此处输入图像描述

我知道的

我不知道的

  • 我不太明白操作系统和可执行文件之间的关系。我猜当您输入程序名称并按回车键时,您基本上是在指示操作系统“执行”该文件,这基本上意味着将文件加载到内存中,将处理器的指针设置为它,并告诉它'去!'
  • 我明白为什么二进制文件的文本字符串中有多余的字符会导致问题

我想知道的

  1. 为什么多余的字符会导致程序中断?
  2. 是什么决定了程序坏了?操作系统?操作系统是否也将此程序保持为沙盒状态,以便它现在不会使整个系统崩溃?
  3. 有没有办法通过十六进制编辑器将额外字符添加到已编译程序的文本字符串中,而不会使应用程序中断?
4

3 回答 3

5

当一个程序被编译成机器代码时,它包括许多对程序存储器中指令和数据地址的引用。编译器确定程序所有内存的布局,并将这些地址放入程序中。可执行文件也被组织成多个部分,开头有一个目录,其中包含每个部分的字节数。

如果你在程序中插入一些东西,之后所有东西的地址都会上移。但是包含对程序和数据位置的引用的程序部分没有更新,它们继续指向原始地址。此外,包含所有部分大小的表不再正确,因为您增加了修改的任何部分的大小。

于 2013-12-31T01:17:14.287 回答
5

我不太明白操作系统和可执行文件之间的关系。我猜当您输入程序名称并按回车键时,您基本上是在指示操作系统“执行”该文件,这基本上意味着将文件加载到内存中,将处理器的指针设置为它,并告诉它'去!'

现代操作系统只是将文件映射到内存中。在需要之前,他们不会费心加载它的页面。

为什么多余的字符会导致程序中断?

因为他们把文件中的所有其他信息都放在了错误的位置,所以加载器最终加载了错误的东西。此外,代码中的跳转最终会出现在错误的位置,可能是在指令中间。

是什么决定了程序坏了?操作系统?操作系统是否也将此程序保持为沙盒状态,以便它现在不会使整个系统崩溃?

这取决于到底是什么搞砸了。可能是您移动了一个标头,加载程序注意到标头中的某些参数包含无效数据。

有没有办法通过十六进制编辑器将额外字符添加到已编译程序的文本字符串中,而不会使应用程序中断?

可能不可靠。至少,您需要可靠地识别需要调整的代码部分。这可能非常困难,特别是如果有人故意这样做的话。

于 2013-12-31T01:17:50.233 回答
3

机器语言可执行文件的格式基于硬偏移,而不是解析字节流(如文本程序源代码)。当您在某处插入一个字节时,文件格式将继续引用原始偏移处插入点之后的信息。

偏移量可能发生在文件格式本身中,例如告诉加载程序文件中的内容位于何处以及它们有多大的标题。

硬偏移也出现在机器语言本身中,例如在引用程序数据的指令中或在分支指令中。

假设一条指令说“从我们现在的位置向下分支 200 个字节”,并且您在这 200 个字节中插入一个字节(因为您想要更改的字符串恰好在那里)。哎呀;分支仍然覆盖 200 个字节。

在某些机器上,即使您修复了分支,它甚至不能是 201 字节,因为它会错位并导致 CPU 异常;例如,您必须添加四个字节才能将其修补为 204(以及使文件健全所需的无数其他东西)。

于 2013-12-31T01:18:38.793 回答