业务部提来的需求,自觉搞不来所以随便试试~
之前找过一些资料,基本上可查阅的只有通过符号执行来反控制流平坦化的,即之前说过的TSRC的那篇文章
该文提供的脚本是基于纯PE控制流平坦化之上的,整体执行框架必须满足主分发器-子分发器-真实块-预处理器的流程才行
而实践发现ndk编译出的so,无论是x86架构还是ARM架构都不满足上述框架–cfg相当丑,并且全部没有所谓的预处理器
点了几个函数看,发现混淆程度都不相同,回头看OLLVM资料发现可能是加入了其他混淆选项中的虚假执行流
纯控制流平坦化中,原逻辑的判断全部通过真实块中的cmov来决定,因此可以直接将其patch为jz还原真实块之间的关系。而加入了虚假执行流的CFG中,部分、甚至所有的原始逻辑判断会脱离真实块,放到子分发器平级的部分。这样的处理一方面导致真实块判断标准需要修改–原来的脚本中判断真实块的标准是唯一分支指向预处理器
,而现在逻辑判断块是一个分支指向预处理器(即主分发器,因为ndk的OLLVM中全部没有预处理器),另一个分支指向一个控制参数改变的块。
最先提出符号执行的外网论文中没有提供代码,但是他的思路是控制流平坦化、指令替换、虚假执行流各自单独处理,复合起来后通过3个反混淆也能相应解决。而我这边还没有单独处理虚假执行流,因此直接面对混淆程度不同的样本,较难修改反控制流平坦化脚本使其能够通用处理。
如果要继续的话,思路是先解决虚假执行流,然后再复合到控制流平坦化中。
不过准备暂缓报告的时候发现家俊用了另外一种思路–IDA脚本。通过IDA的Hex-rays插件可以看出,无论是控制流平坦化还是虚假执行流,都用到了一个控制变量,控制流的方法都是对控制变量进行赋值和判断。那么根据赋值和判断,也可以建立真实块之间的联系。
区别在于,符号执行是通过模拟执行主分发器和子分发器的判断来获取真实块之间的关系,而IDA脚本是通过直接匹配控制流变量的相关处理来获取真实块之间的关系。
后者更加简单粗暴,不过我对IDA脚本的掌握程度还差得远orz手头事忙完好好学习一下这个思路吧