Remove redundant modules loading

This commit is contained in:
solohsu 2019-03-11 02:50:14 +08:00
parent 3097077261
commit bbd2f77c9e
6 changed files with 34 additions and 43 deletions

View File

@ -122,9 +122,9 @@ public class Main implements KeepAll {
// prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote // prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote
// https://github.com/rovo89/Xposed/commit/b3ba245ad04cd485699fb1d2ebde7117e58214ff // 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); public static native void deoptMethodNative(Object object);

View File

@ -2,7 +2,6 @@ package com.elderdrivers.riru.xposed.entry;
import android.text.TextUtils; import android.text.TextUtils;
import com.elderdrivers.riru.xposed.Main;
import com.elderdrivers.riru.xposed.core.HookMain; import com.elderdrivers.riru.xposed.core.HookMain;
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge; import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo; import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
@ -52,25 +51,11 @@ public class Router {
} }
public static void loadModulesSafely(boolean isInZygote) { public static void loadModulesSafely(boolean isInZygote) {
boolean loadedByMe;
try { try {
// FIXME some coredomain app can't reading modules.list // FIXME some coredomain app can't reading modules.list
loadedByMe = XposedInit.loadModules(); XposedInit.loadModules(isInZygote);
} catch (Exception exception) { } catch (Exception exception) {
Utils.logE("error loading module list", 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);
} }
} }

View File

@ -84,21 +84,24 @@ public class BlackWhiteListProxy {
// loadModules once for all child processes of zygote // loadModules once for all child processes of zygote
// TODO maybe just save initZygote callbacks and call them when whitelisted process forked? // TODO maybe just save initZygote callbacks and call them when whitelisted process forked?
Router.loadModulesSafely(true); Router.loadModulesSafely(true);
Main.closeFilesBeforeForkNative();
} }
private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) { private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
Main.appDataDir = appDataDir; Main.appDataDir = appDataDir;
Main.niceName = niceName; Main.niceName = niceName;
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.onEnterChildProcess(); Router.onEnterChildProcess();
if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative();
}
if (!checkNeedHook(appDataDir, niceName)) { if (!checkNeedHook(appDataDir, niceName)) {
// if is blacklisted, just stop here // if is blacklisted, just stop here
return; return;
} }
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(isSystemServer); Router.prepare(isSystemServer);
PrebuiltMethodsDeopter.deoptBootMethods(); PrebuiltMethodsDeopter.deoptBootMethods();
Router.reopenFilesIfNeeded();
Router.installBootstrapHooks(isSystemServer); Router.installBootstrapHooks(isSystemServer);
if (isDynamicModulesMode) { if (isDynamicModulesMode) {
Router.loadModulesSafely(false); Router.loadModulesSafely(false);

View File

@ -22,10 +22,9 @@ public class NormalProxy {
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
// install bootstrap hooks for secondary zygote // install bootstrap hooks for secondary zygote
Router.installBootstrapHooks(false); Router.installBootstrapHooks(false);
if (Main.closedFdTable == 0) { // only load modules for secondary zygote
// only load modules for secondary zygote Router.loadModulesSafely(true);
Router.loadModulesSafely(true); Main.closeFilesBeforeForkNative();
}
} }
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) { public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
@ -33,7 +32,7 @@ public class NormalProxy {
Main.appDataDir = appDataDir; Main.appDataDir = appDataDir;
Main.niceName = niceName; Main.niceName = niceName;
Router.prepare(false); Router.prepare(false);
Router.reopenFilesIfNeeded(); Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess(); Router.onEnterChildProcess();
// load modules for each app process on its forked if dynamic modules mode is on // load modules for each app process on its forked if dynamic modules mode is on
Router.loadModulesSafely(false); Router.loadModulesSafely(false);
@ -54,6 +53,7 @@ public class NormalProxy {
// because if not global hooks installed in initZygote might not be // because if not global hooks installed in initZygote might not be
// propagated to processes not forked via forkAndSpecialize // propagated to processes not forked via forkAndSpecialize
Router.loadModulesSafely(true); Router.loadModulesSafely(true);
Main.closeFilesBeforeForkNative();
} }
public static void forkSystemServerPost(int pid) { public static void forkSystemServerPost(int pid) {
@ -61,7 +61,7 @@ public class NormalProxy {
Main.appDataDir = getDataPathPrefix() + "android"; Main.appDataDir = getDataPathPrefix() + "android";
Main.niceName = "system_server"; Main.niceName = "system_server";
Router.prepare(true); Router.prepare(true);
Router.reopenFilesIfNeeded(); Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess(); Router.onEnterChildProcess();
// reload module list if dynamic mode is on // reload module list if dynamic mode is on
Router.loadModulesSafely(false); Router.loadModulesSafely(false);

View File

@ -88,10 +88,11 @@ public final class XposedInit {
*/ */
private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false); private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
public static boolean loadModules() throws IOException { public static void loadModules(boolean isInZygote) throws IOException {
if (!modulesLoaded.compareAndSet(false, true) boolean hasLoaded = !modulesLoaded.compareAndSet(false, true);
&& !ConfigManager.isDynamicModulesMode()) { // dynamic module list mode doesn't apply to loading in zygote
return false; 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 // FIXME module list is cleared but never could be reload again when using dynamic-module-list under multi-user environment
XposedBridge.clearLoadedPackages(); XposedBridge.clearLoadedPackages();
@ -99,7 +100,7 @@ public final class XposedInit {
BaseService service = SELinuxHelper.getAppDataFileService(); BaseService service = SELinuxHelper.getAppDataFileService();
if (!service.checkFileExists(filename)) { if (!service.checkFileExists(filename)) {
Log.e(TAG, "Cannot load any modules because " + filename + " was not found"); Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
return false; return;
} }
ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER; ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
@ -115,7 +116,6 @@ public final class XposedInit {
loadModule(apk, topClassLoader); loadModule(apk, topClassLoader);
} }
apks.close(); apks.close();
return true;
} }

View File

@ -20,18 +20,21 @@ jobject gInjectDexClassLoader;
static bool isInited = false; static bool isInited = false;
jlong closeFilesBeforeForkNative(JNIEnv *, jclass) { static FileDescriptorTable *gClosedFdTable = nullptr;
return reinterpret_cast<jlong>(FileDescriptorTable::Create());
void closeFilesBeforeForkNative(JNIEnv *, jclass) {
// FIXME what if gClosedFdTable is not null
gClosedFdTable = FileDescriptorTable::Create();
} }
void reopenFilesAfterForkNative(JNIEnv *, jclass, jlong fdTable) { void reopenFilesAfterForkNative(JNIEnv *, jclass) {
if (fdTable == 0) { if (!gClosedFdTable) {
LOGE("fdTable is null when reopening files"); LOGE("gClosedFdTable is null when reopening files");
return; return;
} }
auto *closedFdTable = reinterpret_cast<FileDescriptorTable *>(fdTable); gClosedFdTable->Reopen();
closedFdTable->Reopen(); delete gClosedFdTable;
delete closedFdTable; gClosedFdTable = nullptr;
} }
jlong suspendAllThreads(JNIEnv *, jclass) { jlong suspendAllThreads(JNIEnv *, jclass) {
@ -90,10 +93,10 @@ static JNINativeMethod hookMethods[] = {
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name "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 "deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method