为什么不可能进行真正的仿真?

逆向工程 二元分析 仿真
2021-07-01 20:47:58

防病毒软件和类似的分析引擎经常面临识别文件是否有害的问题。他们经常使用(部分)模拟来这样做,因此经常成为二进制文件使用的技巧(反模拟)的牺牲品。是否有可能将二进制文件模拟到无法执行的程度确定它是否在虚拟环境中运行?

1个回答

问题放错了地方

你问错了问题。字面上地。问题绝不是为什么它不可能(在许多情况下可能的)。更好的问题是:为什么它不实用?

不过,问它很有趣。

为什么不使用硬件辅助虚拟化?

首先,我过去曾与某些同事(我在 AV 行业工作)发生过争论,并试图在某些硬件虚拟化方法中解决这个问题,与自己的仿真实现相比,您可以在不损失安全性的情况下提高速度。其中一些同事认为,我们绝不能在没有气隙的机器上本地执行恶意软件。我个人认为这是一个有问题的陈述,因为恶意软件的现有扩散以及今天的硬件虚拟化功能无论如何都提供(接近)本机执行。但我想这最终是一个品味和政治问题。

除此之外,您必须拥有对系统的特权访问才能控制管理程序。这在文件系统过滤器的上下文中可能很好,它在内核模式下运行,但在其他纯用户模式场景(如命令行扫描程序)中不会是一个选项。

然后你只是“模拟”了机器,而不是正常运行无害或恶意代码的(操作系统)环境。

AV 中的速度很重要

然而,关于实用性,问题主要归结为速度。如果您认为 AV 文件系统过滤器至少扫描每个对象一次,那就太多了。

现在,AV 引擎通常会尝试确保某些可执行的打包程序有静态解包程序,这样就不必对其进行模拟等等。在进入仿真之前,还有其他启发式方法和静态方法。

但在这种情况下,即使只是部分,整个扫描文件中仍有相当大的一部分需要模拟。由于仿真通常至少比本机执行慢一个数量级,因此即使最终只仿真了整个代码的一部分,这也会很快加起来。

模拟哪个系统?

现在这从表面上看似乎很容易。总是模仿你正在运行的那个。

那么问题就变成了如何将整个操作系统安装放入您的引擎中。现在您可能会反驳:“为什么不使用正在运行的操作系统的库”,对此我会回应说,这仅适用于上述特定用例。但是,在 AIX 下的 PowerPC 上运行时,如何模拟 Win32 API?或者在您的 ARM 处理器上的 Android 手机中?

我们的扫描仪预计将运行在各种操作系统和处理器架构上,这限制了在扫描文件/对象时保持必要速度的可能性。

模拟器应该多接近真实环境的行为?

如果您曾经尝试过ReactOS——一个开源项目,旨在重新实现 Windows XP 和 2003 Server 的二进制接口,真正做到最后的细节——除了 CD 映像上的内容之外的任何东西,你就会知道它拥有所有各种故障。Wine也有很多小故障(ReactOS 和 Wine 共享很多代码)。

AV 仿真通常比 Wine 需要更多的捷径,因为很多功能不是必需的。让一个函数成功或失败,这很好。问题在于 Win32 API 的非常精细的细节。有很多这样的。

Windows 95、98、Me、NT 4、2000、XP、2003、Vista、2008、7、2008 R2、8、2012、8.1、2012 R2

...然后你也应该关心 Linux 和 Mac 恶意软件?以及其他情况,例如某些硬件配置(想想 Stuxnet 以及它如何“绑定”到某些 USB 密钥)。

基本上,如果您“模拟”一个可执行文件以找到某些恶意或良性指标,那么您的要求与模拟整个操作系统或可以像运行在真实硬件上一样运行操作系统的机器时的要求是不同的。

结论:一个近似值就足够了

因此,真实环境的近似值通常就足够了。此外,您应该记住,许多逃避尝试本身都可以被检测到,是可疑的,并且会引发标记。