Save zygoteInit callbacks to invoke after process forked

This commit is contained in:
solohsu 2019-02-11 16:23:23 +08:00
parent e4051c5e28
commit 8c4682e2b3
4 changed files with 33 additions and 3 deletions

View File

@ -55,6 +55,7 @@ public class Main implements KeepAll {
sAppDataDir = appDataDir; sAppDataDir = appDataDir;
sIsGlobalMode = isGlobalMode; sIsGlobalMode = isGlobalMode;
sIsDynamicModules = isDynamicModules; sIsDynamicModules = isDynamicModules;
Router.prepare(false);
if (isGlobalMode) { if (isGlobalMode) {
// do bootstrap hooking only once in zygote process // do bootstrap hooking only once in zygote process
Router.onProcessForked(false); Router.onProcessForked(false);
@ -78,6 +79,7 @@ public class Main implements KeepAll {
// load modules for each app process on its forked // load modules for each app process on its forked
Router.loadModulesSafely(); Router.loadModulesSafely();
} }
Router.callZygoteInits();
} else { } else {
// in zygote process, res is child zygote pid // 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 // 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); // Utils.logD(sForkSystemServerPramsStr + " = " + pid);
if (pid == 0) { if (pid == 0) {
// in system_server process // in system_server process
Router.prepare(true);
Router.onProcessForked(true); Router.onProcessForked(true);
Router.loadModulesSafely(); Router.loadModulesSafely();
Router.callZygoteInits();
} else { } else {
// in zygote process, res is child zygote pid // 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 // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66

View File

@ -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.entry.hooker.SystemMainHooker;
import com.elderdrivers.riru.xposed.util.Utils; 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.XposedBridge;
import de.robv.android.xposed.XposedInit; import de.robv.android.xposed.XposedInit;
public class Router { public class Router {
public static void prepare(boolean isSystem) {
// this flag is needed when loadModules
XposedInit.startsSystemServer = isSystem;
}
public static void onProcessForked(boolean isSystem) { public static void onProcessForked(boolean isSystem) {
// Initialize the Xposed framework // Initialize the Xposed framework
try { try {
@ -31,6 +39,16 @@ public class Router {
} }
} }
public static void callZygoteInits() {
for (Map.Entry<IXposedHookZygoteInit, IXposedHookZygoteInit.StartupParam> 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) { public static void startBootstrapHook(boolean isSystem) {
Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); Utils.logD("startBootstrapHook starts: isSystem = " + isSystem);
ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER; ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER;

View File

@ -65,6 +65,7 @@ public final class XposedBridge {
// built-in handlers // built-in handlers
private static final Map<Member, CopyOnWriteSortedSet<XC_MethodHook>> sHookedMethodCallbacks = new HashMap<>(); private static final Map<Member, CopyOnWriteSortedSet<XC_MethodHook>> sHookedMethodCallbacks = new HashMap<>();
public static final CopyOnWriteSortedSet<XC_LoadPackage> sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>(); public static final CopyOnWriteSortedSet<XC_LoadPackage> sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>();
public static final HashMap<IXposedHookZygoteInit, IXposedHookZygoteInit.StartupParam> sZygoteInitCallbacks = new HashMap<>();
/*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>(); /*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>();
private XposedBridge() {} 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. * Adds a callback to be executed when the resources for an app are initialized.
* *

View File

@ -34,7 +34,7 @@ import static de.robv.android.xposed.XposedHelpers.setStaticLongField;
public final class XposedInit { public final class XposedInit {
private static final String TAG = XposedBridge.TAG; 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 private static final String startClassName = ""; // ed: no support for tool process anymore
public static final String INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager"; 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)) { if (!bootstrapHooked.compareAndSet(false, true)) {
return; return;
} }
startsSystemServer = isSystem;
Router.startBootstrapHook(isSystem); Router.startBootstrapHook(isSystem);
// MIUI // MIUI
if (findFieldIfExists(ZygoteInit.class, "BOOT_START_TIME") != null) { if (findFieldIfExists(ZygoteInit.class, "BOOT_START_TIME") != null) {
@ -209,7 +208,8 @@ public final class XposedInit {
IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam(); IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
param.modulePath = apk; param.modulePath = apk;
param.startsSystemServer = startsSystemServer; param.startsSystemServer = startsSystemServer;
((IXposedHookZygoteInit) moduleInstance).initZygote(param); // ((IXposedHookZygoteInit) moduleInstance).initZygote(param);
XposedBridge.hookZygoteInit((IXposedHookZygoteInit) moduleInstance, param);
} }
if (moduleInstance instanceof IXposedHookLoadPackage) if (moduleInstance instanceof IXposedHookLoadPackage)