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 d8621221..2bd4ff7a 100644 --- a/core/src/main/java/org/lsposed/lspd/core/Startup.java +++ b/core/src/main/java/org/lsposed/lspd/core/Startup.java @@ -32,6 +32,7 @@ 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.LoadedApkGetCLHooker; import org.lsposed.lspd.hooker.OpenDexFileHooker; import org.lsposed.lspd.impl.LSPosedContext; import org.lsposed.lspd.impl.LSPosedHelper; @@ -56,6 +57,7 @@ public class Startup { LSPosedHelper.hookConstructor(LoadedApkCtorHooker.class, LoadedApk.class, ActivityThread.class, ApplicationInfo.class, CompatibilityInfo.class, ClassLoader.class, boolean.class, boolean.class, boolean.class); + LSPosedHelper.hookMethod(LoadedApkGetCLHooker.class, LoadedApk.class, "getClassLoader"); LSPosedHelper.hookAllMethods(AttachHooker.class, ActivityThread.class, "attach"); } 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 0721d7b9..00f1f7ce 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java @@ -72,7 +72,7 @@ public class LoadedApkCtorHooker implements XposedInterface.Hooker { return; } - new LoadedApkGetCLHooker(loadedApk); + LoadedApkGetCLHooker.addLoadedApk(loadedApk); } catch (Throwable t) { Hookers.logE("error when hooking LoadedApk.", t); } diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java index 8e7c476c..f36f8644 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java @@ -40,6 +40,8 @@ import java.io.IOException; import java.lang.reflect.Field; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; @@ -47,12 +49,18 @@ import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; 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") -public class LoadedApkGetCLHooker extends XC_MethodHook { +@XposedHooker +public class LoadedApkGetCLHooker implements XposedInterface.Hooker { private final static Field defaultClassLoaderField; + private final static Set loadedApks = ConcurrentHashMap.newKeySet(); + static { Field field = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -65,19 +73,15 @@ public class LoadedApkGetCLHooker extends XC_MethodHook { defaultClassLoaderField = field; } - private final LoadedApk loadedApk; - private final Unhook unhook; - - public LoadedApkGetCLHooker(LoadedApk loadedApk) { - this.loadedApk = loadedApk; - unhook = XposedHelpers.findAndHookMethod(LoadedApk.class, "getClassLoader", this); + static void addLoadedApk(LoadedApk loadedApk) { + loadedApks.add(loadedApk); } - @Override - protected void afterHookedMethod(MethodHookParam param) { - LoadedApk loadedApk = (LoadedApk) param.thisObject; + @AfterInvocation + public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) { + LoadedApk loadedApk = (LoadedApk) callback.getThisObject(); - if (loadedApk != this.loadedApk) { + if (!loadedApks.contains(loadedApk)) { return; } @@ -95,7 +99,7 @@ public class LoadedApkGetCLHooker extends XC_MethodHook { } Object mAppDir = XposedHelpers.getObjectField(loadedApk, "mAppDir"); - ClassLoader classLoader = (ClassLoader) param.getResult(); + ClassLoader classLoader = (ClassLoader) callback.getResult(); Hookers.logD("LoadedApk#getClassLoader ends: " + mAppDir + " -> " + classLoader); if (classLoader == null) { @@ -163,11 +167,11 @@ public class LoadedApkGetCLHooker extends XC_MethodHook { } catch (Throwable t) { Hookers.logE("error when hooking LoadedApk#getClassLoader", t); } finally { - unhook.unhook(); + loadedApks.remove(loadedApk); } } - private void hookNewXSP(XC_LoadPackage.LoadPackageParam lpparam) { + private static void hookNewXSP(XC_LoadPackage.LoadPackageParam lpparam) { int xposedminversion = -1; boolean xposedsharedprefs = false; try {