Android加壳native实现
本例仅在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实现的更多相关文章
- Android中对Apk加固(加壳)续篇之---对Native层(so文件)进行加固
有人说Android程序用Java代码写的,再怎么弄都是不安全的,很容易破解的,现在晚上关于应用加固的技术也很多了,当然这些也可以用于商业发展的,梆梆加密和爱加密就是很好的例子,当然这两家加固的Apk ...
- 【腾讯Bugly干货分享】Android Linker 与 SO 加壳技术
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57e3a3bc42eb88da6d4be143 作者:王赛 1. 前言 Andr ...
- 简单粗暴的对android so文件加壳,防止静态分析
转载自http://bbs.pediy.com/showthread.php?t=191649 以前一直对.so文件加载时解密不懂,不了解其工作原理和实现思路.最近翻看各种资料,有了一些思路.看到论坛 ...
- Android中的Apk的加固(加壳)原理解析和实现
一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...
- Android中的Apk的加固(加壳)原理解析和实现(转)
一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...
- 【转】Android中的Apk的加固(加壳)原理解析和实现
一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...
- android黑科技系列——Apk的加固(加壳)原理解析和实现
一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...
- Android Linker 与 SO 加壳技术
1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,N ...
- android apk 防止反编译技术第一篇-加壳技术
做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成 ...
随机推荐
- layui.code代码装饰器
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- bzoj1076【SCOI2008】奖励关
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1076 有n种物品等概率落下,求期望最优收益 sol: 一眼看上去就是状压dp吧QAQ数据范围 ...
- NOIP2017赛前模拟1:总结
题目: 1.造盒子 题目描述 企鹅豆豆收到了面积为 K 的一块橡皮泥.但是他没有合适的盒子来装下这个橡皮泥.所以他打算造一个盒子. 制造台是有方形网格的平台,每个小正方形边长为 1 .现在豆豆有两类木 ...
- 【bzoj1592】[Usaco2008 Feb]Making the Grade 路面修整
FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中. 整条路被分成了N段,N个整数A_1, ...
- 答题小程序开发之socket编程 微信小程序答题 直播答题开发 直播弹幕使用web socket编程
最近有一个项目很火,那就是直播答题的,接到公司的这个任务,开发直播答题的聊天室功能.在线的人相互聊天.之前做过类似的,当时都是使用的ajax轮询的,这种非常的耗费服务器.所以这次就开始使用socket ...
- webpack打包字体图标报错的解决办法
webpack打包字体图标需要两个加载器 url-loader 和 file-loader 另外 字体图标的引入方式 本来应该是 url("....") 这样的方式,但是w ...
- [LeetCode] Rotate Image n-by-n矩阵顺时针旋转
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- poj 1066 Treasure Hunt 线段相交
题目链接 题目描述 一个正方形房间被分成若干个小室,宝藏在其中某一点.现可炸开任意一堵墙壁的中点位置.问至少要炸开多少堵墙才能从外面到达宝藏所在地. 思路 (很巧妙,没想到) 直接枚举墙壁与正方形外壁 ...
- CSS-滤镜 -webkit-filter
css滤镜属性,可以在元素呈现之前,为元素的渲染提供一些效果,如模糊.颜色转移之类的.滤镜常用于调整图像.背景.边框的渲染. 语法: webkit-filter: none | blur(px) | ...
- 2016Unite Shanghai 总结
有幸参加了Unite 2016 Shanghai unity开发者大会,这里做一些简单总结 一.日本Marza 分享 <The Gift> Marza用unity做渲染,加上一些自己的扩展 ...