OLLVM

LLVM 是一个开源的编译器架构,利用虚拟技术对源代码提供现代化的、与目标无关的、针对多种 CPU的,代码优化和代码生成功能。

LLVM 核心库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。

LLVM 三段式架构:

  • 前端:解析源代码,由语法分析器和语义分析协同工作,检查语法错误,并构建语言的抽象语法树来表示输入代码, 然后将分析好的代码转化为 LLVM 的中间表示 IR (IntermediateRepresentation) 。

  • 优化器:通过一系列的 Pass 对中间代码 IR 进行优化, 改善代码的运行时间使代码更高效。

  • 后端:负责将优化器优化后的中间代码 IR 转换为目标机器的代码

image-20240124130149036

OLLVM(Obfuscator-LLVM) 是瑞士西部应用科学大学安全小组于 2010 年 6 月发起的一个项目。该项目的目的是提供一套开源的基于****LLVM的代码混淆工具,通过代码混淆和防篡改提供更高的软件安全

性。

OLLVM 工作在 LLVM IR 中间表示层,通过编写Pass来混淆****IR, 后端依照 IR 转换的目标机器的代码也就达到了混淆的目的。

OLLVM 提供了三种混淆模式:

  • 指令替换 (Instructions Substitution)

  • 虚假控制流 (BogusControl Flow)

  • 控制流平坦化 (Control Flow Flattening)

正向使用

编译 ollvm

编译环境为 ubuntu 20.04,先下载 ollvm 源码:

1
git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git

然后修改 obfuscator/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h 文件第690 行,将 Expected<std::vector<uint8_t>> 改为Expected<std::vector<unsigned char>>

接着降低 gcc 版本,执行如下命令:

1
2
3
4
5
sudo apt-get install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9

切换 gcc 与 g++ 的默认版本

sudo update-alternatives –config gcc

sudo update-alternatives –config g++

在 obfuscator 目录下执行如下命令,开始编译:

1
2
3
4
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../
make -j7

编译完成后,在 obfuscator/build/bin 目录下会产生很多可执行文件,将这个路径添加到环境变量即可。

使用 ollvm

指令替换

通过功能上等价的但更复杂的指令序列, 替换标准二元运算符(如加法、 减法或布尔运算符), 当有

多个可用的等效指令序列时, 随机选择一个。

编译选项:

1
2
-mllvm -sub: 激活指令替代
-mllvm -sub_loop=3: 混淆次数,一个函数会被混淆3次,默认为1

混淆前后对比

image-20240124130430375

指令转换:

Addition

  • a = b - (-c)

  • r = rand (); a = b - r; a = a + b; a = a + r
    
    1
    2
    3

    - ```
    r = rand (); a = b + r; a = a + c; a = a - r
  • a = -(-b + (-c))
    
    1
    2
    3
    4
    5
    6
    7

    Subtraction

    - `a = b + (-c)`

    - ```
    r = rand (); a = b - r; a = a - c; a = a + r
  • r = rand (); a = b + r; a = a - c; a = a - r
    

AND

  • a = b & c => a = (b ^ ~c) & b

OR

  • a = b | c => a = (b & c) | (b ^ c)

XOR

  • a = a ^ b => a = (~a & b) | (a & ~b)

虚假控制流

通过在当前基本块之前添加基本块来修改程序的控制流图,原始的基本块也会被克隆,并插入随机的垃圾指令。

编译选项:

1
2
3
-mllvm -bcf: 激活虚假控制流
-mllvm -bcf_loop=3: 混淆次数,一个函数会被混淆3次,默认为1
-mllvm -bcf_prob=40: 每个基本块被混淆的概率,当前每个基本块被混淆的概率为40%,默认为30%

image-20240124130457258

控制流平坦化

消除正常程序控制流中基本块的相互关联,使用一个集中的主分发块来调度基本块的执行顺序,得到一

个循环嵌套Switch的执行逻辑。

image-20240124130521676

image-20240124130535132

序言:函数的第一个执行的基本块主(子)分发器:控制程序跳转到下一个待执行的基本块

retn块:函数出口

真实块:混淆前的基本块,程序真正执行工作的版块

预处理器:跳转到主分发器

编译选项:

https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flattening

1
2
3
-mllvm -fla: 激活控制流平坦化
-mllvm -split: 激活基本块分割
-mllvm -split_num=3: 指定基本块分割的数目

angr安装

关于angr的一些题目:https://www.cnblogs.com/level5uiharu/p/16925991.html