From 54483ab89bfc4ba2c29aeda89abc2c0092ad596a Mon Sep 17 00:00:00 2001 From: LoveSy Date: Tue, 24 Jan 2023 18:32:35 +0800 Subject: [PATCH] Implement invokeOriginalConstructor --- .../org/lsposed/lspd/impl/LSPosedContext.java | 13 ++++++++++++ .../lsposed/lspd/nativebridge/HookBridge.java | 4 ++++ core/src/main/jni/src/jni/hook_bridge.cpp | 20 +++++++++++++++++++ .../lspd/util/ParasiticManagerHooker.java | 3 ++- 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java index 39f975b5..9e0f3983 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java @@ -51,6 +51,7 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Executable; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; @@ -965,6 +966,18 @@ public class LSPosedContext extends XposedContext { return doDeoptimize(constructor); } + @Nullable + @Override + public Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, Object[] args) throws InvocationTargetException, IllegalAccessException { + return HookBridge.invokeOriginalMethod(method, thisObject, args); + } + + @Nullable + @Override + public T newInstanceOrigin(@NonNull Constructor constructor, Object[] args) throws InvocationTargetException, IllegalAccessException, InstantiationException { + return HookBridge.invokeOriginalConstructor(constructor, constructor.getDeclaringClass(), args); + } + @Override public synchronized void log(@NonNull String message) { Log.i(TAG, mPackageName + ": " + message); diff --git a/core/src/main/java/org/lsposed/lspd/nativebridge/HookBridge.java b/core/src/main/java/org/lsposed/lspd/nativebridge/HookBridge.java index c48c7471..f6a190f4 100644 --- a/core/src/main/java/org/lsposed/lspd/nativebridge/HookBridge.java +++ b/core/src/main/java/org/lsposed/lspd/nativebridge/HookBridge.java @@ -1,5 +1,6 @@ package org.lsposed.lspd.nativebridge; +import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.InvocationTargetException; @@ -7,12 +8,15 @@ import dalvik.annotation.optimization.FastNative; public class HookBridge { public static native boolean hookMethod(Executable hookMethod, Class hooker, int priority, Object callback); + public static native boolean unhookMethod(Executable hookMethod, Object callback); public static native boolean deoptimizeMethod(Executable method); public static native Object invokeOriginalMethod(Executable method, Object thisObject, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; + public static native T invokeOriginalConstructor(Constructor method, Class clazz, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; + @FastNative public static native boolean instanceOf(Object obj, Class clazz); diff --git a/core/src/main/jni/src/jni/hook_bridge.cpp b/core/src/main/jni/src/jni/hook_bridge.cpp index b789ff12..fa867c3d 100644 --- a/core/src/main/jni/src/jni/hook_bridge.cpp +++ b/core/src/main/jni/src/jni/hook_bridge.cpp @@ -143,6 +143,25 @@ LSP_DEF_NATIVE_METHOD(jobject, HookBridge, invokeOriginalMethod, jobject hookMet return env->CallObjectMethod(to_call, invoke, thiz, args); } +LSP_DEF_NATIVE_METHOD(jobject, HookBridge, invokeOriginalConstructor, jobject hookConstructor, + jclass cls, jobjectArray args) { + auto target = env->FromReflectedMethod(hookConstructor); + HookItem * hook_item = nullptr; + { + std::shared_lock lk(hooked_lock); + if (auto found = hooked_methods.find(target); found != hooked_methods.end()) { + hook_item = found->second.get(); + } + } + jobject to_call = hookConstructor; + if (hook_item) { + std::unique_lock lk(backup_lock); + if (hook_item->backup) to_call = hook_item->backup; + } + auto thiz = env->AllocObject(cls); + return env->CallObjectMethod(to_call, invoke, thiz, args); +} + LSP_DEF_NATIVE_METHOD(jboolean, HookBridge, instanceOf, jobject object, jclass expected_class) { return env->IsInstanceOf(object, expected_class); } @@ -180,6 +199,7 @@ static JNINativeMethod gMethods[] = { LSP_NATIVE_METHOD(HookBridge, unhookMethod, "(Ljava/lang/reflect/Executable;Ljava/lang/Object;)Z"), LSP_NATIVE_METHOD(HookBridge, deoptimizeMethod, "(Ljava/lang/reflect/Executable;)Z"), LSP_NATIVE_METHOD(HookBridge, invokeOriginalMethod, "(Ljava/lang/reflect/Executable;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), + LSP_NATIVE_METHOD(HookBridge, invokeOriginalConstructor, "(Ljava/lang/reflect/Constructor;Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;"), LSP_NATIVE_METHOD(HookBridge, instanceOf, "(Ljava/lang/Object;Ljava/lang/Class;)Z"), LSP_NATIVE_METHOD(HookBridge, setTrusted, "(Ljava/lang/Object;)Z"), LSP_NATIVE_METHOD(HookBridge, callbackSnapshot, "(Ljava/lang/reflect/Executable;)[Ljava/lang/Object;"), diff --git a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java index 560382d1..ca506189 100644 --- a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java +++ b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java @@ -236,7 +236,8 @@ public class ParasiticManagerHooker { info.applicationInfo.packageName = packageName + ".origin"; var originalPkgInfo = ActivityThread.currentActivityThread().getPackageInfoNoCheck(info.applicationInfo, HiddenApiBridge.Resources_getCompatibilityInfo(ctx.getResources())); XposedHelpers.setObjectField(originalPkgInfo, "mPackageName", packageName); - originalContext = (Context) XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ContextImpl", null), "createAppContext", ActivityThread.currentActivityThread(), originalPkgInfo); + originalContext = (Context) XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ContextImpl", null), + "createAppContext", ActivityThread.currentActivityThread(), originalPkgInfo); info.applicationInfo.packageName = packageName; } param.args[ctxIdx] = originalContext;