编译环境:win10
所需工具:cmke,mingw,我用的都是最新的包
cmake的msi和exe 2选1就好了,下载后按照安装流程安装即可。
注意这里有一个坑,使用cmake-msi下载并添加到环境,win10会把原来的系统环境全部删除--
所以这里不要勾选把cmake添加到系统环境,手动添加。
我的部分系统环境截图:
一、下载
新建一个ollvm文件夹,git clone下载也可以,zip下载也可以
地址:https://github.com/obfuscator-llvm/obfuscator.git
网址:https://github.com/obfuscator-llvm/obfuscator/tree/llvm-4.0
命令下载:
git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
以下是我的目录,我采用的是zip下载,然后解压
二、编译
注意正确命令如下:
1.下载并编译ollvm
$ git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
这里下好了之后,需要字符串加密的,可以找到字符串加密的pass位置
这里写下简要流程:下载放到相应的位置去。
cpp文件: StringObfuscation.cpp
头文件:StringObfuscation.h
我的位置截图:
这里添加了StringObfuscation.cpp肯定要修改CmkeList.txt,不然没编译等于没加
CmkeList.txt,就在这个文件夹里,打开添加一行就好。
注意头文件要放在这里,地址看清楚不一样,在include目录下
到这里就加入了字符串加密并且变异了,可是加入了之后,如果代码里没有调用,也等于是白费。
添加调用代码。
在 IPO文件夹下有个PassManagerBuilder.cpp文件,打开
添加代码流程:
1) 添加引用
#include "llvm/Transforms/Obfuscation/StringObfuscation.h"
2) 找到如下函数,在下面加两个函数声明,实际上看代码就知道,是加了编译参数-mllvm -sobf
// Flags for 字符串混淆 ,这两个参数可以在cflag里面了,可以调用 static cl::opt
3) 在 PassManagerBuilder::PassManagerBuilder() 构造函数中添加随机数因子的初始化代码,实际只要搜索关键字PassManagerBuilder,然后很容易找到它上面也有一个Seed是空的
//添加随机数因子的初始化 if(!Seed.empty()) { if(!llvm::cryptoutils->prng_seed(Seed.c_str())) exit(1); }
4)将该pass添加进 void PassManagerBuilder::populateModulePassManager 中
MPM.add(createStringObfuscation(StringObf));
到这里终于搞定了字符串加密的相关内容了。就没有啥要准备的了,可以开始退出所有文件进行编译。
命令:或者直接新建打开cmd或者powershell就可以了
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/ 错误 X
正确:cmake.exe -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ..\obfuscator-llvm-4.0\
这里会编译,大概编译30分钟,没仔细计时,反正最后编译出来两个error,不过build/bin下面的clang++都在,感觉这两个error好像无伤大雅……
编译好了之后,再运行
$ make -j16 错误X
正确:mingw32-make -j16
至此,完成编译。bin目录下该有的都有。
三、使用
采用的是复制的方式
我是复制了toolchains路径下的 clang3.6然后重命名为下面这个
之后打开clang3.6-obfuscator中的setup.mk
只要该红框里面的东西,设置一个自己的build/bin地址,然后修改下
TARGET_CC和TARGET_CXX,保存退出即可。
四、使用
提供一个demo工程吧,简单看就很明白的。
bcf可以配合下面参数使用
-mllvm -perBCF=20: 对所有函数都混淆的概率是20%,默认100%
-mllvm -boguscf-loop=3: 对函数做3次混淆,默认1次
-mllvm -boguscf-prob=40: 代码块被混淆的概率是40%,默认30%
给某个函数单独加入混淆;注意注意经过我测试只有ollvm3.5和ollvm3.6可以使用单独函数加混淆
int main(int argc, char **args)__attribute((__annotate__(("bcf"))));
效果图附上:
反正一个小函数被混淆成这样。
原函数是
jint JNICALL Java_com_test_Test(JNIEnv *env, jclass t,jint k) {
int key = 8;
return key^k;//假设这是个算法
}
相关参考链接:
https://www.anquanke.com/post/id/86384
https://zhuanlan.zhihu.com/p/39322683
https://www.jianshu.com/p/4a43ca8a9b13