本例仅在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. beautifusouptest

    from bs4 import BeautifulSoupimport urllib.requesturl = "http://www.douban.com/tag/%E5%B0%8F%E8 ...

  2. 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆

    题目描述 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他.如果要满足顾客的需求,就必须要有足够的库存.问 ...

  3. [NOIP2017] 时间复杂度 (模拟,栈)

    题目链接 Solution 用栈进行模拟. 记录一个 \(map\) 来看循环变量有没有用过. 对于每一次入栈都加信息. 出栈直接将 \(top\) 减一下. 反正一堆乱七八糟的东西瞎搞... 注意条 ...

  4. eclipse testng插件安装

    1.安装Testng 在Eclipse中,点击Help→Install new software→点击Add,在location中输入http://beust.com/eclipse ,选择TestN ...

  5. hdu 3320 计算几何(三维图形几何变换)

    openGL Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  6. llinux 定时器 转载自 http://blog.chinaunix.net/uid-11848011-id-96374.html

    这篇文章主要记录我在试图解决如何尽可能精确地在某个特定的时间间隔执行某项具体任务时的思路历程,并在后期对相关的API进行的归纳和总结,以备参考. 问题引出 很多时候,我们会有类似“每隔多长时间执行某项 ...

  7. linux下网络监控神器"iptraf-ng"

    优点:监控的网络信息很全面,安装和使用方便   #centos安装: #yum 源使用centos自带的base源即可. yum install -y iptraf-ng   #运行 iptraf-n ...

  8. 关于nginx所遇问题

    1. 如果出现 nginx: [error] invalid PID number “” in “/usr/local/var/run/nginx/nginx.pid” 错误重新加载配置文件 /usr ...

  9. Integration_Unit test coding standard

    Integration & Unit test coding standard 命名规则 好的命名规则,直接从命名就可以清楚的知道该测试方法测试的内容和目的,而不用额外的添加注释说明.对于MV ...

  10. Codeforces 934 A.Compatible Pair

    http://codeforces.com/contest/934 A. A Compatible Pair   time limit per test 1 second memory limit p ...