Пример #1
0
static void miui_dexspy_DexspyInstaller_hookMethodNative(JNIEnv* env, jclass clazz, jobject declaredClassIndirect, jint slot) {
    // Usage errors?
    if (declaredClassIndirect == NULL) {
        dvmThrowIllegalArgumentException("declaredClass must not be null");
        return;
    }

    // Find the internal representation of the method
    ClassObject* declaredClass = (ClassObject*) dvmDecodeIndirectRef(dvmThreadSelf(), declaredClassIndirect);
    Method* method = dvmSlotToMethod(declaredClass, slot);
    if (method == NULL) {
        dvmThrowNoSuchMethodError("could not get internal representation for method");
        return;
    }

    if (findOriginalMethod(method) != dexspyOriginalMethods.end()) {
        ALOGD("why this method already hooked: %s:%s(%s)", method->clazz->descriptor, method->name, method->shorty);
        // already hooked
        return;
    }

    // Save a copy of the original method
    dexspyOriginalMethods.push_front(*method);

    // Replace method with our own code
    SET_METHOD_FLAG(method, ACC_NATIVE);
    method->nativeFunc = &dexspyCallHandler;
    method->registersSize = method->insSize;
    method->outsSize = 0;
    #ifdef WITH_JIT
    // reset JIT cache
    gDvmJit.codeCacheFull = true;
    #endif
}
Пример #2
0
static void de_robv_android_xposed_XposedBridge_hookMethodNative(JNIEnv* env, jclass clazz, jobject declaredClassIndirect, jint slot) {
    // Usage errors?
    if (declaredClassIndirect == NULL) {
        dvmThrowIllegalArgumentException("declaredClass must not be null");
        return;
    }
    
    // Find the internal representation of the method
    ClassObject* declaredClass = (ClassObject*) dvmDecodeIndirectRef(dvmThreadSelf(), declaredClassIndirect);
    Method* method = dvmSlotToMethod(declaredClass, slot);
    if (method == NULL) {
        dvmThrowNoSuchMethodError("could not get internal representation for method");
        return;
    }
    
    if (findXposedOriginalMethod(method) != xposedOriginalMethods.end()) {
        // already hooked
        return;
    }
    
    // Save a copy of the original method
    xposedOriginalMethods.push_front(*((MethodXposedExt*)method));

    // Replace method with our own code
    SET_METHOD_FLAG(method, ACC_NATIVE);
    method->nativeFunc = &xposedCallHandler;
    method->registersSize = method->insSize;
    method->outsSize = 0;

    if (PTR_gDvmJit != NULL) {
        // reset JIT cache
        MEMBER_VAL(PTR_gDvmJit, DvmJitGlobals, codeCacheFull) = true;
    }
}
Пример #3
0
static void de_robv_android_xposed_XposedBridge_hookMethodNative(JNIEnv* env,
		jclass clazz, jobject reflectedMethodIndirect,
		jobject declaredClassIndirect, jint slot,
		jobject additionalInfoIndirect) {
	// Usage errors?
	if (declaredClassIndirect == NULL || reflectedMethodIndirect == NULL) {
		dvmThrowIllegalArgumentException(
				"method and declaredClass must not be null");
		return;
	}

	// Find the internal representation of the method
	ClassObject* declaredClass = (ClassObject*) dvmDecodeIndirectRef(
			dvmThreadSelf(), declaredClassIndirect);
	Method* method = dvmSlotToMethod(declaredClass, slot);
	if (method == NULL) {
		dvmThrowNoSuchMethodError(
				"could not get internal representation for method");
		return;
	}


	if (xposedIsHooked(method)) {
		ALOGD("Hook: Ignored! [%s] [%s]\n", declaredClass->descriptor, method->name);
		// already hooked
		return;
	}
	else {
		ALOGD("Hook: [%s] [%s]\n", declaredClass->descriptor, method->name);
	}

	// Save a copy of the original method and other hook info
	XposedHookInfo* hookInfo = (XposedHookInfo*) calloc(1,
			sizeof(XposedHookInfo));
	memcpy(hookInfo, method, sizeof(hookInfo->originalMethodStruct));
	hookInfo->reflectedMethod = dvmDecodeIndirectRef(dvmThreadSelf(),
			env->NewGlobalRef(reflectedMethodIndirect));
	hookInfo->additionalInfo = dvmDecodeIndirectRef(dvmThreadSelf(),
			env->NewGlobalRef(additionalInfoIndirect));

	// Replace method with our own code
	SET_METHOD_FLAG(method, ACC_NATIVE);
	method->nativeFunc = &xposedCallHandler;
	method->insns = (const u2*) hookInfo;
	method->registersSize = method->insSize;
	method->outsSize = 0;

	if (PTR_gDvmJit != NULL) {
		// reset JIT cache
		MEMBER_VAL(PTR_gDvmJit, DvmJitGlobals, codeCacheFull) = true;
	}
}
Пример #4
0
extern "C" JNIEXPORT void JNICALL
Java_com_zhaoxiaodan_hookdemo_Demo1_hook(JNIEnv *env, jobject instance, jobject clazzToHook,
                                                jstring methodName_, jstring methodSig_) {

    const char *methodName = env->GetStringUTFChars(methodName_, 0);
    const char *methodSig = env->GetStringUTFChars(methodSig_, 0);

    jmethodID methodIDToHook = env->GetMethodID((jclass) clazzToHook,methodName,methodSig);

    // 找不到有可能是个static
    if(nullptr == methodIDToHook){
        env->ExceptionClear();
        methodIDToHook = env->GetStaticMethodID((jclass) clazzToHook,methodName,methodSig);
    }


    if(methodIDToHook != nullptr)
    {
        //主要在这里替换
        //jmethodID 在dvm里实际上就是个Method 结构体
        Method* method = (Method*) methodIDToHook;

        //看看method的各个属性都是啥:
        showMethodInfo(method);

        //设置Method 的 accessFlags 为 枚举型
        // ACC_NATIVE 表示 这个method 切换成了一个native 方法
        // 这个枚举 在 dalvik/libdex/DexFile.h
        // 类似:
        // ACC_PUBLIC       = 0x00000001,       // class, field, method, ic
        // ACC_PRIVATE      = 0x00000002,       // field, method, ic
        // ACC_PROTECTED    = 0x00000004,       // field, method, ic
        SET_METHOD_FLAG(method, ACC_NATIVE);

        //既然是一个native方法, 那就把 nativeFunc 指针指向我们的hook, 用来替换test的新方法
        method->nativeFunc = &newTestMethod;

        // registersSize是函数栈大小, insSize是参数占用大小
        // 如果是native方法, 就没有额外开销了
        // 所有开销就是参数占用, 所以把它设置成跟参数占用空间
        method->registersSize=method->insSize;

        //未知
        method->outsSize=0;
    }

    env->ReleaseStringUTFChars(methodName_, methodName);
    env->ReleaseStringUTFChars(methodSig_, methodSig);
}
Пример #5
0
bool HookDalvikMethod(jmethodID jmethod){
	Method *method = (Method*)jmethod;
	//关键!!将目标方法修改为native方法
	SET_METHOD_FLAG(method, ACC_NATIVE);

	int argsSize = dvmComputeMethodArgsSize(method);
    if (!dvmIsStaticMethod(method))
        argsSize++;

    method->registersSize = method->insSize = argsSize;

    if (dvmIsNativeMethod(method)) {
        method->nativeFunc = dvmResolveNativeMethod;
        method->jniArgInfo = computeJniArgInfo(&method->prototype);
    }
}
Пример #6
0
extern "C" int hook_dvm(JNIEnv *env, struct hook_java_args *args) {
    jclass clz, tmp;
    jmethodID jm;
    bool isStatic = false;
    struct hook_java_args *ha = NULL;
    Method *method;
    int argsSize;

    if (loadDVM()) {
        LOGE("hook_dvm: loadDVM() failed");
        return -1;
    }
    if ((args->prev || args->post) && args->func) {
        LOGE("hook_dvm: invalid argument");
        return -1;
    }
    tmp = hsdk_find_clz(env, args->clz);
    if (tmp == NULL) {
        LOGE("hook_dvm: class `%s\' not found", args->clz);
        return -1;
    }
    // XXX: find_clz3w
    // saying given clz is invalid
    //W/dalvikvm( 8493): Invalid indirect reference 0x41cd9338 in decodeIndirectRef
    //E/dalvikvm( 8493): VM aborting
    clz = (jclass) env->NewGlobalRef(tmp);
    env->DeleteLocalRef(tmp);
    if (clz == NULL) {
        LOGE("hook_dvm: unable to ref clz");
        return -1;
    }
    jm = env->GetMethodID(clz, args->mtd, args->sig);
    if (jm == NULL) {
        if (env->ExceptionOccurred())
            env->ExceptionClear();
        jm = env->GetStaticMethodID(clz, args->mtd, args->sig);
        if (env->ExceptionOccurred())
            env->ExceptionClear();
        if (jm == NULL) {
            LOGE("hook_dvm: method `%s\' with sig `%s\' not found", args->mtd, args->sig);
            env->DeleteGlobalRef(clz);
            return -1;
        }
        isStatic = true;
    }
    // XXX: leak the global ref so GC won't recycle the class then Member will be always valid?
    env->DeleteGlobalRef(clz);
    method = (Method *) jm;
    if ((method->nativeFunc == hsdk_bridge_func) ||
        (method->nativeFunc == dvmCallJNIMethod && method->insns == args->func)) {
        LOGD("hook_dvm: already hooked");
        return 0;
    }
    // hook
    args->old = calloc(1, sizeof(*method));
    if (args->old)
        memcpy(args->old, jm, sizeof(*method));
    if (!args->func) {
        ha = (struct hook_java_args *) calloc(1, sizeof(*ha));
        if (!ha) {
            LOGE("hook_dvm: calloc failed");
            if (args->old) {
                free(args->old);
                args->old = 0;
            }
            return -1;
        }
        ha->clz = strdup(args->clz);
        ha->mtd = strdup(args->mtd);
        ha->sig = strdup(args->sig);
        ha->prev = args->prev;
        ha->post = args->post;
    }
    argsSize = dexProtoComputeArgsSize(&method->prototype);
    if (!isStatic)
        argsSize += 1;
    method->registersSize = argsSize;
    method->insSize = argsSize;
    method->outsSize = 0;
    method->insns = NULL;
    method->jniArgInfo = computeJniArgInfo(&method->prototype);
    if (!args->func) {
        method->insns = (const u2*) ha;
        method->nativeFunc = hsdk_bridge_func;
    } else {
        dvmUseJNIBridge(method, args->func);
    }
    SET_METHOD_FLAG(method, ACC_NATIVE);
    if (args->func) {
        LOGD("hook_dvm: %sL%s;%s->%s => %p", isStatic ? "static " : "",
            args->clz, args->mtd, args->sig, args->func);
    }

    return 0;
}