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 5259aca9..0ac415f4 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/Main.java @@ -122,9 +122,9 @@ public class Main implements KeepAll { // prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote // https://github.com/rovo89/Xposed/commit/b3ba245ad04cd485699fb1d2ebde7117e58214ff - public static native long closeFilesBeforeForkNative(); + public static native void closeFilesBeforeForkNative(); - public static native void reopenFilesAfterForkNative(long fdTable); + public static native void reopenFilesAfterForkNative(); public static native void deoptMethodNative(Object object); 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 f8f7ed8c..5510caa9 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 @@ -2,7 +2,6 @@ package com.elderdrivers.riru.xposed.entry; import android.text.TextUtils; -import com.elderdrivers.riru.xposed.Main; import com.elderdrivers.riru.xposed.core.HookMain; import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge; import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo; @@ -52,25 +51,11 @@ public class Router { } public static void loadModulesSafely(boolean isInZygote) { - boolean loadedByMe; try { // FIXME some coredomain app can't reading modules.list - loadedByMe = XposedInit.loadModules(); + XposedInit.loadModules(isInZygote); } catch (Exception exception) { Utils.logE("error loading module list", exception); - // return true in case there are files opened... - loadedByMe = true; - } - // at last close all fds - if (isInZygote && loadedByMe) { - Main.closedFdTable = Main.closeFilesBeforeForkNative(); - } - } - - public static void reopenFilesIfNeeded() { - long closedFdTable = Main.closedFdTable; - if (closedFdTable != 0) { - Main.reopenFilesAfterForkNative(closedFdTable); } } diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/BlackWhiteListProxy.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/BlackWhiteListProxy.java index 7b3ec5c9..c0c5ab1b 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/BlackWhiteListProxy.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/BlackWhiteListProxy.java @@ -84,21 +84,24 @@ public class BlackWhiteListProxy { // loadModules once for all child processes of zygote // TODO maybe just save initZygote callbacks and call them when whitelisted process forked? Router.loadModulesSafely(true); + Main.closeFilesBeforeForkNative(); } private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) { Main.appDataDir = appDataDir; Main.niceName = niceName; + final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled(); + ConfigManager.setDynamicModulesMode(isDynamicModulesMode); Router.onEnterChildProcess(); + if (!isDynamicModulesMode) { + Main.reopenFilesAfterForkNative(); + } if (!checkNeedHook(appDataDir, niceName)) { // if is blacklisted, just stop here return; } - final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled(); - ConfigManager.setDynamicModulesMode(isDynamicModulesMode); Router.prepare(isSystemServer); PrebuiltMethodsDeopter.deoptBootMethods(); - Router.reopenFilesIfNeeded(); Router.installBootstrapHooks(isSystemServer); if (isDynamicModulesMode) { Router.loadModulesSafely(false); diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/NormalProxy.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/NormalProxy.java index 51ee8eb7..b60e9e0c 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/NormalProxy.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/proxy/yahfa/NormalProxy.java @@ -22,10 +22,9 @@ public class NormalProxy { PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote // install bootstrap hooks for secondary zygote Router.installBootstrapHooks(false); - if (Main.closedFdTable == 0) { - // only load modules for secondary zygote - Router.loadModulesSafely(true); - } + // only load modules for secondary zygote + Router.loadModulesSafely(true); + Main.closeFilesBeforeForkNative(); } public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) { @@ -33,7 +32,7 @@ public class NormalProxy { Main.appDataDir = appDataDir; Main.niceName = niceName; Router.prepare(false); - Router.reopenFilesIfNeeded(); + Main.reopenFilesAfterForkNative(); Router.onEnterChildProcess(); // load modules for each app process on its forked if dynamic modules mode is on Router.loadModulesSafely(false); @@ -54,6 +53,7 @@ public class NormalProxy { // because if not global hooks installed in initZygote might not be // propagated to processes not forked via forkAndSpecialize Router.loadModulesSafely(true); + Main.closeFilesBeforeForkNative(); } public static void forkSystemServerPost(int pid) { @@ -61,7 +61,7 @@ public class NormalProxy { Main.appDataDir = getDataPathPrefix() + "android"; Main.niceName = "system_server"; Router.prepare(true); - Router.reopenFilesIfNeeded(); + Main.reopenFilesAfterForkNative(); Router.onEnterChildProcess(); // reload module list if dynamic mode is on Router.loadModulesSafely(false); 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 1e917390..20700ebb 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java @@ -88,10 +88,11 @@ public final class XposedInit { */ private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false); - public static boolean loadModules() throws IOException { - if (!modulesLoaded.compareAndSet(false, true) - && !ConfigManager.isDynamicModulesMode()) { - return false; + public static void loadModules(boolean isInZygote) throws IOException { + boolean hasLoaded = !modulesLoaded.compareAndSet(false, true); + // dynamic module list mode doesn't apply to loading in zygote + if (hasLoaded && (isInZygote || !ConfigManager.isDynamicModulesMode())) { + return; } // FIXME module list is cleared but never could be reload again when using dynamic-module-list under multi-user environment XposedBridge.clearLoadedPackages(); @@ -99,7 +100,7 @@ public final class XposedInit { BaseService service = SELinuxHelper.getAppDataFileService(); if (!service.checkFileExists(filename)) { Log.e(TAG, "Cannot load any modules because " + filename + " was not found"); - return false; + return; } ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER; @@ -115,7 +116,6 @@ public final class XposedInit { loadModule(apk, topClassLoader); } apks.close(); - return true; } diff --git a/Core/jni/main/java_hook/java_hook.cpp b/Core/jni/main/java_hook/java_hook.cpp index 8cb0a7b0..8841acaa 100644 --- a/Core/jni/main/java_hook/java_hook.cpp +++ b/Core/jni/main/java_hook/java_hook.cpp @@ -20,18 +20,21 @@ jobject gInjectDexClassLoader; static bool isInited = false; -jlong closeFilesBeforeForkNative(JNIEnv *, jclass) { - return reinterpret_cast(FileDescriptorTable::Create()); +static FileDescriptorTable *gClosedFdTable = nullptr; + +void closeFilesBeforeForkNative(JNIEnv *, jclass) { + // FIXME what if gClosedFdTable is not null + gClosedFdTable = FileDescriptorTable::Create(); } -void reopenFilesAfterForkNative(JNIEnv *, jclass, jlong fdTable) { - if (fdTable == 0) { - LOGE("fdTable is null when reopening files"); +void reopenFilesAfterForkNative(JNIEnv *, jclass) { + if (!gClosedFdTable) { + LOGE("gClosedFdTable is null when reopening files"); return; } - auto *closedFdTable = reinterpret_cast(fdTable); - closedFdTable->Reopen(); - delete closedFdTable; + gClosedFdTable->Reopen(); + delete gClosedFdTable; + gClosedFdTable = nullptr; } jlong suspendAllThreads(JNIEnv *, jclass) { @@ -90,10 +93,10 @@ static JNINativeMethod hookMethods[] = { "getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name }, { - "closeFilesBeforeForkNative", "()J", (void *) closeFilesBeforeForkNative + "closeFilesBeforeForkNative", "()V", (void *) closeFilesBeforeForkNative }, { - "reopenFilesAfterForkNative", "(J)V", (void *) reopenFilesAfterForkNative + "reopenFilesAfterForkNative", "()V", (void *) reopenFilesAfterForkNative }, { "deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method