Implement invokeOriginalConstructor

This commit is contained in:
LoveSy 2023-01-24 18:32:35 +08:00 committed by LoveSy
parent e1e716b52f
commit 54483ab89b
4 changed files with 39 additions and 1 deletions

View File

@ -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> T newInstanceOrigin(@NonNull Constructor<T> 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);

View File

@ -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> T invokeOriginalConstructor(Constructor<T> method, Class<T> clazz, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
@FastNative
public static native boolean instanceOf(Object obj, Class<?> clazz);

View File

@ -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;"),

View File

@ -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;