From acc6dfe479590d2e5c65d6af522846b24f76d3b5 Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Wed, 3 Sep 2025 19:58:00 +0300 Subject: [PATCH 1/4] Switch to the new Xposed API --- .github/workflows/core.yml | 1 - core/proguard-rules.pro | 11 ++++-- .../lsposed/lspd/annotation/XposedHooker.java | 11 ++++++ .../org/lsposed/lspd/hooker/AttachHooker.java | 9 +++-- .../lsposed/lspd/hooker/CrashDumpHooker.java | 8 ++-- .../HandleSystemServerProcessHooker.java | 6 +-- .../lspd/hooker/LoadedApkCreateCLHooker.java | 6 +-- .../lspd/hooker/LoadedApkCtorHooker.java | 6 +-- .../lspd/hooker/OpenDexFileHooker.java | 8 ++-- .../hooker/StartBootstrapServicesHooker.java | 6 +-- .../org/lsposed/lspd/impl/LSPosedBridge.java | 8 ++-- .../org/lsposed/lspd/impl/LSPosedContext.java | 38 +++++++++++++++++++ .../util/ParasiticManagerSystemHooker.java | 7 +--- 13 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 0077b0319..6a23ad902 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -45,7 +45,6 @@ jobs: with: repository: libxposed/api path: libxposed/api - ref: 54582730315ba4a3d7cfaf9baf9d23c419e07006 - name: Checkout libxposed/service uses: actions/checkout@v4 diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro index 4638bb630..e7192eacb 100644 --- a/core/proguard-rules.pro +++ b/core/proguard-rules.pro @@ -1,6 +1,7 @@ -keep class android.** { *; } -keep class de.robv.android.xposed.** {*;} -keep class io.github.libxposed.** {*;} +-keep class org.lsposed.lspd.annotation.* {*;} -keep class org.lsposed.lspd.core.* {*;} -keep class org.lsposed.lspd.hooker.HandleSystemServerProcessHooker {*;} -keep class org.lsposed.lspd.hooker.HandleSystemServerProcessHooker$Callback {*;} @@ -22,9 +23,13 @@ -keepclassmembers class org.lsposed.lspd.impl.LSPosedHookCallback { public ; } --keep,allowoptimization,allowobfuscation @io.github.libxposed.api.annotations.* class * { - @io.github.libxposed.api.annotations.BeforeInvocation ; - @io.github.libxposed.api.annotations.AfterInvocation ; +-keepclassmembers,allowoptimization class ** implements io.github.libxposed.api.XposedInterface$Hooker { + public *** before(***); + public *** after(***); +} +-keep,allowoptimization,allowobfuscation @org.lsposed.lspd.annotation.XposedHooker class * { + public *** before(***); + public *** after(***); } -assumenosideeffects class android.util.Log { public static *** v(...); diff --git a/core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java b/core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java new file mode 100644 index 000000000..32a407483 --- /dev/null +++ b/core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java @@ -0,0 +1,11 @@ +package org.lsposed.lspd.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.TYPE_USE}) +public @interface XposedHooker { +} diff --git a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java index b003ac2f5..0f26dc91c 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java @@ -2,16 +2,17 @@ import android.app.ActivityThread; +import androidx.annotation.NonNull; + +import org.lsposed.lspd.annotation.XposedHooker; + import de.robv.android.xposed.XposedInit; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class AttachHooker implements XposedInterface.Hooker { - @AfterInvocation - public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) { + public static void after(@NonNull XposedInterface.AfterHookCallback callback) { XposedInit.loadModules((ActivityThread) callback.getThisObject()); } } diff --git a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java index ea94b132c..0d58eef2d 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java @@ -1,17 +1,17 @@ package org.lsposed.lspd.hooker; +import androidx.annotation.NonNull; + +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.util.Utils.Log; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.BeforeInvocation; -import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class CrashDumpHooker implements XposedInterface.Hooker { - @BeforeInvocation - public static void beforeHookedMethod(XposedInterface.BeforeHookCallback callback) { + public static void before(@NonNull XposedInterface.BeforeHookCallback callback) { try { var e = (Throwable) callback.getArgs()[0]; LSPosedBridge.log("Crash unexpectedly: " + Log.getStackTraceString(e)); diff --git a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java index 4552153e3..f11440662 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java @@ -22,13 +22,12 @@ import android.annotation.SuppressLint; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.util.Hookers; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; // system_server initialization @XposedHooker @@ -42,8 +41,7 @@ public interface Callback { public static volatile Callback callback = null; @SuppressLint("PrivateApi") - @AfterInvocation - public static void afterHookedMethod() { + public static void after() { Hookers.logD("ZygoteInit#handleSystemServerProcess() starts"); try { // get system_server classLoader diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java index 161c730eb..125aaa20b 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java @@ -30,6 +30,7 @@ import androidx.annotation.NonNull; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.MetaDataReader; @@ -51,8 +52,6 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.libxposed.api.XposedInterface; import io.github.libxposed.api.XposedModuleInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; @SuppressLint("BlockedPrivateApi") @XposedHooker @@ -77,8 +76,7 @@ static void addLoadedApk(LoadedApk loadedApk) { loadedApks.add(loadedApk); } - @AfterInvocation - public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) { + public static void after(@NonNull XposedInterface.AfterHookCallback callback) { LoadedApk loadedApk = (LoadedApk) callback.getThisObject(); if (callback.getArgs()[0] != null || !loadedApks.contains(loadedApk)) { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java index e84e3d1d6..ff73881a8 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java @@ -23,21 +23,19 @@ import android.app.LoadedApk; import android.content.res.XResources; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.Utils.Log; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; // when a package is loaded for an existing process, trigger the callbacks as well @XposedHooker public class LoadedApkCtorHooker implements XposedInterface.Hooker { - @AfterInvocation - public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) { + public static void after(XposedInterface.AfterHookCallback callback) { Hookers.logD("LoadedApk# starts"); try { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java index af6f70a2d..e98bd481c 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java @@ -2,18 +2,18 @@ import android.os.Build; +import androidx.annotation.NonNull; + +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.nativebridge.HookBridge; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class OpenDexFileHooker implements XposedInterface.Hooker { - @AfterInvocation - public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) { + public static void after(@NonNull XposedInterface.AfterHookCallback callback) { ClassLoader classLoader = null; for (var arg : callback.getArgs()) { if (arg instanceof ClassLoader) { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java index 30bf835d3..9539b0f7e 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java @@ -24,6 +24,7 @@ import androidx.annotation.NonNull; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; @@ -32,14 +33,11 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.libxposed.api.XposedInterface; import io.github.libxposed.api.XposedModuleInterface; -import io.github.libxposed.api.annotations.BeforeInvocation; -import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class StartBootstrapServicesHooker implements XposedInterface.Hooker { - @BeforeInvocation - public static void beforeHookedMethod() { + public static void before(@NonNull XposedInterface.BeforeHookCallback callback) { logD("SystemServer#startBootstrapServices() starts"); try { diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java index 27c7ce8ce..4f1ca9b06 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java @@ -2,6 +2,7 @@ import androidx.annotation.NonNull; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.nativebridge.HookBridge; import org.lsposed.lspd.util.Utils.Log; @@ -12,9 +13,6 @@ import de.robv.android.xposed.XposedBridge; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.BeforeInvocation; -import io.github.libxposed.api.annotations.XposedHooker; import io.github.libxposed.api.errors.HookFailedError; public class LSPosedBridge { @@ -225,7 +223,7 @@ public static void dummyCallback() { Method beforeInvocation = null, afterInvocation = null; var modifiers = Modifier.PUBLIC | Modifier.STATIC; for (var method : hooker.getDeclaredMethods()) { - if (method.getAnnotation(BeforeInvocation.class) != null) { + if ("before".equals(method.getName())) { if (beforeInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @BeforeInvocation"); } @@ -241,7 +239,7 @@ public static void dummyCallback() { } beforeInvocation = method; } - if (method.getAnnotation(AfterInvocation.class) != null) { + if ("after".equals(method.getName())) { if (afterInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @AfterInvocation"); } 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 9c6b19634..d05565d4c 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java @@ -31,6 +31,7 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -38,6 +39,7 @@ import io.github.libxposed.api.XposedInterface; import io.github.libxposed.api.XposedModule; import io.github.libxposed.api.XposedModuleInterface; +import io.github.libxposed.api.errors.HookFailedError; import io.github.libxposed.api.errors.XposedFrameworkError; import io.github.libxposed.api.utils.DexParser; @@ -170,6 +172,32 @@ public MethodUnhooker hook(@NonNull Method origin, @NonNull Class MethodUnhooker> hookClassInitializer(@NonNull Class origin, @NonNull Class hooker) { + return hookClassInitializer(origin, PRIORITY_DEFAULT, hooker); + } + + @NonNull + @Override + public MethodUnhooker> hookClassInitializer(@NonNull Class origin, int priority, @NonNull Class hooker) { + try { + final var typeParams = hooker.getTypeParameters(); + final Class[] typeParamsArray = new Class[typeParams.length]; + for (int i = 0; i < typeParams.length; i++) { + try { + typeParamsArray[i] = origin.getClassLoader().loadClass(typeParams[i].getTypeName()); + } catch (Throwable e) { + typeParamsArray[i] = Object.class; + } + } + + return LSPosedBridge.doHook(origin.getDeclaredConstructor(typeParamsArray), priority, hooker); + } catch (Throwable e) { + throw new HookFailedError(e); + } + } + @Override @NonNull public MethodUnhooker hook(@NonNull Method origin, int priority, @NonNull Class hooker) { @@ -213,6 +241,11 @@ public Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, return HookBridge.invokeOriginalMethod(method, thisObject, args); } + @Override + public void invokeOrigin(@NonNull Constructor constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException { + HookBridge.invokeOriginalMethod(constructor, thisObject, args); + } + private static char getTypeShorty(Class type) { if (type == int.class) { return 'I'; @@ -256,6 +289,11 @@ public Object invokeSpecial(@NonNull Method method, @NonNull Object thisObject, return HookBridge.invokeSpecialMethod(method, getExecutableShorty(method), method.getDeclaringClass(), thisObject, args); } + @Override + public void invokeSpecial(@NonNull Constructor constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException { + HookBridge.invokeSpecialMethod(constructor, getExecutableShorty(constructor), constructor.getDeclaringClass(), thisObject, args); + } + @NonNull @Override public T newInstanceOrigin(@NonNull Constructor constructor, Object... args) throws InvocationTargetException, IllegalAccessException, InstantiationException { diff --git a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java index 578627a85..9ec936468 100644 --- a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java +++ b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java @@ -6,14 +6,12 @@ import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; +import org.lsposed.lspd.annotation.XposedHooker; import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.service.BridgeService; -import org.lsposed.lspd.util.Utils; import io.github.libxposed.api.XposedInterface; -import io.github.libxposed.api.annotations.AfterInvocation; -import io.github.libxposed.api.annotations.XposedHooker; public class ParasiticManagerSystemHooker implements HandleSystemServerProcessHooker.Callback { @@ -35,8 +33,7 @@ public static void beforeHookedMethod(XposedInterface.BeforeHookCallback callbac @XposedHooker private static class Hooker implements XposedInterface.Hooker { - @AfterInvocation - public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) throws Throwable { + public static void after(XposedInterface.AfterHookCallback callback) throws Throwable { var intent = (Intent) callback.getArgs()[0]; if (intent == null) return; if (!intent.hasCategory("org.lsposed.manager.LAUNCH_MANAGER")) return; From add493877262ce9ebdd71bc084ae192e47e77d8a Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Wed, 3 Sep 2025 22:41:49 +0300 Subject: [PATCH 2/4] Fix the libsposed API included modules --- core/proguard-rules.pro | 2 +- .../github/libxposed/api/annotations}/XposedHooker.java | 2 +- .../src/main/java/org/lsposed/lspd/hooker/AttachHooker.java | 2 +- .../main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java | 2 +- .../lspd/hooker/HandleSystemServerProcessHooker.java | 2 +- .../org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java | 2 +- .../java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java | 2 +- .../java/org/lsposed/lspd/hooker/OpenDexFileHooker.java | 2 +- .../lsposed/lspd/hooker/StartBootstrapServicesHooker.java | 2 +- core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java | 6 +++--- .../org/lsposed/lspd/util/ParasiticManagerSystemHooker.java | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) rename core/src/main/java/{org/lsposed/lspd/annotation => io/github/libxposed/api/annotations}/XposedHooker.java (86%) diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro index e7192eacb..332be3a63 100644 --- a/core/proguard-rules.pro +++ b/core/proguard-rules.pro @@ -27,7 +27,7 @@ public *** before(***); public *** after(***); } --keep,allowoptimization,allowobfuscation @org.lsposed.lspd.annotation.XposedHooker class * { +-keep,allowoptimization,allowobfuscation @io.github.libxposed.api.annotations.* class * { public *** before(***); public *** after(***); } diff --git a/core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java b/core/src/main/java/io/github/libxposed/api/annotations/XposedHooker.java similarity index 86% rename from core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java rename to core/src/main/java/io/github/libxposed/api/annotations/XposedHooker.java index 32a407483..acff8c038 100644 --- a/core/src/main/java/org/lsposed/lspd/annotation/XposedHooker.java +++ b/core/src/main/java/io/github/libxposed/api/annotations/XposedHooker.java @@ -1,4 +1,4 @@ -package org.lsposed.lspd.annotation; +package io.github.libxposed.api.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java index 0f26dc91c..3692ba764 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import de.robv.android.xposed.XposedInit; import io.github.libxposed.api.XposedInterface; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java index 0d58eef2d..7bd454958 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java @@ -2,7 +2,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.util.Utils.Log; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java index f11440662..2aacb7209 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java @@ -22,7 +22,7 @@ import android.annotation.SuppressLint; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.util.Hookers; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java index 125aaa20b..05b68b91b 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java @@ -30,7 +30,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.MetaDataReader; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java index ff73881a8..3803a47f9 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java @@ -23,7 +23,7 @@ import android.app.LoadedApk; import android.content.res.XResources; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.Utils.Log; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java index e98bd481c..c8f0931f5 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.nativebridge.HookBridge; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java index 9539b0f7e..4081911f5 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java @@ -24,7 +24,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java index 4f1ca9b06..e79fe0230 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java @@ -2,7 +2,7 @@ import androidx.annotation.NonNull; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.nativebridge.HookBridge; import org.lsposed.lspd.util.Utils.Log; @@ -223,7 +223,7 @@ public static void dummyCallback() { Method beforeInvocation = null, afterInvocation = null; var modifiers = Modifier.PUBLIC | Modifier.STATIC; for (var method : hooker.getDeclaredMethods()) { - if ("before".equals(method.getName())) { + if ("before".equals(method.getName()) || "beforeHookedMethod".equals(method.getName())) { if (beforeInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @BeforeInvocation"); } @@ -239,7 +239,7 @@ public static void dummyCallback() { } beforeInvocation = method; } - if ("after".equals(method.getName())) { + if ("after".equals(method.getName()) || "afterHookedMethod".equals(method.getName())) { if (afterInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @AfterInvocation"); } diff --git a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java index 9ec936468..29daf4548 100644 --- a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java +++ b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java @@ -6,7 +6,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; -import org.lsposed.lspd.annotation.XposedHooker; +import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.service.BridgeService; From c58e7fd18ec73ea3d6c6521d0c8dca03de180175 Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Wed, 3 Sep 2025 22:44:32 +0300 Subject: [PATCH 3/4] Optimize imports --- .../android/xposed/callbacks/XC_InitPackageResources.java | 5 ----- .../de/robv/android/xposed/callbacks/XC_LoadPackage.java | 6 ------ .../org/lsposed/lspd/core/ApplicationServiceClient.java | 1 - core/src/main/java/org/lsposed/lspd/core/Startup.java | 2 +- .../src/main/java/org/lsposed/lspd/hooker/AttachHooker.java | 3 +-- .../main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java | 2 +- .../lspd/hooker/HandleSystemServerProcessHooker.java | 2 +- .../org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java | 2 +- .../java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java | 2 +- .../java/org/lsposed/lspd/hooker/OpenDexFileHooker.java | 2 +- .../lsposed/lspd/hooker/StartBootstrapServicesHooker.java | 2 +- core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java | 2 +- .../src/main/java/org/lsposed/lspd/impl/LSPosedContext.java | 1 - .../java/org/lsposed/lspd/util/LspModuleClassLoader.java | 4 ++-- .../org/lsposed/lspd/util/ParasiticManagerSystemHooker.java | 3 +-- 15 files changed, 12 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java b/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java index 5c39ec968..dd8e42d72 100644 --- a/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java +++ b/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java @@ -21,15 +21,10 @@ package de.robv.android.xposed.callbacks; import android.content.res.XResources; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import java.util.concurrent.CopyOnWriteArraySet; import de.robv.android.xposed.IXposedHookInitPackageResources; -import io.github.libxposed.api.XposedModuleInterface; /** * This class is only used for internal purposes, except for the {@link InitPackageResourcesParam} diff --git a/core/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java b/core/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java index 848e3eeb3..e428d6cad 100644 --- a/core/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java +++ b/core/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java @@ -21,16 +21,10 @@ package de.robv.android.xposed.callbacks; import android.content.pm.ApplicationInfo; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import java.util.concurrent.CopyOnWriteArraySet; import de.robv.android.xposed.IXposedHookLoadPackage; -import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet; -import io.github.libxposed.api.XposedModuleInterface; /** * This class is only used for internal purposes, except for the {@link LoadPackageParam} diff --git a/core/src/main/java/org/lsposed/lspd/core/ApplicationServiceClient.java b/core/src/main/java/org/lsposed/lspd/core/ApplicationServiceClient.java index 6eb01d0b3..1184852a3 100644 --- a/core/src/main/java/org/lsposed/lspd/core/ApplicationServiceClient.java +++ b/core/src/main/java/org/lsposed/lspd/core/ApplicationServiceClient.java @@ -19,7 +19,6 @@ package org.lsposed.lspd.core; -import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; diff --git a/core/src/main/java/org/lsposed/lspd/core/Startup.java b/core/src/main/java/org/lsposed/lspd/core/Startup.java index e4d08b96d..499c7ca2e 100644 --- a/core/src/main/java/org/lsposed/lspd/core/Startup.java +++ b/core/src/main/java/org/lsposed/lspd/core/Startup.java @@ -31,8 +31,8 @@ import org.lsposed.lspd.hooker.AttachHooker; import org.lsposed.lspd.hooker.CrashDumpHooker; import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker; -import org.lsposed.lspd.hooker.LoadedApkCtorHooker; import org.lsposed.lspd.hooker.LoadedApkCreateCLHooker; +import org.lsposed.lspd.hooker.LoadedApkCtorHooker; import org.lsposed.lspd.hooker.OpenDexFileHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.impl.LSPosedHelper; diff --git a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java index 3692ba764..0579c275e 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/AttachHooker.java @@ -4,10 +4,9 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; - import de.robv.android.xposed.XposedInit; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class AttachHooker implements XposedInterface.Hooker { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java index 7bd454958..935af66cb 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/CrashDumpHooker.java @@ -2,11 +2,11 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.util.Utils.Log; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class CrashDumpHooker implements XposedInterface.Hooker { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java index 2aacb7209..af76acb93 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/HandleSystemServerProcessHooker.java @@ -22,12 +22,12 @@ import android.annotation.SuppressLint; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.util.Hookers; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; // system_server initialization @XposedHooker diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java index 05b68b91b..ddd3cd186 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java @@ -30,7 +30,6 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.MetaDataReader; @@ -52,6 +51,7 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.libxposed.api.XposedInterface; import io.github.libxposed.api.XposedModuleInterface; +import io.github.libxposed.api.annotations.XposedHooker; @SuppressLint("BlockedPrivateApi") @XposedHooker diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java index 3803a47f9..e52fcd348 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java @@ -23,13 +23,13 @@ import android.app.LoadedApk; import android.content.res.XResources; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.Utils.Log; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; // when a package is loaded for an existing process, trigger the callbacks as well @XposedHooker diff --git a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java index c8f0931f5..f0462493b 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/OpenDexFileHooker.java @@ -4,11 +4,11 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedBridge; import org.lsposed.lspd.nativebridge.HookBridge; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class OpenDexFileHooker implements XposedInterface.Hooker { diff --git a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java index 4081911f5..423264450 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/StartBootstrapServicesHooker.java @@ -24,7 +24,6 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.util.Hookers; @@ -33,6 +32,7 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.libxposed.api.XposedInterface; import io.github.libxposed.api.XposedModuleInterface; +import io.github.libxposed.api.annotations.XposedHooker; @XposedHooker public class StartBootstrapServicesHooker implements XposedInterface.Hooker { diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java index e79fe0230..335dfc347 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java @@ -2,7 +2,6 @@ import androidx.annotation.NonNull; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.nativebridge.HookBridge; import org.lsposed.lspd.util.Utils.Log; @@ -13,6 +12,7 @@ import de.robv.android.xposed.XposedBridge; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.XposedHooker; import io.github.libxposed.api.errors.HookFailedError; public class LSPosedBridge { 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 d05565d4c..e175461a1 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java @@ -31,7 +31,6 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.nio.ByteBuffer; -import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; diff --git a/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java b/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java index 56f60b7e6..9e51de964 100644 --- a/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java +++ b/core/src/main/java/org/lsposed/lspd/util/LspModuleClassLoader.java @@ -11,6 +11,8 @@ import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; +import org.lsposed.lspd.util.Utils.Log; + import java.io.File; import java.io.IOException; import java.net.URL; @@ -24,8 +26,6 @@ import java.util.jar.JarFile; import java.util.zip.ZipEntry; -import org.lsposed.lspd.util.Utils.Log; - import hidden.ByteBufferDexClassLoader; import sun.misc.CompoundEnumeration; diff --git a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java index 29daf4548..1baed910c 100644 --- a/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java +++ b/magisk-loader/src/main/java/org/lsposed/lspd/util/ParasiticManagerSystemHooker.java @@ -6,13 +6,12 @@ import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; -import io.github.libxposed.api.annotations.XposedHooker; import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker; import org.lsposed.lspd.impl.LSPosedHelper; import org.lsposed.lspd.service.BridgeService; import io.github.libxposed.api.XposedInterface; - +import io.github.libxposed.api.annotations.XposedHooker; public class ParasiticManagerSystemHooker implements HandleSystemServerProcessHooker.Callback { public static void start() { From 53f91a65395e1eea89bab5e7d20d6d79e849d530 Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Wed, 3 Sep 2025 23:28:24 +0300 Subject: [PATCH 4/4] Add BeforeInvocation and AfterInvocation for the backwards compatibility --- .../libxposed/api/annotations/AfterInvocation.java | 11 +++++++++++ .../libxposed/api/annotations/BeforeInvocation.java | 11 +++++++++++ .../java/org/lsposed/lspd/impl/LSPosedBridge.java | 6 ++++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/io/github/libxposed/api/annotations/AfterInvocation.java create mode 100644 core/src/main/java/io/github/libxposed/api/annotations/BeforeInvocation.java diff --git a/core/src/main/java/io/github/libxposed/api/annotations/AfterInvocation.java b/core/src/main/java/io/github/libxposed/api/annotations/AfterInvocation.java new file mode 100644 index 000000000..e26b3188b --- /dev/null +++ b/core/src/main/java/io/github/libxposed/api/annotations/AfterInvocation.java @@ -0,0 +1,11 @@ +package io.github.libxposed.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AfterInvocation { +} diff --git a/core/src/main/java/io/github/libxposed/api/annotations/BeforeInvocation.java b/core/src/main/java/io/github/libxposed/api/annotations/BeforeInvocation.java new file mode 100644 index 000000000..7b4a17b8a --- /dev/null +++ b/core/src/main/java/io/github/libxposed/api/annotations/BeforeInvocation.java @@ -0,0 +1,11 @@ +package io.github.libxposed.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface BeforeInvocation { +} diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java index 335dfc347..1480e2312 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedBridge.java @@ -12,6 +12,8 @@ import de.robv.android.xposed.XposedBridge; import io.github.libxposed.api.XposedInterface; +import io.github.libxposed.api.annotations.AfterInvocation; +import io.github.libxposed.api.annotations.BeforeInvocation; import io.github.libxposed.api.annotations.XposedHooker; import io.github.libxposed.api.errors.HookFailedError; @@ -223,7 +225,7 @@ public static void dummyCallback() { Method beforeInvocation = null, afterInvocation = null; var modifiers = Modifier.PUBLIC | Modifier.STATIC; for (var method : hooker.getDeclaredMethods()) { - if ("before".equals(method.getName()) || "beforeHookedMethod".equals(method.getName())) { + if (method.getAnnotation(BeforeInvocation.class) != null || "before".equals(method.getName()) || "beforeHookedMethod".equals(method.getName())) { if (beforeInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @BeforeInvocation"); } @@ -239,7 +241,7 @@ public static void dummyCallback() { } beforeInvocation = method; } - if ("after".equals(method.getName()) || "afterHookedMethod".equals(method.getName())) { + if (method.getAnnotation(AfterInvocation.class) != null || "after".equals(method.getName()) || "afterHookedMethod".equals(method.getName())) { if (afterInvocation != null) { throw new IllegalArgumentException("More than one method annotated with @AfterInvocation"); }