之前遇到了很多次ollvm平坦化的题目,所以想学习一下,参照了很多前人的方法,特此记录一下。
环境vmware虚拟机,ubuntu20.04
ollvm定义 LLVM(Low Level Virtual Machine)是一个开源的编译器基础架构,它包含了一组模块化、可重用的编译器和工具,支持多种编程语言和目标架构,包括x86、ARM和MIPS等。LLVM的核心思想是将编译器分为前端和后端两个部分,前端负责将源代码转换为中间表示(IR),后端负责将中间表示转换为目标机器的汇编代码。这种设计使得LLVM可以支持多种编程语言,因为只需要为每种语言编写一个前端,就可以利用后端的通用性支持多种目标架构。
OLLVM(Obfuscator-LLVM)是瑞士西北应用科技大学安全实验室于2010年6月份发起的一个项目,这个项目的目标是提供一个LLVM编译套件的开源分支,能够通过代码混淆和防篡改,所使用的编译器是clang。
搭建ollvm环境ollvm github仓库
https://github.com/obfuscator-llvm/obfuscator git下载ollvm源码 git clone -b llvm-4.0 --depth=1 https://github.com/obfuscator-llvm/obfuscator.git 配置编译工具 cmake , gcc , g++ cmake去官网下载cmake或者直接sudo安装
sudo apt install cmake 安装 gcc-8 g++-8 降低版本查看gcc和g++版本,若为9则要降低版本

image-20240113195643948.png (102.39 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
安装gcc-8和g++-8 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切换版本 默认gcc 8 sudo update-alternatives --config gcc输入选择版本的数字

image-20240113200022936.png (145.9 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
g++切换版本 默认g++ 8 sudo update-alternatives --config g++

image-20240113200225611.png (139.97 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
修改ollvm源码进入 ollvm目录/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
定位到第690行 把char 改成 uint8_t
在config.guess文件中存在一些DOS行结尾(DOS line endings),需要将其转换为Unix行结尾。
sudo apt-get install dos2unix dos2unix obfuscator/cmake/config.guess

image-20240114123645849.png (56.3 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
编译 ollvm mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator/

image-20240114124017851.png (159.05 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
make -j4这个过程会很久
[ 97%] Built target llvm-objdump [ 97%] Linking CXX executable ../../bin/llvm-mc [ 97%] Built target llvm-mc [ 97%] Linking CXX executable ../../bin/llvm-dwp [ 97%] Linking CXX executable ../../bin/llvm-lto2 [ 97%] Built target llvm-dwp [ 97%] Built target llvm-lto2 make: *** [Makefile:152: all] Error 2可能是环境配置出了问题,编译到97%时就停止了,几个主要的clang文件都没编译成功
试了好几次都卡在这个

image-20240114173753408.png (34.68 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
如果卡住了,不要慌,不要删,继续make -j

image-20240114232004689.png (204.96 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
混淆两种方法,一种是配置ndk环境混淆,另一种是直接将clang作为程序进行混淆。推荐第二种,第一种无法控制混淆的方法。
注意,混淆时一定要采用gcc8和g++8,9以上的环境会混淆失败。
配置ndk环境执行命令,打开配置文件
gedit ~/.bashrc把下面这两行粘贴到文件末尾, 注意,替换路径成自己下载的ndk路径
export NDK_HOME=/home/bag/android/android-ndk-r16b/ export PATH=$NDK_HOME:$PATH最后执行命令,使配置文件生效
source ~/.bashrc 复制编译好的4个 clang 文件到ndk目录clang,clang++,clang-4.0,clang-format
粘贴到ndk目录
ndk目录/toolchains/llvm/prebuilt/linux-x86_64/bin 复制build目录的 3个头文件到ndk目录 fatal error 'Stddef.h' file not found fatal error 'Stdarg.h' file not found fatal error '__stddef_max_align_t.h' file not foundndk目录
android-ndk-r16b/sources/cxx-stl/system/include新建jni文件夹(名字改了的话在对应的配置文件得该指定路径方式)
在文件夹中新建Android.mk,Application.mk,try.cpp
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := bag LOCAL_SRC_FILES := try.cpp include $(BUILD_EXECUTABLE)Application.mk
APP_ABI := armeabi-v7a arm64-v8a APP_PIE := true APP_CPPFLAGS := -frtti -std=c++11 -mllvm -fla -mllvm -bcf -mllvm -subtry.cpp
#include<cstdio> int main() { int d; scanf("%d",&d); if(d==1)printf("d = 1"); else if(d==2)printf("d = 2"); else printf("not 1 or 2"); return 0; }在jni的上级路径,输入ndk-build

image-20240115000808138.png (80.63 KB, 下载次数: 0)
下载附件
2024-1-15 17:50 上传
混淆后的文件在libs内

image-20240115105209708.png (51.54 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传

image-20240115105259783.png (145.45 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传
clang混淆这里对源文件进行平坦化混淆处理。
来到build/bin目录下,将待混淆的源文件放在该目录下。
命令格式为
./clang -mllvm -fla 源文件 -o 目标文件 ./clang -mllvm -fla try.cpp -o try成功生成混淆后的文件,用ida查看效果

image-20240115132134904.png (80.75 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传
去平坦化 虚拟环境安装虚拟环境
pip install virtualenv配置环境变量
export WORKON_HOME=$HOME/.virtualenvs export PROJECT_HOME=$HOME/workspace source /usr/local/bin/virtualenvwrapper.sh打开虚拟环境
source ~/.local/bin/virtualenvwrapper.sh创建新的虚拟环境
mkvirtualenv demo展示当前虚拟环境
workon进入虚拟环境
workon demo 使用脚本由于脚本需要angr,在当前虚拟环境中安装
pip install angr脚本github地址:deflat: use angr to deobfuscation
将脚本中的am_graph.py和util.py文件复制到下级

image-20240115113143066.png (54.38 KB, 下载次数: 1)
下载附件
2024-1-15 17:51 上传
在ida中找到平坦化的入口地址,一般而言入口前都会存在大量var_(局部变量),下图入口地址为0x401140

image-20240115132230565.png (105.26 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传

image-20240115132332941.png (122.93 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传

image-20240115132452335.png (73.3 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传

image-20240115132612816.png (62.83 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传

image-20240115132654105.png (50.14 KB, 下载次数: 0)
下载附件
2024-1-15 17:51 上传
总结
定位入口地址
在./deflat-master/flat_control_flow/路径下启动虚拟环境
source ~/.local/bin/virtualenvwrapper.sh workon workon demo
使用去平坦化命令
python3 deflat.py -f filename --addr address(入口地址,一般为main入口) 参考文章OLLVM环境搭建-Ubuntu20.04_ubuntu配置llvm-CSDN博客
跟着铁头干混淆2 ubuntu20.04编译ollvm - 简书 (jianshu.com)
OLLVM 与去平坦化 &RoarCTF2019 polyre 详细WP









查看全部评分