Exemplo n.º 1
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);
    }
}
Exemplo n.º 2
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;
}