Android安全之NDK的代码混淆 -- Ollvm

安卓开发者交流群欢迎您加入
418263790

关键代码放JNI (C/C++)里真的很安全吗?

很多Android开发者都认为 把关键代码放到C/C++里 然后打包静态库 然后破解者就无法破解
我想说 你太嫩了

不信? 举个例子:

编写以下jnil例子

#include <jni.h>
#include "android_log.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h> 

jint JNICALL
Java_com_test_Test(JNIEnv *env, jclass t,jint k) {
 int key = 8;
 return key^k;//假设这是个算法
}

然后使用ndk编译

ubuntu@ubuntu:~/桌面/Android/project/AndroidNDK-master/jni$ ndk-build
[armeabi-v7a] Compile thumb  : SecShell <= test.c
[armeabi-v7a] SharedLibrary  : libSecShell.so
[armeabi-v7a] Install        : libSecShell.so => libs/armeabi-v7a/libSecShell.so
ubuntu@ubuntu:~/桌面/Android/project/AndroidNDK-master/jni$ 
得到so文件 然后打开 IDA pro(反汇编工具) 没有的百度下载

可以看到 我们的jni函数名: Java_com_test_Test
这里写图片描述
点进去

然后按F5 查看伪代码
这里写图片描述

//IDA-pro 伪代码效果
int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  return a3 ^ 8;
}

如图 a3则是jint k , int key=8 于是相当于 k^8, 则为a3^8;
看到了吧 so的代码都能看到了 和我们的jni没编译前的代码基本一致, 你还觉得jni安全么

插句话: 在 Android上实现OLLVM的资料实在太少了 不是写的不全 或者写的不知道是从哪里抄来的 等等 好像写这些高端文章 害怕我们学会似的 写一半又故意留一半没说 这还让我们怎么学习啊?看你装B吗? … 我实在看不惯才写下了这篇文章 因此,转载请注明出处!!!

因此 本文就是为了解决这个问题 使用 OLLVM对c代码进行混淆(类似java的混淆,但又不一样)

环境:windows+vmware虚拟机
Ubuntu 64位:

先贴一段从官网copy过来的,对OLLVM的说明

  • Obfuscator-LLVM is a project initiated in June 2010 by the information security group of the University of Applied Sciences and Arts Western Switzerland of Yverdon-les-Bains (HEIG-VD).
    The aim of this project is to provide an open-source fork of the LLVM compilation suite able to provide increased software security through code obfuscation and tamper-proofing. As we currently mostly work at the Intermediate Representation (IR) level, our tool is compatible with all programming languages (C, C++, Objective-C, Ada and Fortran) and target platforms (x86, x86-64, PowerPC, PowerPC-64, ARM, Thumb, SPARC, Alpha, CellSPU, MIPS, MSP430, SystemZ, and XCore) currently supported by LLVM.

安装Linux下的NDK环境、cmake 、git 并配置好环境

这个参考我另一篇帖子FFmpeg For Android 系列 这里我就不重复讲了

编译LLVM

先从git仓库拉下来 拉不了的请到官网自己下下来然后解压(后面的版本3.6.1直接看分支 拿最新的就好):

源码:https://github.com/obfuscator-llvm/obfuscator/tree/llvm-3.6.1

$ git clone -b obfuscator https://github.com/obfuscator-llvm/obfuscator.git

然后创建build目录 并进行编译

$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE:String=Release ../obfuscator/
$ make -j5

如果错误提示:没有这个路径,那就这样

$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE:String=Release ../../obfuscator/
$ make -j5

注意这个obfuscator文件夹名 如果你下载的是另一个名字 那么上面的命令要改成你的名字…
输入 make -j5后 就开始编译 ,然后等吧 等到100% 即可 编译可能需要半小时左右…

编译完成后
进入 你的NDK/toolchains下 比如我的是:

/home/ubuntu/桌面/Android/NDK/android-ndk-r10e/toolchains

然后找到arm-linux-androideabi-clang3.5 如果你没找到 那就找arm-linux-androideabi-clang3.4或 arm-linux-androideabi-clang3.3 …懂了吧? 要记住 等会要用

/home/ubuntu/桌面/Android/NDK/android-ndk-r10e/toolchains/arm-linux-androideabi-clang3.5

进去把config.mk和setup.mk 两个文件 复制到

//config.mk和setup.mk 两个文件复制到这里,没有这个文件夹就自己创建
/toolchains/arm-linux-androideabi-clang3.4-obfuscator/

编辑arm-linux-androideabi-clang3.4-obfuscator/setup.mk文件
将文件里面的:

TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)

修改为 注意路径 不要照抄

LLVM_TOOLCHAIN_PATH :=这里填你刚才编译的LLVM的路径/build/bin/
TARGET_CC := $(LLVM_TOOLCHAIN_PATH)clang$(HOST_EXEEXT)
TARGET_CXX := $(LLVM_TOOLCHAIN_PATH)clang++$(HOST_EXEEXT)

至此 ollvm已经和ndk联系起来了 那么我们可以使用ollvm进行混淆c/c++了

创建jni工程

新建
Android.mk 文件 内容为

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libSecShell
LOCAL_LDLIBS := -lm -llog 
LOCAL_SRC_FILES := test.c
LOCAL_CFLAGS := -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

include $(BUILD_SHARED_LIBRARY)

这些命令请参看官方文档 本文后面有链接 -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

解释:这句是开启级别更高的混淆

LOCAL_CFLAGS := -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

Application.mk文件内容如下

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI := armeabi-v7a
NDK_TOOLCHAIN_VERSION :=  clang3.4-obfuscator
APP_PLATFORM=android-14
include $(BUILD_EXECUTABLE)

解释:clang3.4-obfuscator为刚才你复制的arm-linux-androideabi-clang3.4-obfuscator的文件夹后缀名称 这样ndk就会通过setup.mk里找到obfuscator/build/bin/下的clang进行混淆编译

然后 和普通NDK命令一样 编译jni工程

cd yourProject/jni
ndk-build

编译so后 重新使用IDA pro反汇编这个so文件,查看c/c++代码 如下….

//IDA-pro  进行OLLVM混淆-伪代码效果
//尴尬了 一个普通的算法突然混淆成这样 大大增加了破解者的破解难度!!!
//....反正我是看不懂了...
unsigned int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  signed int v3; // r4@1
  signed int v4; // r5@1
  unsigned int v5; // r1@1
  signed int v6; // r3@5
  bool v7; // zf@9
  signed int v8; // r5@9
  unsigned int v9; // r2@9
  signed int v10; // r1@9
  signed int v11; // r4@13
  unsigned __int8 v13; // [sp+2h] [bp-16h]@3
  unsigned __int8 v14; // [sp+3h] [bp-15h]@5
  unsigned int v15; // [sp+4h] [bp-14h]@0

  v3 = 0;
  v4 = 0;
  v5 = x * ~-x & (x * ~-x ^ 0xFFFFFFFE);
  if ( !v5 )
    v4 = 1;
  v13 = v4;
  if ( y < 10 )
    v3 = 1;
  v6 = 0;
  v14 = v3;
  if ( v5 )
    v5 = 1;
  if ( y > 9 )
    v6 = 1;
  v7 = ((v6 | v5) ^ 1 | v4 ^ v3) == 0;
  v8 = -1313485305;
  v9 = a3 & 0xFFFFFFF7 | 8 * (((unsigned int)~a3 >> 3) & 1);
  v10 = -1265641972;
  if ( !v7 )
    v10 = 1153232101;
  while ( 1 )
  {
    v11 = v8;
    if ( v8 > 1153232100 )
      break;
    v8 = -1766943702;
    if ( v11 != -1265641972 )
    {
      if ( v11 == -1766943702 )
      {
        v15 = v9;
        v8 = v10;
      }
      else
      {
        if ( v11 != -1313485305 )
          goto LABEL_22;
        v8 = -1265641972;
        if ( ((unsigned __int8)(v13 & v14) | v13 ^ v14) & 1 )
          v8 = -1766943702;
      }
    }
  }
  if ( v8 != 1153232101 )
  {
    while ( 1 )
LABEL_22:
      ;
  }
  return v15;
}

以上就是混淆效果
你再看看原来没混淆的

//IDA-pro 未进行OLLVM混淆-伪代码效果
int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  return a3 ^ 8;
}

这就是区别 当然可能会导致运算速度降低 但至今未发现有什么问题

参考

http://blog.csdn.net/wangbaochu/article/details/45370397
https://github.com/obfuscator-llvm/obfuscator/pull/18
http://www.voidcn.com/blog/gongsunjinqian/article/p-4869314.html
http://www.voidcn.com/blog/beyond702/article/p-6218200.html
http://blog.csdn.net/dickwang1229/article/details/49408865#android
https://github.com/Fuzion24/AndroidObfuscation-NDK
https://github.com/obfuscator-llvm/obfuscator/wiki/Features
http://www.freebuf.com/articles/terminal/130142.html
https://github.com/obfuscator-llvm/obfuscator/wiki/Installation
http://www.jianshu.com/p/0c23e0a886f4
http://blog.csdn.net/feibabeibei_beibei/article/details/52729136

猜你喜欢

转载自blog.csdn.net/u014418171/article/details/72809816