一、OLLVM混淆工具
OLLVM是一种针对LLVM框架的混淆器,通过改变代码的结构和控制流程等方式来隐藏程序的真实逻辑,从而增加程序的安全性。
一般而言,混淆的目标包括:1) 使程序的静态分析变得困难,增加逆向破解的难度;2) 对抗动态分析,如反调试和反病毒软件等。
OLLVM的混淆层次可以分为三个:基本混淆、掩盖混淆和复杂混淆。其中,掩盖混淆指让分析人员无法轻易地发现控制流程,使程序难以静态分析;复杂混淆指在程序中添加大量虚假代码,使逆向分析者需要大量时间来区分真伪代码。
下面是一段基于Foo函数的基本混淆示例:
define i32 @Foo(i32 %0, i32 %1) { entry: %add = add i32 %1, %0 %cmp = icmp sgt i32 %add, 5 %sub = sub i32 %add, 1 %tobool = icmp ne i32 %add, 1337 %sel = select i1 %cmp, i32 %sub, i32 %add %ret = select i1 %tobool, i32 0, i32 %sel ret i32 %ret }
二、OLLVM技能
OLLVM不仅具有混淆功效,还有其他实用技能。
其中一项比较值得注意的技能是:增加对新硬件和新架构的支持。由于硬件和架构的升级变化不断,因此需要保持对新型号的兼容性。如果没有类似OLLVM这样的框架,代码的迁移或者编译调试会非常繁琐。
此外,OLLVM还支持目标平台的错误注入。这项技能的主要应用场景是:在程序执行的过程中,通过意外注入、修改,刻意制造错误,从而达到测试目的,可有效降低程序崩溃风险。
三、OLLVM台词
由于OLLVM经常用于程序混淆,其名字也被玩弄了起来,如下:
1、Oblivious LLVM(不知道的LLVM)
2、Offensive LLVM(攻击性的LLVM)
3、Onion LLVM(洋葱式的LLVM)
4、Obfuscating LLVM(混淆的LLVM)
当然,这里还有一些基于名字的“梗”(仅供娱乐):
1、LLVM is Everywhere, OLLeVM is Everywhere Also
2、Life is short, Use OLLeVM
3、Trust no one, trust OLLeVM
四、OLLVM加强
针对OLLVM的一些不足,研究者也开展了多项加强研究。
1、优化混淆策略,以更好地保护程序。例如,引入AST基于push/pull模型的控制流混淆,动态混淆等等。
2、增加正确性保证和安全性证明。是为了避免混淆过程中带来的副作用,例如混淆后程序无法运行,或者在混淆后易受攻击等问题。
3、为高阶编译器提供使用便利性。例如,加强对日常编程语言(如Python、Java、Rust、Go)的支持。
代码示例
以下是一段基于OLLVM的混淆代码示例:
int Foo(int a, int b) { int c = a + b; c = c > 5 ? (c - 1) : c; c = c != 1337 ? c : 0; return c; }
在经过OLLVM混淆后:
define i32 @Foo(i32 %0, i32 %1) { entry: %add_1 = add i32 %1, %0 %0x = and i32 %add_1, 0x7fffffff %shr_1 = ashr i32 %add_1, 31 %add_2 = add i32 %0x, %shr_1 %cmp = icmp sgt i32 %add_2, 5 %sub = sub i32 %add_2, 1 %0x_1 = and i32 %sub, 0x7fffffff %shr = ashr i32 %sub, 31 %and = and i32 %shr, -4 %tobool = icmp ne i32 %add_1, 1337 %sel = select i1 %cmp, i32 %0x_1, i32 %and %ret = select i1 %tobool, i32 0, i32 %sel ret i32 %ret }
可以看到,原有的代码被修改,并添加了很多无实际意义的指令,增加了逆向破解的难度。