到现在为止,我们基本上已经有了重构代码流程的所有信息,再梳理一下的话,我们现在对于一个经过混淆过的程序,目前掌握了以下两点信息:
目前我们还差一步,那就是我们目前还不知道对于一个给定的基本代码块,它的下一个执行节点是什么,也就是我们需要确定一个基本代码块执行完毕的时候,它把状态机的值改成了什么。为了完成这个目标,我们就要借助Binary Ninja的另一个很重要的特性,Value-Set分析,通过这个分析,可以知道某个寄存器或者内存位置里面的值是什么(译者注:相当于一个值跟踪系统,有点模拟执行的味道),有了这个,我们也可以确定出来最后状态机的值了。
大致逻辑就是:
回头观察上图中的SSA-MLIL, 我们看下高亮的语句部分,其实就是在两个不同版本的nextState变量之间进行选择,而且每个不同版本的nextState后面跟着一个数字作为版本号标志,再根据我们分析的逻辑,版本号小的那个就是false,版本号大的是true.最后借助于Ninja的Value-Set分析,我们就可以得出最后的nextState的最终值,所以就能确定下一个要执行的基本块是哪个了,还是上代码:
在我们目前获取的所有原始代码块里面,还包含了当时LLVM Obfuscator插入的一些框架代码,比如更新状态机的代码,这个代码现在对我们来说是垃圾代码了,因此需要清理掉这些代码了,正好用这些代码的空闲位置来插入一些我们的代码块连接指令,我整理了一下,下面这三种类型的指令都可以删掉了:
为了直观一点,继续给例子吧,下图中凡是标红的指令都是要删除掉的了,没用了:
使用插件来还愿代码只需要2步:
下面是一个演示视频:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课