Hikari 是一个基于OLLVM高度优化并包含大量自制混淆功能的二进制加固工具,github地址
最近研究了 Hikari 在 iOS 上的应用,于是想在 Android 端上也进行加强,毕竟黑产手段越来越难防了。
市面上也有 OLLVM 反混淆工具,所以需要一个更加强大的混淆框架。
Android Studio:3.3
cmake:3.13.2 (用已安装的,AS也有自带)
Hikari:7.0
我这边不会介绍如何编译 Hikari,其实作者已经弄的很简便了。
未混淆前的代码
直接建个 Native C++ 项目,代码就用官方模板的吧
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_meiyou_hikaritest_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
如果你环境一切正常,编译完就能在 build 文件夹内找到对应 .so 文件。
随便把输出的 release 下的 .so 文件拖到 hopper ,找到对应方法,pseudo code 下
大体逻辑就能猜到了,所以把逻辑写成 c++ 代码也不安全,会 google 的都能看个大概。
混淆后的效果
我们来看混淆后的,Hikari 提供了多种混淆方式,我这边选了最常见的几个变量。
-mllvm -enable-bcfobf -mllvm -bcf_prob=100 -mllvm -enable-cffobf -mllvm -enable-funcwra -mllvm -enable-strcry
看成品吧,可以发现通过阅读反汇编后的代码,根本看不出逻辑,并且需要单步跟踪的话,时间成本和技术深度的要求都非常大,网络上也比较多解释混淆原理的,大家可以自行搜索。
说点网络没有的
之前 google 了很久,都没有任何关于 Hikari 对 NDK 混淆的例子,而且作者自己也没去做教程。
所以我参考了之前自己弄 OLLVM 的方式,发现有坑,会报 unknown option: --sysroot=...
错误,我也在 github 上提了个 issues,也跟了下相关的 clang 的编译变量,发现 --sysroot 相关变量都有定义。。
然后就陷入迷茫。。。
最后是乱搜乱逛,就到了 google ndk 官网,我就在想是不是新版本的问题,然后 AS 里面的 NDK 还不支持选版本,就是只有 19.0 的版本。
稳定版: 16b
Android Studio:19.0
后面其实就是自己弄了,下了 16b 的ndk,替换原有的 ndk-bundle
文件夹。 package.xml
文件可以留下来,这样 Android Studio 里面的 SDK Manager 才能发现你。
后面的流程就跟 OLLVM 的混淆一样了。用 Hikari Build 后的 bin 文件,替换 ndk-bundle 里面的 bin 文件夹。
编译的时候会报错,xx 头文件没找到,继续从 hikari 搜对应头文件,copy 到 ndk sysroot 里面去
最后添加混淆参数配置。