From 8c4682e2b3e908c4aa42cd4a0ebd18edb90345ca Mon Sep 17 00:00:00 2001 From: solohsu Date: Mon, 11 Feb 2019 16:23:23 +0800 Subject: [PATCH] Save zygoteInit callbacks to invoke after process forked --- .../com/elderdrivers/riru/xposed/Main.java | 4 ++++ .../elderdrivers/riru/xposed/entry/Router.java | 18 ++++++++++++++++++ .../de/robv/android/xposed/XposedBridge.java | 8 ++++++++ .../de/robv/android/xposed/XposedInit.java | 6 +++--- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java index 2b2ba27b..abbdb287 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java @@ -55,6 +55,7 @@ public class Main implements KeepAll { sAppDataDir = appDataDir; sIsGlobalMode = isGlobalMode; sIsDynamicModules = isDynamicModules; + Router.prepare(false); if (isGlobalMode) { // do bootstrap hooking only once in zygote process Router.onProcessForked(false); @@ -78,6 +79,7 @@ public class Main implements KeepAll { // load modules for each app process on its forked Router.loadModulesSafely(); } + Router.callZygoteInits(); } else { // in zygote process, res is child zygote pid // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66 @@ -97,8 +99,10 @@ public class Main implements KeepAll { // Utils.logD(sForkSystemServerPramsStr + " = " + pid); if (pid == 0) { // in system_server process + Router.prepare(true); Router.onProcessForked(true); Router.loadModulesSafely(); + Router.callZygoteInits(); } else { // in zygote process, res is child zygote pid // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66 diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/Router.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/Router.java index 76b78546..829eb4c0 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/Router.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/Router.java @@ -7,11 +7,19 @@ import com.elderdrivers.riru.xposed.entry.bootstrap.SysInnerHookInfo; import com.elderdrivers.riru.xposed.entry.hooker.SystemMainHooker; import com.elderdrivers.riru.xposed.util.Utils; +import java.util.Map; + +import de.robv.android.xposed.IXposedHookZygoteInit; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedInit; public class Router { + public static void prepare(boolean isSystem) { + // this flag is needed when loadModules + XposedInit.startsSystemServer = isSystem; + } + public static void onProcessForked(boolean isSystem) { // Initialize the Xposed framework try { @@ -31,6 +39,16 @@ public class Router { } } + public static void callZygoteInits() { + for (Map.Entry entry : XposedBridge.sZygoteInitCallbacks.entrySet()) { + try { + entry.getKey().initZygote(entry.getValue()); + } catch (Throwable t) { + Utils.logE("Failed to load class " + entry.getKey().getClass(), t); + } + } + } + public static void startBootstrapHook(boolean isSystem) { Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER; diff --git a/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java index 55badbca..d98f693f 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -65,6 +65,7 @@ public final class XposedBridge { // built-in handlers private static final Map> sHookedMethodCallbacks = new HashMap<>(); public static final CopyOnWriteSortedSet sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>(); + public static final HashMap sZygoteInitCallbacks = new HashMap<>(); /*package*/ static final CopyOnWriteSortedSet sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>(); private XposedBridge() {} @@ -373,6 +374,13 @@ public final class XposedBridge { } } + public static void hookZygoteInit(IXposedHookZygoteInit moduleInstance, + IXposedHookZygoteInit.StartupParam param) { + synchronized (sZygoteInitCallbacks) { + sZygoteInitCallbacks.put(moduleInstance, param); + } + } + /** * Adds a callback to be executed when the resources for an app are initialized. * diff --git a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java index 2502b61d..390007ea 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java @@ -34,7 +34,7 @@ import static de.robv.android.xposed.XposedHelpers.setStaticLongField; public final class XposedInit { private static final String TAG = XposedBridge.TAG; - private static boolean startsSystemServer = false; + public static boolean startsSystemServer = false; private static final String startClassName = ""; // ed: no support for tool process anymore public static final String INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager"; @@ -61,7 +61,6 @@ public final class XposedInit { if (!bootstrapHooked.compareAndSet(false, true)) { return; } - startsSystemServer = isSystem; Router.startBootstrapHook(isSystem); // MIUI if (findFieldIfExists(ZygoteInit.class, "BOOT_START_TIME") != null) { @@ -209,7 +208,8 @@ public final class XposedInit { IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam(); param.modulePath = apk; param.startsSystemServer = startsSystemServer; - ((IXposedHookZygoteInit) moduleInstance).initZygote(param); +// ((IXposedHookZygoteInit) moduleInstance).initZygote(param); + XposedBridge.hookZygoteInit((IXposedHookZygoteInit) moduleInstance, param); } if (moduleInstance instanceof IXposedHookLoadPackage)