一 简介
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系统请自行测试)
3.在obfuscator-llvm-3.4目录下创建build目录并用命令行在build目录下执行 cmake -DCMAKE_BUILD_TYPE:String=Release ../ 命令
4.执行完成后再执行命令 make -j7 这个编译会很等待长时间 等编译完成后会在build目录下生成bin和lib目录
5.如果build目录下有lib和bin目录并且bin目录里面有clang文件 代表编译成功 否则为编译失败 编译失败后面的操作就不能进行了 请检查编译失败的原因 如解决不了建议更换OLLVM版本测试或者更换linux系统重新进行以上步骤
四 ndk配置环境变量
1.将附件中 android-ndk-r10b复制到虚拟机ndk目录下 并解压
2执行命令sudo gedit /etc/profile 然后在弹出的profile文件最后添加下面命令注意NDK_HOME为自己ndk目录 保存后退出
export NDK_HOME=/home/heyiran/Pictures/android/ndk/
export PATH=$NDK_HOME:$PATH
3.执行命令 source /etc/profile 使上面更改生效
4.执行命令ndk-build如果出现以下提示 代表品ndk环境变量配置成功
5.如果环境变量未生效可以尝试将内容添加在“~/.bashrc”文件内
$sudo gedit ~/.bashrc
五 整合ollvm到ndk中
1.进入到ndk目录下的toolchains目录并拷贝llvm-3.3文件夹到当前目录并重命名为obfuscator-llvm-3.4
2.将obfuscator-llvm-3.4/prebuilt/linux-x86_64 目录下的bin和lib目录替换成obfuscator-llvm-3.4/build目录下的bin和lib
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)
注意:拷贝后的三个文件夹都要更改
六.通过ndk编译出混淆后的so
1.在Pictures/android/test/hello/jni目录下新建Android.mk,Application.mk和hello.c目录
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打开 发现代码已经被混淆
附件:链接:https://pan.baidu.com/s/1oIg0EcDxTpVUEVp_dIW3Xg 密码:yefs
七 参考资料
《OLLVM4.0+NDK编译环境搭建》
《ollvm的混淆反混淆和定制修改》