本例仅在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. python学习-- 默认urls中 Path converter

    默认Path converter Django2.0自带的PathConveter包括: str:匹配除了路径分隔符(/)之外的非空字符串,如果没有转换器,默认使用str作为转换器. int:匹配0及 ...

  2. 【LeetCode】Remove Duplicates from Sorted Array(删除排序数组中的重复项)

    这道题是LeetCode里的第26道题. 题目描述: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数 ...

  3. Ruby 符号【转】

    Ruby的符号足以让很多初学者迷惑上一段时间,看过本章节后,或许会解开你心中的疑惑. 在Ruby中,一个符号是就是一个Symbol类的实例,它的语法是在通常的变量名前加一个冒号,如 :my_sy Ru ...

  4. Swift UI控件详细介绍(上)

    UI控件 首先介绍一下AppDelegate.swift@UIApplicationMain 调用了OC中的UIApplicationMain函数:UIApplicationMain是iOS应用程序的 ...

  5. 【bzoj3566】[SHOI2014]概率充电器 树形概率dp

    题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的 ...

  6. [luoguP1640] [SCOI2010]连续攻击游戏(二分图最大匹配)

    传送门 我们将每一个属性和物品连边,然后枚举从小到大属性跑匈牙利,直到找不到连边 #include <cstdio> #include <cstring> #include & ...

  7. 浅谈getStackTrace()方法(一)

    缘起: 今天看到有一个工具类中有一句: String msgToPrint = Thread.currentThread().getStackTrace()[1].getMethodName(); 输 ...

  8. 归并排序,时间复杂度nlogn

    思路: /*   考点:   1. 快慢指针:2. 归并排序.   此题经典,需要消化吸收.   复杂度分析:              T(n)            拆分 n/2, 归并 n/2 ...

  9. java中String初始化的两种方式

    转自:http://www.diybl.com/course/3_program/java/javajs/2007104/75886.html       字符串可能是任何程序语言中都会出现的对象,j ...

  10. c++函数学习-关于c++函数的林林总总

    本文是我在学习c++过程中的一些思考和总结,主要是c++中关于函数的林林总总.欢迎大家批评和指正,共同学习. os version: ubuntu 12.04 LTS gcc version: gcc ...