Ollvm混淆与反混淆: Goron框架编译与使用
很多App实现的定制ollvm框架中都有goron框架的影子,或多或少的借鉴了它的功能,包括
间接跳转,并加密跳转目标(-mllvm -irobf-indbr)
间接函数调用,并加密目标函数地址(-mllvm -irobf-icall)
间接全局变量引用,并加密变量地址(-mllvm -irobf-indgv)
字符串(c string)加密功能(-mllvm -irobf-cse)
过程相关控制流平坦混淆(-mllvm -irobf-cff)
想要了解怎么针对这些混淆功能完成去混淆,势必要先对其混淆过程有所了解,那么第一步就是对goron框架的编译使用
一、环境配置
环境:MacBook Pro 16G
cmake:cmake version 3.26.3
Android Studio NDK:21.1.6352462
二、编译过程
2.1 工程选定
git clone https://github.com/amimo/goron.git cd goron git checkout llvm-9.0.0
2.2 编译
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/You/Install/Dir/llvm-project-install -S llvm -B build cmake -B build -- -j12 install
LLVM_ENABLE_PROJECTS:参数只需开启clang编译器一个工程即可 CMAKE_INSTALL_PREFIX:(可选参数)设置编译后可执行文件、动态库、静态库、头文件等等统一的放置路径
编译完成之后就可以在bin目录下看到这些可执行文件了
FileCheck llvm-cat llvm-opt-fuzzer arcmt-test llvm-cfi-verify llvm-opt-report bugpoint llvm-config llvm-pdbutil c-arcmt-test llvm-cov llvm-profdata c-index-test llvm-cvtres llvm-ranlib clang llvm-cxxdump llvm-rc clang++ llvm-cxxfilt llvm-readelf clang-9 llvm-cxxmap llvm-readobj clang-check llvm-diff llvm-rtdyld clang-cl llvm-dis llvm-size
三、集成到NDK
替换原有的NDK目录下的clang文件即可,首先在local.properties中配置好ndk.dir,接着替换clang、clang++文件即可
cp /Path/You/Install/Dir/llvm-project-install/bin/clang-9 /Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang cp /Path/You/Install/Dir/llvm-project-install/bin/clang-9 /Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++
配置完clang之后还需要在build.gradle中配置需要混淆组件,如下
defaultConfig { applicationId "com.example.myapplication" minSdk 24 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags "-mllvm -irobf-cff" } } }
配合so函数如下
#include <jni.h> #include <string> char text[256] = {0}; extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */, jint val) { if (val == 0) { strcpy(text, "Hello from C++"); } else if (val == 1) { strcpy(text, "value is 1"); } else if (val == 2) { strcpy(text, "value is 2"); } else if (val == 4) { strcpy(text, "value is 4"); } else if (val == 8) { strcpy(text, "value is 8"); } else if (val == 16) { strcpy(text, "value is 16"); } else if (val == 32) { strcpy(text, "value is 32"); } else if (val == 64) { strcpy(text, "value is 64"); } else if (val == 3) { strcpy(text, "value is 3"); } else if (val == 65535) { strcpy(text, "value is 65535"); } else { strcpy(text, "value is default"); } return env->NewStringUTF(text); }
运行查看效果
四、混淆效果对比
-
fla混淆后的效果
-
cse混淆后的效果
每个字符都对应一个加密函数
-
indgv混淆后的效果
字符串都通过全局变量来获取
-
icall混淆后的效果
-
indbr混淆后的效果
截断了函数流程
我最擅长从零开始创造世界,所以从来不怕失败,它最多也就让我一无所有。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
2008-05-22 强制删除任意文件以及文件夹