3

只是在阅读有关用于将二进制文件识别为汇编指令的不同算法反汇编程序的信息。在不同的反汇编程序中打开一个程序,一些将程序的特定部分显示为代码,而另一些将相同的部分显示为数据。所以我的问题是,如果反汇编程序混淆了操作码是指令还是数据,处理器如何确切知道如何处理该操作码?

我希望我的问题很清楚..提前谢谢..

4

2 回答 2

3

只是在阅读有关用于将二进制文件识别为汇编指令的不同算法反汇编程序的信息。

我假设你的意思是线性扫描与递归遍历 - 这里有一个有趣的页面

所以我的问题是,如果反汇编程序混淆了操作码是指令还是数据,处理器如何确切知道如何处理该操作码?

所以,问题的核心——他们不关心,也不关心。CPU 对数据与指令一无所知。这就是为什么您可以通过替换包含操作码的字符串来从缓冲区溢出执行堆栈上的输入。这可以通过将页面标记为不执行来解决,在这种情况下,如果指令指针(EIP/RIP)最终到达那里,处理器只会引发错误(基本上是在操作系统上抱怨)。

反汇编的挑战在于,您试图找出代码的结构,除了实际运行它之外的所有事情。解决这个问题的唯一方法是生成一个 x86 模拟器并使用它。

这被称为停机问题

于 2012-07-05T09:51:13.727 回答
3

处理器不知道它被要求执行的是代码还是数据。它可以是其中之一,也可以同时是两者。CPU 将尝试执行给定的任何内容。

如果执行失败,它会生成诸如“遇到无效指令”或“指令引用的内存不可访问”或“除以零”或操作系统将(希望)处理的“权限不足”等事件. 如果它知道如何解决问题(虚拟内存通常基于此机制),或者让应用程序处理此事件或终止应用程序,它将解决问题。

有不同的反汇编程序。有些是“愚蠢的”反汇编程序,因为他们不会尝试对可执行文件格式产生太多或任何意义,他们只会尝试对给出的任何内容进行反汇编。其他人将反汇编标记为代码的文件部分,他们将从入口点位置开始反汇编(每个可执行文件都有一个应该由 OS/CPU 开始执行的位置)并使用各种启发式方法进行合理的反汇编。

然而,拆卸几乎不可能完美地完成。正确反汇编的主要问题是反汇编程序不知道一段代码会做什么以及不会做什么。

例如,可以编写代码以便计算要跳转或调用的地址。反汇编器将无法计算这样的地址,因为它不执行、模拟或解释代码。因此反汇编程序可能无法确定下一个要反汇编的位置。

还有一些具有可变长度指令的 CPU。这使得代码可以跳转到指令的中间。反汇编程序应该如何反汇编那种代码?

另一种令人讨厌的做法是使用代码进行操作。代码可以在执行时即时更改自身。代码还可以生成更多代码。代码也可以存储为数据。你如何分解所有这些?

因此,许多反汇编程序仍然非常愚蠢也就不足为奇了。他们只是无法与编写各种曲折程序的程序员的脑力竞争。

编辑

此外,由于同样的可变长度指令问题,从稍微不同的位置开始反汇编相同的代码可能会产生不同的指令。

例子:

考虑 x86 处理器在 32 位模式下的这个字节序列:66h,0B8h,90h,90h,90h,90h。

如果你从第一个字节开始反汇编它,你会得到:

mov ax,9090h
nop
nop

如果您在下一个字节开始反汇编,您将获得:

mov eax,90909090h

如果您跳过另一个字节,您将获得:

nop
nop
nop
nop
于 2012-07-05T09:52:46.113 回答