一 简介

LLVM:一个编译器,用来编译so和可执行文件等

OLLVM:在LLVM的基础上去混淆so

 

二 OLLVM混淆环境搭建

1.环境配置

虚拟机:VMware

系统:Ubuntu-12.04.5-64位(这里也测试了另一个linux系统ubuntu-17.10.1-64位 编译不出来,ollvm缺少clang)

OLLVM版本:obfuscator-llvm-3.4

ndk版本:android-ndk32-r10b-linux-x86_64.tar

 

三 编译ollvm

1 安装编译工具

 执行两条linux命令

apt-get install cmake

apt-get install g++

 

2.复制ollvm压缩包到linux系统

将附件里面的obfuscator-llvm-3.4复制到虚拟机linux系统下的Home/Pictures/android/llvm (对于ubuntu系统12.04版本这里建议在Picture目录下编译操作 ,如果放到其他位置编译即使给了su权限最后的时候还是提示权限不足,这里未解决.其他linux系统请自行测试)

lua代码在线混淆_android

 

3.在obfuscator-llvm-3.4目录下创建build目录并用命令行在build目录下执行 cmake -DCMAKE_BUILD_TYPE:String=Release ../ 命令

lua代码在线混淆_#include_02

 

4.执行完成后再执行命令 make -j7 这个编译会很等待长时间 等编译完成后会在build目录下生成bin和lib目录 

lua代码在线混淆_android_03

5.如果build目录下有lib和bin目录并且bin目录里面有clang文件 代表编译成功 否则为编译失败 编译失败后面的操作就不能进行了  请检查编译失败的原因 如解决不了建议更换OLLVM版本测试或者更换linux系统重新进行以上步骤

lua代码在线混淆_lua代码在线混淆_04

 

四 ndk配置环境变量

1.将附件中 android-ndk-r10b复制到虚拟机ndk目录下 并解压

lua代码在线混淆_#include_05

 

2执行命令sudo gedit /etc/profile 然后在弹出的profile文件最后添加下面命令注意NDK_HOME为自己ndk目录   保存后退出 

export NDK_HOME=/home/heyiran/Pictures/android/ndk/

export PATH=$NDK_HOME:$PATH

lua代码在线混淆_android_06

 

3.执行命令 source /etc/profile 使上面更改生效

 

4.执行命令ndk-build如果出现以下提示 代表品ndk环境变量配置成功

lua代码在线混淆_android_07

 

5.如果环境变量未生效可以尝试将内容添加在“~/.bashrc”文件内

$sudo gedit ~/.bashrc

 

 

五 整合ollvm到ndk中

1.进入到ndk目录下的toolchains目录并拷贝llvm-3.3文件夹到当前目录并重命名为obfuscator-llvm-3.4

lua代码在线混淆_java_08

 

 

2.将obfuscator-llvm-3.4/prebuilt/linux-x86_64 目录下的bin和lib目录替换成obfuscator-llvm-3.4/build目录下的bin和lib

lua代码在线混淆_#include_09

3.将ndk/toolchains目录下的arm-linux-androideabi-clang3.4,mipsel-linux-android-clang3.4,x86-clang3.4这三个目录拷贝到当前目录并重命名为

arm-linux-androideabi-obfuscator3.4

mipsel-linux-android-obfuscator3.4

x86-obfuscator3.4

并将拷贝后文件夹里面的setup.mk 文件中的 LLVM_NAME 的值都更改为

LLVM_NAME := obfuscator-llvm-$(LLVM_VERSION)

注意:拷贝后的三个文件夹都要更改

lua代码在线混淆_java_10

lua代码在线混淆_#include_11

六.通过ndk编译出混淆后的so

1.在Pictures/android/test/hello/jni目录下新建Android.mk,Application.mk和hello.c目录

lua代码在线混淆_#include_12

Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := hello
LOCAL_SRC_FILES := hello.c
LOCAL_CFLAGS +=  -mllvm -sub -mllvm -bcf -mllvm -fla
LOCAL_ARM_MODE := arm
LOCAL_PROGUARD_ENABLED:= disabled
include $(BUILD_SHARED_LIBRARY)


Application.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI := armeabi
NDK_TOOLCHAIN_VERSION := obfuscator3.4
include $(BUILD_SHARED_LIBRARY)

hello.c:
#include <stdio.h>
#include <fcntl.h>
#include <elf.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>

char * a(char* Text);

static jstring JNICALL serial(JNIEnv *env, jobject class,jstring user)
{
   char *c_user = (*env)->GetStringUTFChars(env,user,0);
   char * pass = a("Tm|hjllv|o");

    if(strcmp(c_user,pass)==0)
    {
     return (*env)->NewStringUTF(env,"successful!");
    }
    else
    {
     return (*env)->NewStringUTF(env,"wrong password!");
    }

}

char * a(char* Text)
{
    char secretText[128]={'\0'};
    int count=0;
    int i;
    count = strlen(Text);
    for(i=0;i<count;i++){
        secretText[i]=Text[i]-i-1;
    }
    secretText[i] = '\0';
    return secretText;
}

static const JNINativeMethod gMethods[] = {
// {"check", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (jstring*)check},
        {"check", "(Ljava/lang/String;)Ljava/lang/String;", (jstring*)serial}
// {"checkport", "()V", (jstring*)checkport}
};

static jclass myClass;

static const char* const kClassName="demo2/jni/com/myapplication/myJNI";
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
        JNIEnv* env = NULL;
        jint result = -1;
        if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
                return -1;
        myClass = (*env)->FindClass(env, kClassName);
       
        if(myClass == NULL)
        {
                printf("cannot get class:%s\n", kClassName);
                return -1;
        }
        if((*env)->RegisterNatives(env,myClass,gMethods,sizeof(gMethods)/sizeof(gMethods[0]))<0)
        {
                printf("register native method failed!\n");
                return -1;
        }
        printf("--------JNI_OnLoad-----");
        return JNI_VERSION_1_4;
}

 

2.在jni目录下执行命令ndk-build 发现hello目录下已经生成了libs和obj目录 将libs目录下的libhello.so复制到windows系统并用IDA打开 发现代码已经被混淆 

lua代码在线混淆_android_13

lua代码在线混淆_#include_14

lua代码在线混淆_#include_15

lua代码在线混淆_#include_16

lua代码在线混淆_java_17

 

附件:链接:https://pan.baidu.com/s/1oIg0EcDxTpVUEVp_dIW3Xg 密码:yefs

七 参考资料

《OLLVM4.0+NDK编译环境搭建》

《ollvm的混淆反混淆和定制修改》