#include <jni.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <android/log.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <elf.h> #include <sys/mman.h> #include <assert.h> /*************************************************************************************** * * 宏定义 * ****************************************************************************************/ //输出调试信息到logcat #define DEBUG #define LOG_TAG "LOG_ANDROID_SHELL" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) //求一维数组元素个数 # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) //Application类,壳入口 #define JNIREG_CLASS "com/lzy/androidshell/MainApplication" /*************************************************************************************** * * 范例代码 * ****************************************************************************************/ //解密dex JNIEXPORT void JNICALL sub_1111(JNIEnv* env, jobject thiz, jobject context) { jclass native_clazz = env->GetObjectClass(context); jmethodID methodID_func = env->GetMethodID(native_clazz, "getPackageName", "()Ljava/lang/String;"); jstring packagename = (jstring) (env->CallObjectMethod(context, methodID_func)); const char *str = env->GetStringUTFChars(packagename, 0); char destination[128]; const char *blank = "/data/data/", *c = "/.cache/"; strcpy(destination, blank); strcat(destination, str); strcat(destination, c); LOGI("stringcccccccccccccccc %s", destination); env->ReleaseStringUTFChars(packagename, str); jint a = mkdir(destination, 777); LOGI("Created a file in android! %d", a); const char *pre = "chmod 755 "; char cmd[128]; strcpy(cmd, pre); strcat(cmd, destination); LOGI("cmd %s", cmd); jstring jcmd = CharTojstring(env, cmd); //exec jclass Runtime = env->FindClass("java/lang/Runtime"); jmethodID Runtime_func = env->GetStaticMethodID(Runtime, "getRuntime", "()Ljava/lang/Runtime;"); jobject class_obj = env->CallStaticObjectMethod(Runtime, Runtime_func); jclass class_java = env->GetObjectClass(class_obj); jmethodID exec_func = env->GetMethodID(class_java, "exec", "(Ljava/lang/String;)Ljava/lang/Process;"); jobject method_obj = env->CallObjectMethod(class_obj, exec_func, jcmd); jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID waitfor_func = env->GetMethodID(class_method_obj, "waitFor", "()I"); jint result = env->CallIntMethod(method_obj, waitfor_func); LOGI("CallIntMethod %d", result); jclass native_clazz2 = env->GetObjectClass(context); jmethodID methodID_func2 = env->GetMethodID(native_clazz2, "getPackageName", "()Ljava/lang/String;"); jstring packagename2 = (jstring) (env->CallObjectMethod(context, methodID_func2)); const char *str2 = env->GetStringUTFChars(packagename2, 0); char destination2[128]; const char *blank2 = "/data/data/", *c2 = "/.cache/classdex.jar"; strcpy(destination2, blank2); strcat(destination2, str2); strcat(destination2, c2); LOGI("string %s", destination2); LOGI("log test ok "); env->ReleaseStringUTFChars(packagename2, str2); jstring jdestination = CharTojstring(env, destination2); jmethodID methodID_getApplicationInfo = env->GetMethodID(native_clazz2, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;"); jobject ApplicationInfo = env->CallObjectMethod(context, methodID_getApplicationInfo); jclass cls_ApplicationInfo = env->GetObjectClass(ApplicationInfo); jfieldID JarFieldId = env->GetFieldID(cls_ApplicationInfo, "publicSourceDir", "Ljava/lang/String;"); jstring SourceDir = (jstring) (env->GetObjectField(ApplicationInfo, JarFieldId)); const char *strs = env->GetStringUTFChars(SourceDir, 0); char destinations[128]; strcpy(destinations, strs); jbyteArray bytes = env->NewByteArray(65536); LOGI("HAHAHAHHAHAHAHA %s", destinations); env->ReleaseStringUTFChars(SourceDir, strs); LOGI("HAHAHAHHAHAHAHA222222222222222"); char *classdex_jar2 = "assets/ErickyProtect.so"; jstring jclassdex_jar = CharTojstring(env, classdex_jar2); jclass cls_JarFile = env->FindClass("java/util/jar/JarFile"); jmethodID methodID_JarFile = env->GetMethodID(cls_JarFile, "<init>", "(Ljava/lang/String;)V"); jobject localJarFile = env->NewObject(cls_JarFile, methodID_JarFile, SourceDir); //localjarFile getEntry method jmethodID methodID_getentry = env->GetMethodID(cls_JarFile, "getEntry", "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;"); jobject LocalZipEntry = env->CallObjectMethod(localJarFile, methodID_getentry, jclassdex_jar); //localjarFile getInputStream method jmethodID methodID_getInputStream = env->GetMethodID(cls_JarFile, "getInputStream", "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;"); jobject BufferinputstreamParam = env->CallObjectMethod(localJarFile, methodID_getInputStream, LocalZipEntry); //new a File class jclass cls_File = env->FindClass("java/io/File"); jmethodID methodID_File = env->GetMethodID(cls_File, "<init>", "(Ljava/lang/String;)V"); jobject localFile = env->NewObject(cls_File, methodID_File, jdestination); //new BufferedInputStream jclass cls_BufferedInputStream = env->FindClass( "java/io/BufferedInputStream"); jmethodID methodID_BufferedInputStream = env->GetMethodID( cls_BufferedInputStream, "<init>", "(Ljava/io/InputStream;)V"); jobject localBufferedInputStream = env->NewObject(cls_BufferedInputStream, methodID_BufferedInputStream, BufferinputstreamParam); //new FileoutputStream jclass cls_FileOutputStream = env->FindClass("java/io/FileOutputStream"); jmethodID methodID_FileOutputStream = env->GetMethodID(cls_FileOutputStream, "<init>", "(Ljava/io/File;)V"); jobject BufferoutputstreamParam = env->NewObject(cls_FileOutputStream, methodID_FileOutputStream, localFile); //new BufferedOutputStream jclass cls_BufferedOutputStream = env->FindClass( "java/io/BufferedOutputStream"); jmethodID methodID_BufferedOutputStream = env->GetMethodID( cls_BufferedOutputStream, "<init>", "(Ljava/io/OutputStream;)V"); jobject localBufferedOutputStream = env->NewObject(cls_BufferedOutputStream, methodID_BufferedOutputStream, BufferoutputstreamParam); //some preparations jmethodID methodID_write = env->GetMethodID(cls_BufferedOutputStream, "write", "([BII)V"); jmethodID methodID_read = env->GetMethodID(cls_BufferedInputStream, "read", "([B)I"); jmethodID output_flush = env->GetMethodID(cls_BufferedOutputStream, "flush", "()V"); jmethodID output_close = env->GetMethodID(cls_BufferedOutputStream, "close", "()V"); jmethodID input_close = env->GetMethodID(cls_BufferedInputStream, "close", "()V"); while (true) { jint i = env->CallIntMethod(localBufferedInputStream, methodID_read, bytes); LOGI("IIIIIIIIII %d", i); if (i <= 0) { env->CallVoidMethod(localBufferedOutputStream, output_flush); env->CallVoidMethod(localBufferedOutputStream, output_close); env->CallVoidMethod(localBufferedInputStream, input_close); return; } env->CallVoidMethod(localBufferedOutputStream, methodID_write, bytes, 0, i); LOGI("afterwrite %d", i); } } //动态加载DEX JNIEXPORT jobject JNICALL sub_2222(JNIEnv* env, jobject thiz, jobject context) { jclass native_clazz = env->GetObjectClass(context); jmethodID methodID_func = env->GetMethodID(native_clazz, "getPackageName", "()Ljava/lang/String;"); jstring packagename = (jstring) (env->CallObjectMethod(context, methodID_func)); char *aa = "android.app.ActivityThread", *bb = "currentActivityThread"; jstring jaa = CharTojstring(env, aa); jstring jbb = CharTojstring(env, bb); jobjectArray pareTyple; jobjectArray pareVaules; jobject currentActivityThread = invokeStaticMethodss(env, jaa, jbb, pareTyple, pareVaules); char *cc = "android.app.ActivityThread", *dd = "mPackages"; jstring jcc = CharTojstring(env, cc); jstring jdd = CharTojstring(env, dd); jclass class_hashmap = env->FindClass("java/util/HashMap"); jmethodID hashmap_construct_method = env->GetMethodID(class_hashmap, "<init>", "()V"); jobject obj_hashmap = env->NewObject(class_hashmap, hashmap_construct_method, ""); obj_hashmap = getFieldOjbect(env, jcc, currentActivityThread, jdd); jclass class_WeakReference = env->FindClass("java/lang/ref/WeakReference"); if (class_WeakReference == NULL) { LOGI("class_WeakReference Not Found "); } jmethodID WeakReference_get_method = env->GetMethodID(class_WeakReference, "get", "()Ljava/lang/Object;"); if (WeakReference_get_method == NULL) { LOGI("WeakReference_get_method Not Found "); } jmethodID get_func = env->GetMethodID(class_hashmap, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); if (get_func == NULL) { LOGI("get_func Not Found "); } jobject get_obj = env->CallObjectMethod(obj_hashmap, get_func, packagename); if (get_obj == NULL) { LOGI("get_obj Not Found "); } jobject get_get_obj = env->CallObjectMethod(get_obj, WeakReference_get_method); if (get_get_obj == NULL) { LOGI("get_get_obj Not Found "); } //Strings prepared const char *str = env->GetStringUTFChars(packagename, 0); char parameter1[128]; char parameter2[128]; char parameter3[128]; const char *qz = "/data/data/", *hz1 = "/.cache/classdex.jar", *hz2 = "/.cache", *hz3 = "/.cache/"; strcpy(parameter1, qz); strcat(parameter1, str); strcat(parameter1, hz1); strcpy(parameter2, qz); strcat(parameter2, str); strcat(parameter2, hz2); strcpy(parameter3, qz); strcat(parameter3, str); strcat(parameter3, hz3); LOGI("protect parameter1 %s", parameter1); LOGI("protect parameter2 %s", parameter2); LOGI("protect parameter3 %s", parameter3); env->ReleaseStringUTFChars(packagename, str); jstring jparameter1 = CharTojstring(env, parameter1); jstring jparameter2 = CharTojstring(env, parameter2); jstring jparameter3 = CharTojstring(env, parameter3); char *loadapk = "android.app.LoadedApk", *mClassLoader = "mClassLoader"; jstring jloadapk = CharTojstring(env, loadapk); jstring jmClassLoader = CharTojstring(env, mClassLoader); jclass class_DexClassloader = env->FindClass("dalvik/system/DexClassLoader"); if (class_DexClassloader == NULL) { LOGI("class_DexClassloader Not Found "); } jmethodID DexClassloader_construct_method = env->GetMethodID(class_DexClassloader, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V"); if (DexClassloader_construct_method == NULL) { LOGI("DexClassloader_construct_method Not Found "); } jobject obj_DexClassloader = env->NewObject(class_DexClassloader, DexClassloader_construct_method, jparameter1, jparameter2, jparameter3, getFieldOjbect(env, jloadapk, get_get_obj, jmClassLoader)); if (obj_DexClassloader == NULL) { LOGI("obj_DexClassloader Not Found "); } setFieldOjbect(env, jloadapk, jmClassLoader, get_get_obj, obj_DexClassloader); return get_get_obj; } //char* 到 jstring 转换 jstring CharTojstring(JNIEnv* env, char* str) { jsize len = strlen(str); jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("GB2312"); jmethodID mid = env->GetMethodID(clsstring, "<init>", "([BLjava/lang/String;)V"); jbyteArray barr = env->NewByteArray(len); env->SetByteArrayRegion(barr, 0, len, (jbyte*) str); return (jstring) env->NewObject(clsstring, mid, barr, strencode); } //调用指令类的静态函数 jobject invokeStaticMethodss(JNIEnv *env, jstring class_name, jstring method_name, jobjectArray pareTyple, jobjectArray pareVaules) { jclass context = env->FindClass("java/lang/Class"); jmethodID forName_func = env->GetStaticMethodID(context, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); jobject class_obj = env->CallStaticObjectMethod(context, forName_func, class_name); jclass class_java = env->GetObjectClass(class_obj); jmethodID getMethod_func = env->GetMethodID(class_java, "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); jobject method_obj = env->CallObjectMethod(class_obj, getMethod_func, method_name, pareTyple); jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID invoke_func = env->GetMethodID(class_method_obj, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); jobject invoke_obj = env->CallObjectMethod(method_obj, invoke_func, NULL, pareVaules); env->DeleteLocalRef(class_java); env->DeleteLocalRef(method_obj); return invoke_obj; } //获取类的成员变量的值 jobject getFieldOjbect(JNIEnv *env, jstring class_name, jobject obj, jstring fieldName) { jclass context = env->FindClass("java/lang/Class"); jmethodID forName_func = env->GetStaticMethodID(context, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); jobject class_obj = env->CallStaticObjectMethod(context, forName_func, class_name); jclass class_java = env->GetObjectClass(class_obj); jmethodID getField_func = env->GetMethodID(class_java, "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); jobject method_obj = env->CallObjectMethod(class_obj, getField_func, fieldName); jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID setaccess_func = env->GetMethodID(class_method_obj, "setAccessible", "(Z)V"); env->CallVoidMethod(method_obj, setaccess_func, true); jmethodID get_func = env->GetMethodID(class_method_obj, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); jobject get_obj = env->CallObjectMethod(method_obj, get_func, obj); env->DeleteLocalRef(class_java); env->DeleteLocalRef(method_obj); return get_obj; } //修改类的成员变量的值 void setFieldOjbect(JNIEnv *env, jstring class_name, jstring fieldName, jobject obj, jobject filedVaule) { jclass context = env->FindClass("java/lang/Class"); jmethodID forName_func = env->GetStaticMethodID(context, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); jobject class_obj = env->CallStaticObjectMethod(context, forName_func, class_name); jclass class_java = env->GetObjectClass(class_obj); jmethodID getField_func = env->GetMethodID(class_java, "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); jobject method_obj = env->CallObjectMethod(class_obj, getField_func, fieldName); jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID setaccess_func = env->GetMethodID(class_method_obj, "setAccessible", "(Z)V"); env->CallVoidMethod(method_obj, setaccess_func, true); jmethodID set_func = env->GetMethodID(class_method_obj, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); env->CallVoidMethod(method_obj, set_func, obj, filedVaule); env->DeleteLocalRef(class_java); env->DeleteLocalRef(method_obj); }