一、前言
最近在学习《看雪》课程的时候,老看见hanbing大佬在操作时,对着某个文件加几行代码就实现了so文件的ollvm混淆,我很好奇,混淆so文件为啥这么简单??于是就去研究研究,最终也实现了
- mllvm -fla:控制流扁平化
- mllvm -sub:指令替换
- mllvm -bcf:虚假控制流程
- mllvm -sobf: 字符串加密
选择在liunx环境中搭建,因为参考网上大佬所说,在windows下会出现一个无法解决的问题,所以,还是选择Linux环境吧
二、环境准备
- Ubuntu 虚拟机20.04版本
- 需要安装gcc , g++, git ,cmake
(其他三个可以sudo apt install ,但cmake似乎不太行,直接安装版本太低,最后编译到99%的时候老是弹出make error 97***)
- ndk版本(选21.0.6113669吧,或者22版本的也行,重点!不然后面替换文件会报一个not find library lgcc,找半天没有解决,估计是clang文件里面的导入文件的错误)
ndk版本
就像上面看见的一样,gcc 和g++都选择的是9.4.0,cmake是最新的3.26.0,ndk选择21.0.6
三、cmake编译安装
网上虽然有相关的教程,但自己也写写吧,
安装cmake时,还是应当先安装gcc和g++,
1、从官网下载cmake最新安装包
下载地址:https://cmake.org/download/ ,选择 Linux 版本
2、解压编译
将下载下来的文件复制至虚拟机,位置随意,并解压
两次压缩,第一次解压用gunzip命令
第二次解压用tar 命令
进入解压后的文件夹,并执行以下命令
cd cmake-3.26.0
sudo .bootstrap
make
sudo make install
执行sudo make install 应该会报错could not find OpenSSL,缺少openssl,执行
sudo apt install libssl-dev
再次执行sudo make install就没有问题了,最后执行
cmake --version
出现版本号即没有问题,继续下一步
四、SDK环境配置
Ubuntu20.04中安装Android Studio 还是挺简单的,从官网下载Linux 安装包并解压,在bin文件夹中执行./studio.sh就可以啦
但SDK环境配置也是一个问题,配置错误会出现adb not found,那么,开始配置环境吧,
执行命令:
sudo echo "export PATH=$PATH:/home/jearry/Android/sdk/platform-tools" >> ~/.bashrc
其中/home/jearry/Android/为安装目录。如果不知道自己当前目录的完整路径,执行
pwd
就可以啦。执行完命令后,关闭命令窗口。重新打开后再次执行adb devices,这样表示成功
其中,查看配置文件的命令为
sudo gedit ~/.bashrc
执行sudo echo 就是在该文件中插入export 语句
五、下载并编译ollvm9.0.1
网上所说的那些ollvm4.0似乎已经过时了,更新也比较少,零零散散还是有一些22年的
编译一个9.0.1的目前也够用了。
github上地址是https://github.com/obfuscator-llvm/obfuscator 只不过仅更新到llvm的4.0,2017年开始就没在更新。最新的9.0.1等版本均是后来大神修改出来的分支,参考着用吧。
下载:
git clone https://github.com/heroims/obfuscator.git
# 没有安装git的,执行
# sudo apt update
# sudo apt install git
编译:
cd obfuscator
git checkout llvm-9.0.1 #切换分支至9.0.1
mkdir build #新建目录
cd build
# 执行编译
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_CREATE_XCODE_TOOLCHAIN=ON ../obfuscator/
make -j7
编译中遇到的问题:进度80%多的时候,一直出现这个问题,最后去找到了,解决方法
Makefile:876: recipe for target 'all' failed
make: *** [all] Error 2
执行
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator
解决啦,编译成功后,
编译成功后,主要关注是两个文件夹,一个是bin,一个是lib,
六、替换文件
其实就是将源NDK中的文件,替换成自己编译后生成的文件,主要替换bin和lib中的文件。
将编译目录build/bin文件夹中的文件clang、clang++、clang-9、clang-format
复制ndk/21.0.6113669/toolchains/llvm/prebuilt/linux-x86_64/bin文件夹中,有相同的文件就进行替换。
还有将编译生成的头部文件替换到ndk中,不然Android Studio 编译时会提示找不到stddef.h文件
将编译目录/build/lib/clang/9.0.1/include文件夹中的下列这些文件
stdarg.h
stddef.h
__stddef_max_align_t.h
float.h
复制到ndk/21.0.6113669/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include文件夹中。
到这儿就OK啦。
最后只是到Android Studio 中新建一个带有c++的apk项目就行啦
注意,替换后编译失败,有可能是因为文件权限问题,需要赋予复制过来的文件777权限
七、CMakeList.txt文件
Android Studio 中新建一个带有c++的项目,在CmakeList.txt文件中添加指令
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -fla -mllvm -split -mllvm -split_num=3")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mllvm -fla -mllvm -split -mllvm -split_num=3")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -sobf")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mllvm -sobf")
其中,ollvm9.0.1支持
- mllvm -fla:控制流扁平化,最直观的感受就是简单的if-else语句,被嵌套成了while-switch语句,出现了很多干扰无用的分支,增加阅读难度。
- mllvm -sub:指令替换,主要是将正常的运算操作(+,-,&,|等)替换成功能相等但表述更复杂的形式。
- mllvm -bcf:虚假控制流程,表示使用控制流伪造模式,也是对程序的控制流做操作。BCF模式会在原代码块的前后随机插入新的代码块,新插入的代码块不是确定的,然后新代码块再通过条件判断跳转到原代码块中
- mllvm -sobf: 字符串加密,就是代码中出现的字符串进行替换,
另外还可以设置 这些指令出现的频率、次数等等。
参考网站:https://www.cnblogs.com/zhangshenghui/p/12001739.html
八、效果样图
(原)控制流图
(原)函数中的字符串
(混淆后)控制流图
(混淆后)字符串
(混淆后)控制流扁平化