恶意软件中使用对抗反汇编的技巧

黑客技术 2019-03-15 07:18:41

恶意软件编写者们很可能利用某些特殊手段实施攻击,而恶意软件分析工具很难通过传统的静态分析机制(如IDA Pro)对其代码进行识别。利用这些经过精心设计的asm指令,恶意软件不会对程序的正常运行流程造成任何影响,但却能够混淆IDA Pro等静态分析工具对代码内容的正确解释。

遥想当年,市面上存在着两类反汇编算法——其一为线性反汇编,其二为流导向反汇编。不过前者在反汇编工具当中很少被用到。

因此这里我们要探讨的就是后者,也正是IDA Pro以及一部分恶意软件编写者们所使用的技术手段。

1.将指令跳转至常量值位置

这是恶意软件编写者/反汇编程序所爱使用的招数,即在同样的位置创建+1或者+2字节的跳转。这会导致系统产生完全不同的字节码解释结果。

举例来说,上图所示的跳转过程会让程序流直接转向箭头所指的字节码位置。

因为IDA Pro之类的工具并没有太高的智能性(无意冒犯其发明者),它当然没办法对此做出判断,因此在跳转之后opcode就从E8转移到了其它位置。这时,我们会看到调用指令指向了随机地址,使得运行结果完全意义不明。

我们可以利用IDA Pro轻松解决此类问题。只需在E8位置按下C键、在8B位置按下C键,解释结果就会恢复正常。

在交替按下C、D键之后,我们终于在IDA当中看到了如下图所示的正常结果:

不过现在出现的情况是,软件作者可能在代码当中插入了“流氓字节(rogue byte)”,并通过这种混淆方式让IDA Pro对其余opcode产生了错误解释。这是一项简单的技术,而且如果大家不喜欢E8这种丑陋的字节,也可以直接将其留空。

2.通过跳转让指令指向同一目标

在这种情况下,IDA Pro通常会根据其首先反汇编的条件指令(jnz)指向错误的条件指令分支,而后再移动至正确的部分。

通过以下恶意软件POV图示,我们可以看到jz与jnz都表现出类似的无条件跳转:

一旦IDA Pro到达jz指令,其会首先偏离并解释错误指令,而后重新回归jnz并再次偏离。在这里我们可以使用一项高明的伎俩,即插入一段流氓字节码从而使得反汇编工具将指令解释为调用。

如果我们在这里重复第1点中提到的C与D键操作,最终得到的代码结果如下图所示:

3.往来跳转

我不知道该怎样为这项技术命名,不过其本质就是利用第1点与第2点当中所描述的方法实现大量跳转。

下面让我们看看下图所示的“乱跳”状况:

经过一系列跳转,最终指向的loc_4012E6+2位置实际上就成了EB opcode。如果我们忽略66与B8 opcode,并让IDA对其余代码进行解释,那么得到的结果如下所示:

接下来再跳几次。

再次忽略其它E8字节并将其余部分作为代码解释,那么得出的结果如下图所示:

我们可以由此看到,流氓字节如何掩盖了其调用的实际函数并成功蒙蔽了静态分析工具的检测。

4.函数指针的使用

这一次我们不再使用屏幕截图,而是直接来看一段实际代码:

1
2
3
4
5

mov [ebp+var8],offset sub4211C1

push 4Ah

call [ebp+var_8]

以上代码的内容是,一项函数通过地址引用的方式被调用。以该函数调用为例,其通过使用某种奇怪的解码子程序获取到该函数字符串名称,并将值保存在偏移的sub4211C1位置。这会使静态分析机制丧失功能,因为IDA很难意识到这一状况。

从静态分析的角度来看,虽然这种作法不至于造成什么灾难性的后果,但在配合其它反汇编技术之后却可能给分析人员带来很大麻烦