• 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");
    }

  • 相关阅读:
    将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组
    vue 设计一个倒计时秒杀的组件
    es6之三个点(...)扩展运算符
    es6之解构赋值
    es6之字符串添加的东西
    ES6系列之变量声明let const
    js对数组进行删除
    python学习
    泛型
    随笔
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7219439.html
Copyright © 2020-2023  润新知