本例仅在Android2.3模拟器跑通过,假设要适配其它机型。请自行研究,这里不过抛砖引玉。

0x00

Android中的Apk的加固(加壳)原理解析和实现,一文中脱壳代码都写在了java层非常easy被识别出来。非常多需求须要把脱壳的程序转移到native层,事实上转移的思路也非常简单,就是在native层通过JNI调用Java层代码。

执行前,首先把ForceApkObj.apk放在/sdcard/payload_odex/文件夹下。

代码已上传至github,地址为https://github.com/jltxgcy/AndroidNativeShell

0x01

    public class ProxyApplication extends Application {

	@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
DexLoader.load("com.jltxgcy.dynamicdex");
} @Override
public void onCreate() {
DexLoader.run();
}
}

还记得原来这两个方法有着一大堆代码,这里唯独一行代码就搞定。

我们再看来DexLoader类。

public class DexLoader {
static {
System.loadLibrary("dexloader");
} public static native void load(String path); public static native void run();
}

原来核心脱壳代码放在了native层。

0x02

JNI的实现例如以下。大家能够看到本质上就是把java层的代码通过JNI转移到native层了。

static void loadApk(JNIEnv * env, jclass clazz, jstring package) {
jclass activityThreadClazz;
jmethodID currentActivityThreadMethodID;
jobject activityThreadObject;
const char *packageName;
const char *className;
const char *methodName;
int codeoff; jfieldID mPackagesFieldID;
jobject mPackagesJObject;
jclass mPackagesClazz;
jmethodID getMethodID; jobject weakReferenceJObject;
jclass weakReferenceJClazz;
jmethodID getweakMethodID; jobject loadedApkJObject;
jclass loadedApkJClazz;
jfieldID mClassLoaderFieldID;
jobject mClassLoaderJObject;
jstring dexPath;
jstring dexOptPath; jclass dexClassLoaderClazz;
jmethodID initDexLoaderMethod;
jobject dexClassLoaderJObject; activityThreadClazz = env->FindClass("android/app/ActivityThread");
currentActivityThreadMethodID = env->GetStaticMethodID(activityThreadClazz, "currentActivityThread",
"()Landroid/app/ActivityThread;");
activityThreadObject = env->CallStaticObjectMethod(activityThreadClazz, currentActivityThreadMethodID);
packageName = env->GetStringUTFChars(package, JNI_FALSE);
mPackagesFieldID = env->GetFieldID(activityThreadClazz, "mPackages", "Ljava/util/HashMap;");
mPackagesJObject = env->GetObjectField(activityThreadObject, mPackagesFieldID);
mPackagesClazz = env->GetObjectClass(mPackagesJObject);
getMethodID = env->GetMethodID(mPackagesClazz, "get",
"(Ljava/lang/Object;)Ljava/lang/Object;");
weakReferenceJObject = env->CallObjectMethod(mPackagesJObject, getMethodID, package);
weakReferenceJClazz = env->GetObjectClass(weakReferenceJObject);
getweakMethodID = env->GetMethodID(weakReferenceJClazz, "get",
"()Ljava/lang/Object;");
loadedApkJObject = env->CallObjectMethod(weakReferenceJObject, getweakMethodID);
loadedApkJClazz = env->GetObjectClass(loadedApkJObject);
mClassLoaderFieldID = env->GetFieldID(loadedApkJClazz, "mClassLoader", "Ljava/lang/ClassLoader;");
mClassLoaderJObject = env->GetObjectField(loadedApkJObject, mClassLoaderFieldID);
dexPath = env->NewStringUTF("/sdcard/payload_odex/ForceApkObj.apk");
dexOptPath = env->NewStringUTF("/sdcard/payload_odex/");
dexClassLoaderClazz = env->FindClass("dalvik/system/DexClassLoader");
initDexLoaderMethod = env->GetMethodID(dexClassLoaderClazz, "<init>","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
dexClassLoaderJObject = env->NewObject(dexClassLoaderClazz,initDexLoaderMethod, dexPath, dexOptPath, NULL, mClassLoaderJObject);
env->SetObjectField(loadedApkJObject, mClassLoaderFieldID, dexClassLoaderJObject);
ALOGD("packageName:%s", packageName);
} static void run(JNIEnv * env, jclass clazz) {
jclass activityThreadClazz;
jmethodID currentActivityThreadMethodID;
jobject activityThreadObject; jfieldID mBoundApplicationFieldID;
jobject mBoundApplicationJObject;
jclass mBoundApplicationClazz;
jfieldID mInfoFieldID;
jobject mInfoJObject;
jclass mInfoClazz; jfieldID mApplicationFieldID;
jobject mApplicationJObject; jfieldID mInitialApplicationFieldID;
jobject mInitialApplicationJObject; jfieldID mAllApplicationsFieldID;
jobject mAllApplicationsJObject;
jclass mAllApplicationsClazz;
jmethodID removeMethodID; jfieldID mApplicationInfoFieldID;
jobject mApplicationInfoJObject;
jclass mApplicationInfoClazz; jfieldID mBindApplicationInfoFieldID;
jobject mBindApplicationInfoJObject;
jclass mBindApplicationInfoClazz; jfieldID classNameFieldID;
jfieldID mBindClassNameFieldID;
jstring applicationName; jmethodID makeApplicationMethodID;
jobject ApplicationJObject;
jclass ApplicationClazz;
jmethodID onCreateMethodID; activityThreadClazz = env->FindClass("android/app/ActivityThread");
currentActivityThreadMethodID = env->GetStaticMethodID(activityThreadClazz, "currentActivityThread",
"()Landroid/app/ActivityThread;");
activityThreadObject = env->CallStaticObjectMethod(activityThreadClazz, currentActivityThreadMethodID);
mBoundApplicationFieldID = env->GetFieldID(activityThreadClazz, "mBoundApplication", "Landroid/app/ActivityThread$AppBindData;");
mBoundApplicationJObject = env->GetObjectField(activityThreadObject, mBoundApplicationFieldID);
mBoundApplicationClazz = env->GetObjectClass(mBoundApplicationJObject);
mInfoFieldID = env->GetFieldID(mBoundApplicationClazz, "info", "Landroid/app/LoadedApk;");
mInfoJObject = env->GetObjectField(mBoundApplicationJObject, mInfoFieldID);
mInfoClazz = env->GetObjectClass(mInfoJObject);
mApplicationFieldID = env->GetFieldID(mInfoClazz, "mApplication", "Landroid/app/Application;");
mApplicationJObject = env->GetObjectField(mInfoJObject, mApplicationFieldID);
env->SetObjectField(mInfoJObject, mApplicationFieldID, NULL);
mInitialApplicationFieldID = env->GetFieldID(activityThreadClazz, "mInitialApplication", "Landroid/app/Application;");
mInitialApplicationJObject = env->GetObjectField(activityThreadObject, mInitialApplicationFieldID);
mAllApplicationsFieldID = env->GetFieldID(activityThreadClazz, "mAllApplications", "Ljava/util/ArrayList;");
mAllApplicationsJObject = env->GetObjectField(activityThreadObject, mAllApplicationsFieldID);
mAllApplicationsClazz = env->GetObjectClass(mAllApplicationsJObject);
removeMethodID = env->GetMethodID(mAllApplicationsClazz, "remove",
"(Ljava/lang/Object;)Z");
jboolean isTrue = env->CallBooleanMethod(mAllApplicationsJObject, removeMethodID, mInitialApplicationJObject);
mApplicationInfoFieldID = env->GetFieldID(mInfoClazz, "mApplicationInfo", "Landroid/content/pm/ApplicationInfo;");
mApplicationInfoJObject = env->GetObjectField(mInfoJObject, mApplicationInfoFieldID);
mApplicationInfoClazz = env->GetObjectClass(mApplicationInfoJObject);
mBindApplicationInfoFieldID = env->GetFieldID(mBoundApplicationClazz, "appInfo", "Landroid/content/pm/ApplicationInfo;");
mBindApplicationInfoJObject = env->GetObjectField(mBoundApplicationJObject, mBindApplicationInfoFieldID);
mBindApplicationInfoClazz = env->GetObjectClass(mBindApplicationInfoJObject);
classNameFieldID = env->GetFieldID(mApplicationInfoClazz, "className", "Ljava/lang/String;");
mBindClassNameFieldID = env->GetFieldID(mBindApplicationInfoClazz, "className", "Ljava/lang/String;");
applicationName = env->NewStringUTF("com.example.forceapkobj.MyApplication");
env->SetObjectField(mApplicationInfoJObject, classNameFieldID, applicationName);
env->SetObjectField(mBindApplicationInfoJObject, mBindClassNameFieldID, applicationName);
makeApplicationMethodID = env->GetMethodID(mInfoClazz, "makeApplication","(ZLandroid/app/Instrumentation;)Landroid/app/Application;");
ApplicationJObject = env->CallObjectMethod(mInfoJObject, makeApplicationMethodID, JNI_FALSE, NULL);
env->SetObjectField(activityThreadObject, mInitialApplicationFieldID, ApplicationJObject);
ApplicationClazz = env->GetObjectClass(ApplicationJObject);
onCreateMethodID = env->GetMethodID(ApplicationClazz, "onCreate","()V");
env->CallVoidMethod(ApplicationJObject, onCreateMethodID);
} JNIEXPORT void JNICALL Java_com_jltxgcy_dynamicdex_DexLoader_load
(JNIEnv * env, jclass clazz, jstring packageName) {
loadApk(env, clazz, packageName);
ALOGD("Java_com_jltxgcy_dynamicdex_DexLoader_load");
} JNIEXPORT void JNICALL Java_com_jltxgcy_dynamicdex_DexLoader_run
(JNIEnv * env, jclass clazz) {
run(env, clazz);
ALOGD("Java_com_jltxgcy_dynamicdex_DexLoader_run");
}

Android加壳native实现的更多相关文章

  1. Android中对Apk加固(加壳)续篇之---对Native层(so文件)进行加固

    有人说Android程序用Java代码写的,再怎么弄都是不安全的,很容易破解的,现在晚上关于应用加固的技术也很多了,当然这些也可以用于商业发展的,梆梆加密和爱加密就是很好的例子,当然这两家加固的Apk ...

  2. 【腾讯Bugly干货分享】Android Linker 与 SO 加壳技术

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57e3a3bc42eb88da6d4be143 作者:王赛 1. 前言 Andr ...

  3. 简单粗暴的对android so文件加壳,防止静态分析

    转载自http://bbs.pediy.com/showthread.php?t=191649 以前一直对.so文件加载时解密不懂,不了解其工作原理和实现思路.最近翻看各种资料,有了一些思路.看到论坛 ...

  4. Android中的Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  5. Android中的Apk的加固(加壳)原理解析和实现(转)

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  6. 【转】Android中的Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  7. android黑科技系列——Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  8. Android Linker 与 SO 加壳技术

    1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,N ...

  9. android apk 防止反编译技术第一篇-加壳技术

    做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成 ...

随机推荐

  1. 面向对象编程(二)封装--构造方法,this关键字,static关键字,方法重载

    面向对象三大特点:封装.继承.多态 封装概念 ①   将东西包装在一起,然后以新的完整形式呈现出来: 将方法和字段一起包装到一个单元中,单元以类的形式实现; ②   信息隐藏,隐藏对象的实现细节,不让 ...

  2. 【转】关于AI的目标导向型行动计划

    作者:Brent Owens 目标导向型行动计划(简称GOAP)是一种能够轻松呈现给你的代理选择的AI系统,也是帮助你可以无需维持一个庞大且复杂的有限状态机而做出明智的决策的机器. 演示版本 在这一演 ...

  3. 使用jackson解析JSON数据

    本文介绍使用jackson来对json数据进行解析操作 首先,需要去官网下载jackson,本文使用的是(jackson-all-1.9.11.jar) 主要通过ObjectMapper对json进行 ...

  4. Linux命令之必须掌握的十条命令

    Linux现如今已经成为了软件行业最流行的操作系统,掌握Linux就成为了每一个开发者必备的专业技能. 为了方便大家学习,大学君在此为大家整理了在使用Linux时必须掌握的十条命令,希望大家能熟练掌握 ...

  5. iOS学习笔记38-MJExtension使用

    一.MJExtension第三方框架 我们在iOS开发过程中,我们常常需要将字典数据(也就是JSON数据)与Model模型之间的转化,例如网络请求返回的微博数据.等等,如果我们自己全部手动去创建模型并 ...

  6. NOIP2012开车旅行 【倍增】

    题目 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i 和城 ...

  7. 【CCF】无线网络 搜索+思维

    #include<iostream> #include<cstdio> #include<cstring> #include<string> #incl ...

  8. Python Base Two

    //fourth day to study python 24. In python , how to create funcation. we can use def to define funca ...

  9. mysql 查询死锁语句

    我们可以用下面三张表来查原因:        innodb_trx ## 当前运行的所有事务        innodb_locks ## 当前出现的锁        innodb_lock_wait ...

  10. 第一个 spring Boot 应用通过Docker 来实现构建、运行、发布

    1. Docker 简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙 ...