自学内容网 自学内容网

Lsposed Java HOOK原理及检测

当使用 XposedBridge.hookMethod 这个 api对java函数进行hook时:

public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_MethodHook callback) {
    if (!(hookMethod instanceof Executable)) {
        throw new IllegalArgumentException("Only methods and constructors can be hooked: " + hookMethod);
    } else if (Modifier.isAbstract(hookMethod.getModifiers())) {
        throw new IllegalArgumentException("Cannot hook abstract methods: " + hookMethod);
    } else if (hookMethod.getDeclaringClass().getClassLoader() == XposedBridge.class.getClassLoader()) {
        throw new IllegalArgumentException("Do not allow hooking inner methods");
    } else if (hookMethod.getDeclaringClass() == Method.class && hookMethod.getName().equals("invoke")) {
        throw new IllegalArgumentException("Cannot hook Method.invoke");
    }
 
 
    if (callback == null) {
        throw new IllegalArgumentException("callback should not be null!");
    }
 
    if (!HookBridge.hookMethod(false, (Executable) hookMethod, LSPosedBridge.NativeHooker.class, callback.priority, callback)) {
        log("Failed to hook " + hookMethod);
        return null;
    }
 
    return callback.new Unhook(hookMethod);
}

会调用  HookBridge.hookMethod 这个内部api,实现在native层:

public class HookBridge {
    public static native boolean hookMethod(boolean useModernApi, Executable hookMethod, Class<?> hooker, int priority, Object callback);
 
 
    public static native boolean unhookMethod(boolean useModernApi, Executable hookMethod, Object callback);
 
    public static native boolean deoptimizeMethod(Executable method);
 
    public static native <T> T allocateObject(Class<T> clazz) throws InstantiationException;
 
    public static native Object invokeOriginalMethod(Executable method, Object thisObject, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
 
    public static native <T> Object invokeSpecialMethod(Executable method, char[] shorty, Class<T> clazz, Object thisObject, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
 
    @FastNative
    public static native boolean instanceOf(Object obj, Class<?> clazz);
 
    @FastNative
    public static native boolean setTrusted(Object cookie);
 
    public static native Object[][] callbackSnapshot(Class<?> hooker_callback, Executable method);
}

native层方法定义如下:

LSP_DEF_NATIVE_METHOD(jboolean, HookBridge, hookMethod, jboolean useModernApi, jobject hookMethod,
                      jclass hooker, jint priority, jobject callback) {
    bool newHook = false;
#ifndef NDEBUG
    struct finally {
        std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
        bool &newHook;
        ~finally() {
            auto finish = std::chrono::steady_clock::now();
            if (newHook) {
                LOGV("New hook took {}us",
                     std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count());
            }
        }
    } finally {
        .newHook = newHook
    };
#endif
    auto target = env->FromReflectedMethod(hookMethod);     //ArtMethod 结构体
    HookItem * hook_item = nullptr;
    hooked_methods.lazy_emplace_l(target, [&hook_item](auto &it) {
        hook_item = it.second.get();
    }, [&hook_item, &target, &newHook](const auto &ctor) {
        auto ptr = std::make_unique<HookItem>();
        hook_item = ptr.get();
        ctor(target, std::move(ptr));
        newHook = true;
    });
    if (newHook) {
        auto init = env->GetMethodID(hooker, "<init>", "(Ljava/lang/reflect/Executable;)V");
        auto callback_method = env->ToReflectedMethod(hooker, env->GetMethodID(hooker, "callback",   //LSPosedBridge.NativeHooker
                                                                               "([Ljava/lang/Object;)Ljava/lang/Object;"),
                                                      false);
        auto hooker_object = env->NewObject(hooker, init, hookMethod);  //新建 NativeHooker 对象,传入 目标hookMethod
        hook_item->SetBackup(lsplant::Hook(env, hookMethod, hooker_object, callback_method)); //传入的目标method 和 NativeHooker对象
        env->DeleteLocalRef(hooker_object);
    }
    jobject backup = hook_item->GetBackup();
    if (!backup) return JNI_FALSE;
    JNIMonitor monitor(env, backup);
    if (useModernApi) {
        if (before_method_field == nullptr) {
            auto callback_class = JNI_GetObjectClass(env, callback);
            callback_ctor = JNI_GetMethodID(env, callback_class, "<init>", "(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V");
            before_method_field = JNI_GetFieldID(env, callback_class, &#

原文地址:https://blog.csdn.net/a545958498/article/details/142434756

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!