前言
因为前段时间被叫去协助数据部爬某直播软件的小黄车数据,然后学习了下逆向方面的知识,最近需求任务不是特别重,于是把 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 二次打包签名校验的函数为例。


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