ollvm 小结
【1】https://github.com/obfuscator-llvm/obfuscator/tree/llvm-4.0
【2】https://github.com/heroims/obfuscator/tree/llvm-8.0
【3】https://github.com/GoSSIP-SJTU/Armariris
1. linux 环境下编译 【1】ollvm
本机下载 cmake
可以下载最新的 cmake,目前最新的版本是 3.19.1,但是在本机 linux 下编译的时候却出现 os 错误问题,最后更新 cmake 版本为 3.4.3 解决了问题。
https://cmake.org/download/
https://github.com/Kitware/CMake/releases
tar -vxf cmake-3.4.3.tar.gz
cd cmake-3.4.3
sudo make
sudo make install
cmake --version
#: cmake version 3.4.3
下载并编译 ollvm
git clone obfuscator-llvm-4.0..
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator-llvm-4.0
make -j8
编译没有问题的话,会在 .../build/bin
看到生成的文件,clang/clang++/clang-format 等;
验证混淆:
随便编写个 test.c 文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static char* checkchar(char* param) {
printf("checkchar param %s \n", param);
char* result = NULL;
if (param == NULL) {
return result;
}
int len = strlen(param);
int pid = getpid();
printf("checkchar len %d , pid %d \n", len , pid);
char cpid[16] = {0};
if (strstr(param, "123")) {
snprintf(cpid, 10, ",pid:%d", pid);
result = malloc(len + 20);
if (result != NULL) {
strcat(result, param);
strcat(result, cpid);
}
}
return result;
}
int testadd(int a1, int a2) {
printf("testadd a1 %d, a2 %d \n", a1, a2);
int out = -1;
if(a1 > 0) {
int t1 = a1 % 10;
out = t1 + a2;
}
return out;
}
int main(int argv, char** argm) {
printf("main in. \n");
if (argv != 2) {
printf("main argv %d \n", argv);
return -1;
}
char* param = *(argm + 1);
int a = testadd(4567, 6541);
printf("main a %d \n", a);
char* cc = checkchar(param);
if (cc != NULL) {
printf("main cc %s \n", cc);
free(cc);
}
return 0;
}
然后放到 /build/bin/ 目录下执行 ./clang test.c -o test -mllvm -sub -mllvm -bcf -mllvm -fla
生成 test 文件,使用 IDA 查看 test 可以看到已经混淆了;
2. 在 windows 下编译 【2】 ollvm
首先下载 cmake https://cmake.org/download/
,一键式安装,然后添加环境变量;
命令 cmake --version
查看安装状态;
编译 ollvm-8.0:
git clone obfuscator-llvm-8.0..
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator-llvm-8.0
然后使用 visual studio 打开 'build' 目录,在 vs 内进行编译生成;
导入 VS 后,然后双击 LLVM.sln 构建项目;
最后 选择项目生成,就开始编译了。
编译结束后 再 \build\Release\bin
下可以看到输出的文件;
导入 Android Studio 项目验证:
- 注意备份
- 将生成的 clang.exe clang++.exe clang-format.exe 文件拷贝到
D:\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin
路径下 - 构建 jni 项目,然后编译,此时应该会出现缺少 头 文件的问题,可以参考:
https://bbs.pediy.com/thread-258370.htm
https://www.codenong.com/cs105912803/
- 如果是 Android.mk 文件可以添加 flag 对整体项目进行编译:
LOCAL_CFLAGS := -mllvm -sub -mllvm -bcf -mllvm -fla
如果是 CmakeList 应该添加 :
android {
defaultConfig {
externalNativeBuild {
cmake {
cppFlags "-mllvm -fla -mllvm -sub -mllvm -bcf -mllvm -sobf -mllvm -seed=0xdeadbeaf"
}
}
}
如果是对于单个函数进行选择混淆,可以:
int foo() __attribute((__annotate__(("fla"))));
int foo() {
return 2;
}
也可以在要混淆的函数前加上:
__attribute((__annotate__(("bcf"))))
__attribute((__annotate__(("sub"))))
__attribute((__annotate__(("fla"))))
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {}
参考连接:
https://bbs.pediy.com/thread-258370.htm
https://goldsnow.github.io/2017/08/07/android-ollvm/
https://www.dazhuanlan.com/2019/11/21/5dd6108041479/
https://my.oschina.net/u/4350311/blog/3270925
https://blog.csdn.net/hzhdy/article/details/94737931
https://mabin004.github.io/2018/08/23/ollvm%E5%AD%A6%E4%B9%A0/
https://blog.csdn.net/qq_42237638/article/details/104905061
https://blog.csdn.net/weixin_38244174/article/details/82889725