From 80987dee03b9e635de5faa1eb04183c6ea5737ab Mon Sep 17 00:00:00 2001 From: LoveSy Date: Mon, 2 Jan 2023 16:30:44 +0800 Subject: [PATCH] Add method hook interface (not implemented yet) --- .../java/android/content/res/XResources.java | 2 +- .../libxposed/XposedContextWrapper.java | 42 +++++++- .../io/github/libxposed/XposedInterface.java | 102 +++++++++++++++++- .../libxposed/XposedModuleInterface.java | 46 +++++--- .../org/lsposed/lspd/impl/LSPosedContext.java | 43 +++++++- 5 files changed, 206 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/android/content/res/XResources.java b/core/src/main/java/android/content/res/XResources.java index d9ae8fd7..b14fdef4 100644 --- a/core/src/main/java/android/content/res/XResources.java +++ b/core/src/main/java/android/content/res/XResources.java @@ -1275,7 +1275,7 @@ public class XResources extends XposedResources { * Mainly used when inflating layouts. * @hide */ - public static class XTypedArray extends XTypedArraySuperClass { + public static class XTypedArray extends XposedTypedArray { public XTypedArray(Resources resources) { super(resources); diff --git a/core/src/main/java/io/github/libxposed/XposedContextWrapper.java b/core/src/main/java/io/github/libxposed/XposedContextWrapper.java index d1b400c4..50086f9e 100644 --- a/core/src/main/java/io/github/libxposed/XposedContextWrapper.java +++ b/core/src/main/java/io/github/libxposed/XposedContextWrapper.java @@ -5,6 +5,9 @@ import android.content.ContextWrapper; import androidx.annotation.NonNull; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + public class XposedContextWrapper extends ContextWrapper implements XposedInterface { XposedContextWrapper(XposedContext base) { @@ -15,14 +18,13 @@ public class XposedContextWrapper extends ContextWrapper implements XposedInterf super(base); } - @Override - final public XposedContext getBaseContext() { - return (XposedContext) super.getBaseContext(); + final long getAPIVersion() { + return 100; } @Override - final public void hook() { - getBaseContext().hook(); + final public XposedContext getBaseContext() { + return (XposedContext) super.getBaseContext(); } @NonNull @@ -42,6 +44,36 @@ public class XposedContextWrapper extends ContextWrapper implements XposedInterf return getBaseContext().implementationVersionCode(); } + @Override + public MethodUnhooker, Method> hookBefore(@NonNull Method origin, @NonNull BeforeMethodHooker hooker) { + return getBaseContext().hookBefore(origin, hooker); + } + + @Override + public MethodUnhooker, Method> hookAfter(@NonNull Method origin, @NonNull AfterMethodHooker hooker) { + return getBaseContext().hookAfter(origin, hooker); + } + + @Override + public MethodUnhooker, Method> hook(@NonNull Method origin, @NonNull MethodHooker hooker) { + return getBaseContext().hook(origin, hooker); + } + + @Override + public MethodUnhooker>, Constructor> hookBefore(@NonNull Constructor origin, @NonNull BeforeMethodHooker> hooker) { + return getBaseContext().hookBefore(origin, hooker); + } + + @Override + public MethodUnhooker>, Constructor> hookAfter(@NonNull Constructor origin, @NonNull AfterMethodHooker> hooker) { + return getBaseContext().hookAfter(origin, hooker); + } + + @Override + public MethodUnhooker>, Constructor> hook(@NonNull Constructor origin, @NonNull MethodHooker> hooker) { + return getBaseContext().hook(origin, hooker); + } + @Override final public void log(@NonNull String message) { getBaseContext().log(message); diff --git a/core/src/main/java/io/github/libxposed/XposedInterface.java b/core/src/main/java/io/github/libxposed/XposedInterface.java index e620a9d0..06058245 100644 --- a/core/src/main/java/io/github/libxposed/XposedInterface.java +++ b/core/src/main/java/io/github/libxposed/XposedInterface.java @@ -1,17 +1,111 @@ package io.github.libxposed; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; public interface XposedInterface { + interface BeforeHookCallback { + @NonNull + T getOrigin(); - long API_VERSION = 100; + @Nullable + Object getThis(); - void hook(); + @NonNull + Object[] getArgs(); + + void returnAndSkip(@Nullable Object returnValue); + + void throwAndSkip(@Nullable Throwable throwable); + + @Nullable + Object invokeOrigin(@Nullable Object thisObject, Object[] args); + + void setExtra(String key, @Nullable U value); + } + + interface AfterHookCallback { + @NonNull + T getOrigin(); + + @Nullable + Object getThis(); + + @NonNull + Object[] getArgs(); + + @Nullable + Object getResult(); + + @Nullable + Throwable getThrowable(); + + boolean isSkipped(); + + void setResult(@Nullable Object result); + + void setThrowable(@Nullable Throwable throwable); + + @Nullable + Object invokeOrigin(@Nullable Object thisObject, Object[] args); + + @Nullable + U getExtra(String key); + } + + interface PriorityMethodHooker { + int PRIORITY_DEFAULT = 50; + + default int getPriority() { + return PRIORITY_DEFAULT; + } + } + + interface BeforeMethodHooker extends PriorityMethodHooker { + void before(@NonNull BeforeHookCallback callback); + } + + interface AfterMethodHooker extends PriorityMethodHooker { + void after(@NonNull AfterHookCallback callback); + } + + interface MethodHooker extends BeforeMethodHooker, AfterMethodHooker { + } + + interface MethodUnhooker { + @NonNull + U getOrigin(); + + @NonNull + T getHooker(); + + void unhook(); + } + + @NonNull + String implementationName(); + + @NonNull + String implementationVersion(); - @NonNull String implementationName(); - @NonNull String implementationVersion(); long implementationVersionCode(); + MethodUnhooker, Method> hookBefore(@NonNull Method origin, @NonNull BeforeMethodHooker hooker); + + MethodUnhooker, Method> hookAfter(@NonNull Method origin, @NonNull AfterMethodHooker hooker); + + MethodUnhooker, Method> hook(@NonNull Method origin, @NonNull MethodHooker hooker); + + MethodUnhooker>, Constructor> hookBefore(@NonNull Constructor origin, @NonNull BeforeMethodHooker> hooker); + + MethodUnhooker>, Constructor> hookAfter(@NonNull Constructor origin, @NonNull AfterMethodHooker> hooker); + + MethodUnhooker>, Constructor> hook(@NonNull Constructor origin, @NonNull MethodHooker> hooker); + void log(@NonNull String message); + void log(@NonNull String message, @NonNull Throwable throwable); } diff --git a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java b/core/src/main/java/io/github/libxposed/XposedModuleInterface.java index a75bdb28..509fceee 100644 --- a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java +++ b/core/src/main/java/io/github/libxposed/XposedModuleInterface.java @@ -11,32 +11,50 @@ import androidx.annotation.Nullable; public interface XposedModuleInterface { interface ModuleLoadedParam { boolean isSystemServer(); - @NonNull String getProcessName(); - @NonNull String getAppDataDir(); - @Nullable Bundle getExtras(); + + @NonNull + String getProcessName(); + + @NonNull + String getAppDataDir(); + + @Nullable + Bundle getExtras(); } interface PackageLoadedParam { - @NonNull String getPackageName(); - @NonNull ApplicationInfo getAppInfo(); - @NonNull ClassLoader getClassLoader(); - @NonNull String getProcessName(); + @NonNull + String getPackageName(); + + @NonNull + ApplicationInfo getAppInfo(); + + @NonNull + ClassLoader getClassLoader(); + + @NonNull + String getProcessName(); + boolean isFirstApplication(); - @Nullable Bundle getExtras(); + + @Nullable + Bundle getExtras(); } interface ResourcesLoadedParam { - @NonNull String getPackageName(); - @NonNull XposedResources getResources(); - @Nullable Bundle getExtras(); + @NonNull + String getPackageName(); + + @NonNull + XposedResources getResources(); + + @Nullable + Bundle getExtras(); } default void onPackageLoaded(@NonNull PackageLoadedParam param) { - } default void onResourceLoaded(@NonNull ResourcesLoadedParam param) { - } - } 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 cd985afa..1207eacc 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java @@ -42,6 +42,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -720,11 +722,6 @@ public class LSPosedContext extends XposedContext { throw new AbstractMethodError(); } - @Override - public void hook() { - throw new AbstractMethodError(); - } - @NonNull @Override public String implementationName() { @@ -742,6 +739,42 @@ public class LSPosedContext extends XposedContext { return 0; } + // TODO + @Override + public MethodUnhooker, Method> hookBefore(@NonNull Method origin, @NonNull BeforeMethodHooker hooker) { + return null; + } + + // TODO + @Override + public MethodUnhooker, Method> hookAfter(@NonNull Method origin, @NonNull AfterMethodHooker hooker) { + return null; + } + + // TODO + @Override + public MethodUnhooker, Method> hook(@NonNull Method origin, @NonNull MethodHooker hooker) { + return null; + } + + // TODO + @Override + public MethodUnhooker>, Constructor> hookBefore(@NonNull Constructor origin, @NonNull BeforeMethodHooker> hooker) { + return null; + } + + // TODO + @Override + public MethodUnhooker>, Constructor> hookAfter(@NonNull Constructor origin, @NonNull AfterMethodHooker> hooker) { + return null; + } + + // TODO + @Override + public MethodUnhooker>, Constructor> hook(@NonNull Constructor origin, @NonNull MethodHooker> hooker) { + return null; + } + @Override public void log(@NonNull String message) { Log.i(TAG, mPackageName + ": " + message);