欢迎光临散文网 会员登陆 & 注册

[How2DEOBF] #2 控制流混淆

2023-06-25 17:33 作者:Ezlips_yume  | 我要投稿


        在前一篇专栏中,我们已经简单了解了关于反混淆的一些内容。在本篇专栏中,我们将针对控制流混淆进行简单的分析。控制流是指按一定的顺序排列程序元素来决定程序执行的顺序,在大部分混淆器中,为了使目标程序的执行逻辑更加难懂,会进行控制流混淆。

        控制流混淆的方法有很多,可有Exception Jump,FLA,Bogus Jump乃至GEN3(Skidfuscator)之类,后又会有实现细节上的偏差,可能有些甚至叫法都不固定(比如存在JunkJump这种称呼),比较杂乱。          

        但人的脑袋总归是有限的,很多控制流混淆都有共通的解法。这里,我们将对一个简单的控制流混淆进行反混淆,从而初步展现一种解决思路。

分析

        还是以这个目标程序为例,这次我们使用Caesium混淆器为程序添加了一个控制流混淆。

混淆前

        

混淆后

        对比之后我们发现,原来的GOTO竟然变成了这一段奇怪的东西。

        由于没有使用Renamer,这个Getstatic指令所获取的field显然是混淆器生成的(1362525270),那么这到底是什么呢?

        为了搞清楚,让我们查看一下它。

对应的field

        看起来,它似乎被指定了初始值。对整个程序查验之后,也没有发现对它的修改指令。这样,我们可以确定它是一个不变的量,那么上面那一段的执行结果也就确定了:1 %5Cneq%20 0,所以会跳转到Label 8的位置,也就与混淆前的GOTO执行效果一致了。

        好,这样我们也就进行反混淆了——那当然没那么简单。

        让我们看看类似的混淆还在哪些地方被运用了——

另一情况

        先前的情况是IFNE,而这里则是IFEQ,如果我们像刚才那样想当然认定只有一种情况,那反混淆的结果就是不完全的,因此,在分析时,应当考虑可能的多种情况。虽说我们可以等反混淆一次之后再分析查验,不过这实在是不够优雅(强迫症)。

        保持着谨慎的态度,我们继续分析,果然又有新的发现。

int类型

        仿照对于最初的那种情况的思路,我们也发现,这个IFGE执行结果也是依赖于一个固定的int类型的field。

        这下不好,是否还存在其他可能的跳转呢?

        于是,偷懒的我们悄悄看了一下混淆器的源码。

混淆器是如何生成跳转的

        看来我们分析的确实比较到位,四种情况里考察到了三种(事实上示例程序确实不存在第四种情况)。

        现在我们可以掌握思路了,这个控制流混淆实质上就是把GOTO拆成4个效果等价的instructions,其中前两个负责跳转,后两个则是异常处理。我们只要对所有这种形式的跳转分析并修改为初始的跳转语句,就可以完成反混淆。

实现

        说了这么多,总算进入正题了,这次我们仍然使用与上一篇专栏同款的反混淆器编写Transformer。

        遍历所有class的method,并匹配这种跳转。

匹配

        我们知道这些跳转实质上都是GOTO,所以全部替换成GOTO就完事了。

替换

        等等,我们似乎少了什么。

        没错,还有那些混淆器生成的field需要去除,虽然这些东西对最后反混淆的结果几乎没有影响了,但是谁叫我们是强迫症呢。

        让我们记录下这些跳转时使用的field,然后最后再清除它们。

        最后完整的代码差不多是这样:

示例

        运行之后,成功去除了控制流混淆。

后记

        以上便是一个简单的控制流混淆的处理流程。在处理这种混淆时,尤其要留心观察,考虑多种情况,而且不能暴躁(那就更难想到好的处理策略了)。要想提升分析能力,只能够多多实践,可以自行寻找一些样本或是混淆器进行尝试。

        下载示例程序:https://wwcx.lanzoum.com/b032jht7i(5080)


[How2DEOBF] #2 控制流混淆的评论 (共 条)

分享到微博请遵守国家法律