加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 安全 > 正文

针对常见混淆技术的反制举措

发布时间:2022-04-29 11:09:31 所属栏目:安全 来源:互联网
导读:现代软件经常将混淆技术作为其反篡改策略的一部分,以防止黑客逆向分析软件的关键组件。他们经常使用多种混淆技术来抵御黑客的攻击,这有点像滚雪球:随着雪层的增多,软件规模也随之变大,使其逆向分析难度随之提高。 在这篇文章中,我们将仔细研究两种常见
  现代软件经常将混淆技术作为其反篡改策略的一部分,以防止黑客逆向分析软件的关键组件。他们经常使用多种混淆技术来抵御黑客的攻击,这有点像滚雪球:随着雪层的增多,软件规模也随之变大,使其逆向分析难度随之提高。
 
  在这篇文章中,我们将仔细研究两种常见的混淆技术,以了解它们是如何工作的,并弄清楚如何去混淆。
 
  概述
  这里,我们将研究以下混淆技术:
 
  基于IAT导入表的混淆技术
 
  基于控制流的混淆技术
 
  基于IAT导入表的混淆技术
  在深入介绍基于IAT导入表的混淆方法之前,先让我解释一下导入表到底是什么。
 
  什么是导入函数?
  当进行逆向分析时,需要弄清楚的第一件事,就是它如何调用操作系统的函数。在我们的例子中,我们将重点关注Windows 10系统,因为大多数视频游戏只能在Windows系统上运行。无论如何,对于那些还不知道的人来说,Windows提供了一系列重要的动态链接库(DLL)文件,几乎每个Windows可执行文件都会用到这些库文件。这些DLL文件中保存了许多函数,可以供Windows可执行文件“导入”,使其可以加载和执行给定DLL中的函数。
 
  现在读者可能会问,知道这些有什么意义呢?好吧,如果您把一个二进制文件扔到像IDA这样的反汇编器中(我通常会做的第一件事),就是检查所有导入的函数,以便对二进制文件的功能有一个大致的了解。例如,当ws2_32.dll存在于导入表中时,表明该二进制文件可能会连接到Internet。
 
  现在,我们可能想要进行更深入的研究,并考察使用了哪些ws2_32.dll函数。如果我们使用Socket函数并找出它的调用位置,我们就可以检查它的参数,这样,我们就可以通过搜索引擎查找相应的函数名,从而轻松地找出它所使用的协议和类型。
 
  注意:IDA已自动向反汇编代码中添加了注释。
 
  经过混淆处理的导入表
  无论如何,这些Windows函数能提供相当多的信息,因为它们是有据可查的函数。因此,攻击者希望能够把这些函数藏起来,以掩盖正在发生的事情。
 
  我们在反汇编器中看到的所有这些导入函数都是从导入地址表(IAT)加载的,该表在可执行文件的PE头文件中的某个地方被引用。一些恶意软件/游戏通常试图通过不直接指向DLL函数来隐藏这些导入地址。相反,他们可能会使用一个蹦床或迂回函数。
 
  考察我们的示例
  在这个例子中,我们使用的是一种蹦床式混淆技术,具体如下所示:
 
  下面的地址0x7FF7D7F9B000引用了我们的函数0x19AA1040FE1,尽管看起来完全不是这么回事。您可能认为这是垃圾代码,但仔细看看,您会发现并非如此。
 
  请仔细查看前两个指令:前面的指令是mov rax, FFFF8000056C10A1,后面的指令是jmp 19AA1040738,后面的都是垃圾指令。不管怎样,让我们跟随跳转指令,看看它会跳到哪里:
 
  看,又是4个有效的指令,这次是一个异或指令和两个加法指令,然后是另一个跳转指令。让我们把这个过程再重复几遍...
 
  最后,我们来到jmp rax指令!需要注意的是,所有的XOR、SUB和ADD指令都是在Rax寄存器上执行的,这意味着它可能包含导入函数的实际指针。下面,让我们算算看。
 
  实际上,在经过数学运算之后,我们得到了指向advapi32.regopenkeyexa的指针!
 
  现在,我们所要做的就是重复几百次运算,从而彻底消除针对IAT导入表的混淆处理。
 
  基于控制流的混淆技术
  在逆向分析二进制文件时,另一个有价值的信息来源是汇编指令本身。对于人类来说,它们可能难以理解,但对于像IDA这样的反编译器来说,我们只需按下F5键,IDA就会生成我们人类可以理解的伪代码。
 
  混淆实际指令的一个简单方法,是组合使用垃圾代码和不透明分支(即该分支条件总是为不成立,也就是说,该分支用于也不会被执行)。这意味着:把垃圾代码放在一个分支指令之后。诀窍在于,我们可以使用条件转移,但是,要确保条件永远为真,这样分支就会一直被执行。反汇编器不知道的是,条件跳转在运行时总是为真,这使得它相信条件跳转的两个分支都可以在运行时到达。
 
  看到我在左边画的那个蓝色小箭头了吗?右边显示的就是这部分内容的放大版本。现在看一下右边,在函数的一小部分中就有七个去混淆的跳转。想象一下,以手动或半自动方式去混淆得需要多少时间。实际上,就算用IDA脚本手工完成这个过程,也花了我40分钟……这还只是处理了一个函数。设想一下,为了找到真正要找的东西,还得需要处理多少其他的函数呢?!
 
  基于控制流的自动去混淆技术
  好了,现在我们已经考察了基于控制流的去混淆原理,接下来,我们将对这个过程实现自动化。正如我之前提到的,我们曾经用IDA脚本来修补无条件跳转指令,并将垃圾指令替换为NOP指令。
 
  然而,这个去混淆过程还是花了我40分钟,因为识别不透明的分支非常费劲。那么,我们该如何解决这个问题呢?大家可能认为应该检查每一个条件跳转指令,并检查它是否是不透明的,如果是的话,就用NOP替换它,然后重复上述过程,对吧?错了!
 
  让我告诉你一个秘密,我们并不关心什么是不透明的,或诸如此类的事情。我真正关心的是,当我按下F5键时,IDA能否返回反编译好的代码——只要这些经过混淆的跳转指令导致垃圾指令与实际的汇编指令发生冲突,这种情况就不会发生。
 
  但这是否意味着我们需要弄清楚一个条件跳转是否是不透明的呢?不,我们只需检查跳转操作是否与现有的指令相冲突,如果是的话,就对这个指令进行相应的修改,就像我们第一个例子中看到的那样。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读