OLLVM混淆


简介

OLLVM 是基于 LLVM 的开源项目,是 LLVM 的 IR 级别的混淆,所以只要是 LLVM 支持的平台就能够支持 OLLVM,它主要是提供一套开源的针对 LLVM 的代码混淆工具,以增加对逆向工程的难度。

OLLVM 的不同 Features 以及混淆效果

这种混淆技术的目标只是将标准二元运算符(如加法、减法或布尔运算符)替换为功能等效但更复杂的指令序列。当有多个等效指令序列可用时,随机选择一个。这种混淆相当简单,并且不会增加太多安全性,因为它可能通过重新优化生成的代码轻松删除,甚至 IDA 自身也会将其优化。然而,如果伪随机生成器赋予不同的值,也就是在运输中参杂随机数进去,这样指令替换会在生成的二进制文件中带来多样性。

从LLVM到OLLVM学习笔记 | Whitebird’s Home
OLLVM移植和使用 夏洛魂的个人博客

搭建

obfuscator-llvm 环境搭建,使用 nickdiego/ollvm-build这个 docker 环境进行 OLLVM 源码编译。

1
docker pull nickdiego/ollvm-build

然后下载源代码

1
2
git clone https://github.com/nickdiego/docker-ollvm.git
git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git

ollvm-build.sh的第150行添加DOCKER_CMD+=" -DLLVM_INCLUDE_TESTS=OFF"

最后执行ollvm-build.sh

1
2
chmod 777 ollvm-build.sh
sudo ./ollvm-build.sh ../obfuscator

编译完成后在 obfuscator/build_release 目录执行命令创建硬链接

1
2
sudo ln ./bin/* /usr/bin/
clang --version

混淆

控制流平坦化(Control Flow Flattening)

可用选项:

  • -mllvm -fla : 激活控制流平坦化
  • -mllvm -split : 激活基本块分割
  • -mllvm -split_num=3 : 指定基本块分割的数目
1
clang -mllvm -fla -mllvm -split -mllvm -split_num=3 hello.cpp -o hello_fla

虚假控制流(Bogus Control Flow)

可用选项:

  • -mllvm -bcf : 激活虚假控制流
  • -mllvm -bcf_loop=3 : 混淆次数,这里一个函数会被混淆3次,默认为 1
  • -mllvm -bcf_prob=40 : 每个基本块被混淆的概率,这里每个基本块被混淆的概率为40%,默认为 30 %
1
clang -mllvm -bcf -mllvm -bcf_loop=3 -mllvm -bcf_prob=40 hello.cpp -o hello_bcf

指令替换(Instruction Substitution)

可用选项:

  • -mllvm -sub : 激活指令替代
  • -mllvm -sub_loop=3 : 混淆次数,这里一个函数会被混淆3次,默认为 1次
1
clang -mllvm -sub -mllvm -sub_loop=3 hello.cpp -o hello_sub

通过 LLVM IR 生成多平台可执行文件,以控制流平坦化为例

1
2
3
4
clang -mllvm -fla -mllvm -split -mllvm -split_num=3 -S -emit-llvm hello.cpp -o hello_fla.ll

# 切换至Windows(提前安装好clang)
clang hello_fla.ll -o hello_fla.exe

去混淆

  • 使用符号执行脚本deflat的方式进行去混淆

  • 对于指令替换可以使用 D810 这个 IDA 插件进行操作,

例题

2024NewStar 0llvm

[RoarCTF2019]polyre

[UTCTF2020]llvm

[安洵杯 2019]game

2024极客大挑战 你干嘛