LLVM-Obfuscator 可用于混淆程序的代码逻辑,本文介绍如何使用 LLVM-Obfuscator 进行代码逻辑的混淆。

1. 安装 VS Clang 组件

2. 编译 LLVM-Obfuscator

使用 heroims 的 Fork 版本:heroims/obfuscator

2.1 Clone 最新 13.x 分支

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

2.2 安装 mingw

https://github.com/niXman/mingw-builds-binaries/releases 下载 32 位和 64 位 MingW:

  • i686-12.2.0-release-posix-dwarf-msvcrt-rt_v10-rev2.7z
  • x86_64-12.2.0-release-posix-seh-msvcrt-rt_v10-rev2.7z

分别解压到不同的目录。

2.3 编译 64 位 LLVM-Obfuscator

打开 CMD,将 64 位 MingW 的 bin 目录添加到 PATH 环境变量:

1
SET PATH=%PATH%;C:\mingw64\x86_64-12.2.0-release-posix-seh-msvcrt-rt_v10-rev2\bin

在命令行进入 LLVM-Obfuscator 所在目录,开始编译:

1
2
3
4
5
6

mkdir build64
cd build64
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_CREATE_XCODE_TOOLCHAIN=ON -DLLVM_ENABLE_NEW_PASS_MANAGER=OFF -G "MinGW Makefiles" ../llvm
mingw32-make.exe -j8

2.4 编译 32 位 LLVM-Obfuscator

重新打开 CMD,将 32 位 MingW 的 bin 目录添加到 PATH 环境变量:

1
SET PATH=%PATH%;C:\mingw32\i686-12.2.0-release-posix-dwarf-msvcrt-rt_v10-rev2\bin

在命令行进入 LLVM-Obfuscator 所在目录,开始编译:

1
2
3
4
mkdir build32
cd build32
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_CREATE_XCODE_TOOLCHAIN=ON -DLLVM_ENABLE_NEW_PASS_MANAGER=OFF -G "MinGW Makefiles" ../llvm
mingw32-make.exe -j8

3. 用编译输出覆盖到 VS Clang

Visual Studio 的 Clang 位于C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm目录,分别将编译的 32 位和 64 位bin目录中的文件覆盖到 VS Clang 的bin目录中(注意:在覆盖之前,最好先备份)。

4. 设置环境变量

在编译完之后,将 32 位和 64 位 MingW 的bin目录路径都添加到 PATH 环境变量中。因为 VS 编译时会启动 clang.exe,而 clang.exe 需要依赖 MingW。

5. VS 工程配置

命令行其他选项如下:

1
-D__CUDACC__ -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH -mllvm -bcf -mllvm -bcf_prob=73 -mllvm -bcf_loop=1 -mllvm -sub -mllvm -sub_loop=5 -mllvm -fla -mllvm -split_num=5 -mllvm -aesSeed=DEADBEEFDEADCODEDEADBEEFDEADCODE

6. 混淆配置参数

开启控制流扁平化

-mllvm -fla 开启控制流扁平化

-mllvm -split 激活基本块划分。一起使用时能提高打平能力。

-mllvm -split_num=3 如果激活控制流打平,对每一个基本块应用三次控制流打平。默认使用 1 次。

开启指令替换

-mllvm -sub 开启指令替换

-mllvm -sub_loop=3 如果激活了指令替换,使用这个选项在一个函数中应用 3 次指令替换。默认应用 1 次。

开启虚假控制流

-mllvm -bcf 开启虚假控制流。

bcf可以配合下面参数使用:

-mllvm -bcf_loop=3 设置函数混淆次数为 3 次 不加此选项默认为 1 次。

-mllvm -bcf_prob=40 设置代码块被混淆的概率是 40%,默认 30%

7. CMakeList 中配置混淆参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#debug and release all enable
SET(CMAKE_CXX_FLAGS "-mllvm -fla -mllvm -sub -mllvm -sobf ")

#so体积优化,(按需开启)
#SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
#SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -Os -Wall -s")

#设置llvm debug模式混淆编译
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -fla")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mllvm -fla")

#设置llvm release模式混淆编译
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mllvm -fla -mllvm -sub -mllvm -bcf")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mllvm -fla -mllvm -sub -mllvm -bcf")

SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s -O3 -Wall -fvisibility=hidden -mllvm -fla")