前言
因为前段时间被叫去协助数据部爬某直播软件的小黄车数据,然后学习了下逆向方面的知识,最近需求任务不是特别重,于是把 ndk 集成了 ollvm,给 so 层代码加了点混淆,增加逆向的成本。
使用 ollvm 给 so 增加混淆
克隆 goron。
goron 项目地址为 https://github.com/amimo/goron,先克隆项目。
$ git clone https://github.com/amimo/goron.git
访问不了可以使用镜像地址。
$ git clone https://github.com.cnpmjs.org/amimo/goron.git
查看 ndk 的 llvm 版本。
获取当前 ndk 使用的 llvm 版本。
$ NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --version

切换分支
这里将项目切换为 llvm-9.0.0 分支(根据自己的版本来)。
$ cd goron
$ git branch --all
$ git checkout origin/llvm-9.0.0 -b llvm-9.0.0

编译 goron。
新建 build 目录,编译 goron。
$ mkdir build-9.0.0
$ cd build-9.0.0
$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang -DLLVM_INCLUDE_TESTS=OFF ../llvm
$ make -j8
-
-DCMAKE_BUILD_TYPE=Release构建发布版 -
-DLLVM_ENABLE_PROJECTS=clang构建子项目 clang -
-DLLVM_INCLUDE_TESTS=OFF关闭 test 减少编译时间
编译耗时比较久,慢的话可能一个半小时,快的话几十分钟。
文件替换
编译完成后用 goron/build-9.0.0/bin 下的 clang、clang++ 和 clang-format,替换掉 $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin 下的 clang、clang++ 和 clang-format。
替换完文件后构建下 native module。这个时候会报错,找不到一些头文件。

这里只需要将找不到的头文件从 goron/build-9.0.0/lib/clang/9.0.0/include 复制到 $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include 即可。
这里我复制 4 个头文件 stddef.h、__stddef_max_align_t.h、stdarg.h 和 float.h,实际情况根据构建为准。
增加混淆参数
经过上面的步骤,ndk 已经集成好了 ollvm,但是这时候去编译 so 依旧是没有混淆的,还得加一些构建参数。goron 提供了如下 5 种参数。
-
-mllvm -irobf-indbr,间接跳转 -
-mllvm -irobf-icall,间接函数调用 -
-mllvm -irobf-indgv,间接全局变量引用 -
-mllvm -irobf-cse,字符串加密功能 -
-mllvm -irobf-cff,过程相关控制流平坦混淆
需要使用哪种混淆在 build.gradle 配置即可。
externalNativeBuild {
cmake {
cppFlags "-mllvm -irobf-indbr -mllvm -irobf-icall -mllvm -irobf-indgv -mllvm -irobf-cse"
}
}
开启混淆后再构建 so,使用 IDA PRO 查看混淆前与混淆后的对比,这里我以 so 中的防 apk 二次打包签名校验的函数为例。


可以看到混淆后的可读性还是下降了很多的。