assembly - 反汇编程序显示不同的指令

标签 assembly operating-system reverse-engineering decompiling

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

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

最佳答案

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

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

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

然而,反汇编很难做到完美。正确反汇编的主要问题是反汇编程序不知道一段代码会做什么和不会做什么。

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

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

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

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

编辑:

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

例子:

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

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

mov ax,9090h
nop
nop

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

mov eax,90909090h

如果你再跳过一个字节,你会得到:

nop
nop
nop
nop

关于assembly - 反汇编程序显示不同的指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11341484/

相关文章:

c - 使用 GCC 中的 4 位 PowerPC CR0 寄存器

gcc - gcc 可以编译 x86 程序集还是只是链接它?

windows - 了解 Windows 中正在运行的进程的布局(段)的任何工具?

javascript - 如何从模型类型中检索数据?

performance - Perf overcounting simple CPU-bound loop : mysterious kernel work?

assembly - 谁将高级语言转换为汇编语言

java - 使用java时进程输入流有限制吗?

java - 信号能保证到达线程吗?

objective-c - 在分析从 Swift 编译的二进制文件时,是否可以找出没有符号的函数的 Swift 方法名称?

java - 将 Python 生成的 protobuf 转换为没有 .proto 文件的 java