恶意软件是一种招人恨的代码,因为它们专干坏事,如泄漏个人隐私、造成数据丢失,等等。而杀毒软件公司则不断想办法检测并阻止恶意软件。如此一来,猫和老鼠的大戏从此开演了。一般来说,杀毒软件要想防御某种恶意软件需要经过以下过程:收集到样本,分析样本,升级病毒库,之后杀毒软件才能够识别该恶意软件。而反检测技术,就是在恶意软件的分析阶段设置障碍,让分析人员无法或难以对恶意代码进行分析,这主要包括两类技术,一种是反调试技术,一种是反仿真技术,或叫做反虚拟执行技术。
无论是处于分析恶意软件的目的,还是防止软件被分析的目的,了解恶意软件常用的反检测手段都是很有必要的,而本文的目的就是在于,向读者们介绍目前的反调试和反仿真技术,并提供代码样本,以供读者在识别恶意代码时作为练手之用。
一、引言
病毒作者使用反调试与反仿真技术的目的在于为逆向分析恶意软件制造障碍,理想的情况下是使得逆向工程师无法分析恶意软件,退一步讲即使可以分析也会让分析过程更为缓慢。当病毒在一个仿真器或调试器中运行时,这些技术会使逆向工程过程变得举步维艰,他们企图以此逃避检查。恶意代码可以利用多种不同的方法来“忽悠”动态检测和其他如仿真器和调试器之类的分析机制,通常情况下每种病毒都会采用其中的一种甚至多种。
对于这些病毒作者用于使对病毒的逆向过程变缓的方法,本文将分别进行讲解,并为它们提供了示例。本文会概述各种反调试与反仿真技术,以使得读者对它们有所了解。下面我们开始介绍反仿真技术。
二、反仿真技术
仿真器为人们提供了一个受限制的环境(即安装在主机操作系统之上的操作系统的映像),我们可以在这个环境中动态地分析程序。例如,一台运行Linux操作系统的机器可以在其虚拟机上安装并运行Windows XP系统。一个仿真器也将包括对CPU和内存的仿真,以及其它硬件的仿真,还有控制器的仿真。这为我们提供了一种安全的方式来动态地分析程序,因为这种环境下,无论做什么都不会对底层的操作系统造成损害。
然而,这一系统也有其缺点。首先,花在仿真上的时间越多,在对目标程序进行实际分析之前所必须等待的时间也就相应越长。其次,仿真过程是缓慢的,因为不仅对目标程序实施监控需要开销,而且对操作系统和硬件进行仿真同样也需要开销。QEMU,一种硬件和操作系统仿真器,其仿真出来的硬件比物理硬件的速度有四分之一到十分之一之间的下降,软件在其上运行的速度只是在内存管理单元上运行时的二分之一。同时,因为QEMU不具备任何动态监控功能,这会进一步降低速度。最后一个缺点是,恶意软件可以利用各种反仿真技术来“忽悠”模拟器,这些技术分为三类:比耐力型、比智力型以及过度扩展模拟器。
三、跟模拟器比耐力
因为仿真的代价较高,所以模拟器通常只运行代码的前几百条指令来检测恶意软件,后面的指令通常不予理会。在英特尔的X86系统上,人们普遍相信,只要运行1000条指令便足以检测出恶意代码,同时还能保持较短的运行时间。如果在这段时间内没有运行被视为恶意的指令,那么模拟器就不会再将该代码作为恶意软件而继续检查。跟模拟器比耐力的方法有很多,如基于特定概率的感染技术,在运行恶意代码之前先将良性代码运行特定的时间,或通过入口点迷惑技术来达到目的。
1.概率式感染
一些恶意软件的恶意代码并不是每次都会执行,而是按照一定的概率发作。例如,某病毒在运行时执行恶意代码的概率是10%,这就意味着,模拟器将其运行若干次,才有可能检测到恶意代码。
2.运行良性代码
有的恶意软件会在每次启动时先运行良性代码,并且良性代码运行一段时间后,才开始运行恶意代码。这样做的目的是让模拟器运行指定数量的指令,让它觉得该代码在这段时间内没有做恶意的事情。等危险期过后,它就会露出本来面目:感染并危害系统。
3.入口点迷惑技术
入口点迷惑技术(EPO)是一种将附带的恶意代码放到一个文件的特定的部分的方法。恶意软件不会一上来就执行恶意代码,相反,它能查找对ExitProcess()API函数的调用,然后用一个跳至恶意代码的转移指令来覆盖这些调用。用这种方法,代码将在可执行文件的出口处,而非入口处运行。它还可以寻找一个特定的代码序列,然后用恶意代码本身或跳至恶意代码的转移指令来覆盖之。所以,入口点迷惑技术后,能够使病毒在将代码拷贝至新的位置之后、实际覆盖它之前运行恶意代码。