OLLVM 基础学习
作者:FloatingGuy 转载请注明出处:https://floatingguy.github.io/
发现2017年代码混淆技术流行了起来,ios 和 android 上应用的都非常广泛。在这记录一下学习的一点新的,项目相关的案例要等项目接触,酌情选择一部分出来分享。
本文参考了:
Deobfuscation: recovering an OLLVM-protected program
(反混淆:恢复被OLLVM保护的程序) 帮助我快速入门OLLVM。
简介
OLLVM 混淆技术 & 恢复手段
原始案例:
混淆的点:
- 控制流混淆
- 基本块处理
控制流平坦化
这个概念我觉得是 OLLVM 使用的混淆技术里比较复杂的一种,不仅考验思路的严谨性,而且代码实现起来应该也很复杂。
特点
该技术 主要是针对 控制流的混淆,将原本很简单的执行流复杂化。原始条件被转换为CMOV条件传送指令,然后根据比较结果,在状态变量中设置下一个“相关块”。“相关块”就是没有经过混淆的函数的原始块。
采用该混淆技术以后,程序的流程变成了:序言->(进入循环)主分发器->..子分发器/相关块..->预分发器(进入一下轮循环)->返回块
看完上面的文字描述和 两张图以后,我其实还是挺模糊的。不理解如何保证自动化完成控制流的闭合,那么我就建议看看OLLVM 官方文档中关于Control Flow Flattening的描述。
混淆前的代码
123456789int main(int argc, char** argv) {int a = atoi(argv[1]);if(a == 0)return 1;elsereturn 10;return 0;}混淆后的 伪代码:
12345678910111213141516171819202122int main(int argc, char** argv) {int a = atoi(argv[1]);int b = 0;while(1) {switch(b) {case 0:if(a == 0)b = 1;elseb = 2;break;case 1:return 1;case 2:return 10;default:break;}}return 0;}
结合这个案例就清楚多了, 可以将混淆后的伪代码和混淆后的几个对象对应上了。序言
:3-4行主分发器
: #5 while 循环相关块
: 13-16行 混淆前就包含的逻辑子分发器
: #8 新增了一个判断条件,是控制流复杂预分发器
: #6, #9, #11 通过增加一个变量(b) 结合switch语句,是控制流的规模增加。
其实控制流平坦化
主要做手脚的部分就是子分发器
和预分发器
。通过在这2部分增加大量的无效逻辑干扰逆向人员静态分析。
恢复手段
这里我们需要一个符号执行工具来遍历代码,并尝试计算每个基本块的目标终点。当出现判断条件分支时,它将帮助我们尝试运行并获取所有分支可能到达的目标地址列表。Miasm框架包含有一个符号执行引擎(支持x86 32位等架构),其基于自身的“中间表示”(IR)实现,并且可以通过反汇编器转换二进制代码到“中间表示”(IR)。
虚假控制流
特点
该技术是对基本块进行混淆,创建一个包含”不透明谓词”的新代码块。
“不透明谓词”会生成条件跳转:可以跳转到真正的基本块或另一个包含垃圾指令的代码块。
我们可以同样使用前文中的符号执行方法,找到所有有用基本块并重建控制流。但还存在一个问题:“不透明谓词”,如果包含垃圾代码的基本块返回它的父节点块,这种情况下如果我们在符号执行过程中还按这个路径去跟踪,将导致陷入死循环。所以需要先解决“不透明谓词”问题,以避免垃圾代码块,直接找到正确的执行路径。
恢复手段
首先需要识别”不透明谓词”,Miasm框架仍然可以帮助我们完成简化不透明谓词的任务,因为框架包含了一个基于自身IR(中间表示)的表达式简化引擎。我们还需加深对不透明谓词的了解。
但是 貌似OLLVM项目中生成”不透明谓词”时存在一个bug, 具体请查看原文。
指令替换
特点
函数流程图“形状”没有改变,仍可以看到相同的条件分支,但是在“相关块”中,可以看到对输入值的计算过程变得更繁杂。
- 不修改 函数原始的控制流
- OLLVM项目把普通算术和布尔运算换为更复杂的操作。
从OLLVM项目官网上我们可以看到,根据运算符不同,有以下几种指令被替换:+, – ,^,| ,&
恢复手段
这个方法对于所有指令的替换恢复都是相同的。如果是在闭源的混淆器中,我们就必须手动找到它们,将所有OLLVM替换公式添加到Miasm简化引擎后,就可以得到简化过的控制流。
完整保护
特点
这种技术就是将上面 介绍的所有混淆技术:指令替换、虚假控制流、不透明谓词、控制流平坦化 全局添加进来,让所有的混淆手段相互叠加达到最大效果。比如 指令替换还可以针对不透明谓词的代码。
恢复手段
反混淆工具
反obfuscation LLVM(简称为OLLVM)的工具市面上已经有了很多家,我还没有来的急一一去评测,上文中介绍『恢复手段』时基本都是使用的Miasm 框架, 另外还有:
后续会带来 android & ios 平台 对抗OLLVM的案例。