From 6eae86eb0f266817f7b1bf2f9a2a8ff3c95a70e2 Mon Sep 17 00:00:00 2001 From: solohsu Date: Fri, 22 Feb 2019 00:15:43 +0800 Subject: [PATCH] Support EdXposed Manager and Xposed Installer. Priority: EdXposed Installer > EdXposed Manager > Xposed Installer --- .../riru/xposed/config/ConfigManager.java | 14 ++-- .../riru/xposed/config/InstallerChooser.java | 64 +++++++++++++++++++ .../riru/xposed/entry/Router.java | 4 +- .../entry/hooker/HandleBindAppHooker.java | 2 +- .../entry/hooker/XposedBlackListHooker.java | 2 +- .../entry/hooker/XposedInstallerHooker.java | 7 +- .../de/robv/android/xposed/XposedInit.java | 8 +-- 7 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 Bridge/src/main/java/com/elderdrivers/riru/xposed/config/InstallerChooser.java diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/ConfigManager.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/ConfigManager.java index 47701777..a5eb4ce1 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/ConfigManager.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/ConfigManager.java @@ -4,17 +4,17 @@ import java.util.Collections; import java.util.Set; import de.robv.android.xposed.SELinuxHelper; -import de.robv.android.xposed.XposedInit; -import static de.robv.android.xposed.XposedInit.INSTALLER_PACKAGE_NAME; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_DATA_BASE_DIR; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_PACKAGE_NAME; public class ConfigManager { - private static final String BLACK_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/blacklist/"; - private static final String WHITE_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/whitelist/"; - private static final String COMPAT_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/compatlist/"; - private static final String USE_WHITE_LIST = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/usewhitelist"; - private static final String DYNAMIC_MODULES = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/dynamicmodules"; + private static final String BLACK_LIST_PATH = INSTALLER_DATA_BASE_DIR + "conf/blacklist/"; + private static final String WHITE_LIST_PATH = INSTALLER_DATA_BASE_DIR + "conf/whitelist/"; + private static final String COMPAT_LIST_PATH = INSTALLER_DATA_BASE_DIR + "conf/compatlist/"; + private static final String USE_WHITE_LIST = INSTALLER_DATA_BASE_DIR + "conf/usewhitelist"; + private static final String DYNAMIC_MODULES = INSTALLER_DATA_BASE_DIR + "conf/dynamicmodules"; private static final Set WHITE_LIST = Collections.singleton(INSTALLER_PACKAGE_NAME); private static final boolean IS_DYNAMIC_MODULES; diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/InstallerChooser.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/InstallerChooser.java new file mode 100644 index 00000000..20677317 --- /dev/null +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/config/InstallerChooser.java @@ -0,0 +1,64 @@ +package com.elderdrivers.riru.xposed.config; + +import android.annotation.SuppressLint; +import android.os.Build; + +import com.elderdrivers.riru.xposed.util.Utils; + +import java.util.concurrent.atomic.AtomicBoolean; + +import de.robv.android.xposed.SELinuxHelper; +import de.robv.android.xposed.services.BaseService; + +public class InstallerChooser { + + private static final AtomicBoolean hasSet = new AtomicBoolean(false); + private static final String DATA_DIR_PATH_PREFIX = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? "/data/user_de/0/" : "/data/data/"; + + + public static final String PRIMARY_INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager"; + public static final String SECONDARY_INSTALLER_PACKAGE_NAME = "org.meowcat.edxposed.manager"; + public static final String LEGACY_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer"; + + public static String INSTALLER_PACKAGE_NAME = PRIMARY_INSTALLER_PACKAGE_NAME; + @SuppressLint("SdCardPath") + public static String INSTALLER_DATA_BASE_DIR = DATA_DIR_PATH_PREFIX + INSTALLER_PACKAGE_NAME + "/"; + + + public static void setup() { + if (!hasSet.compareAndSet(false, true)) { + // init once + return; + } + String dataBaseDir; + if (checkDataDirValid(dataBaseDir = DATA_DIR_PATH_PREFIX + PRIMARY_INSTALLER_PACKAGE_NAME + "/")) { + INSTALLER_PACKAGE_NAME = PRIMARY_INSTALLER_PACKAGE_NAME; + INSTALLER_DATA_BASE_DIR = dataBaseDir; + Utils.logI("using " + PRIMARY_INSTALLER_PACKAGE_NAME + "as installer app"); + return; + } + if (checkDataDirValid(dataBaseDir = DATA_DIR_PATH_PREFIX + SECONDARY_INSTALLER_PACKAGE_NAME + "/")) { + INSTALLER_PACKAGE_NAME = SECONDARY_INSTALLER_PACKAGE_NAME; + INSTALLER_DATA_BASE_DIR = dataBaseDir; + Utils.logI("using " + SECONDARY_INSTALLER_PACKAGE_NAME + "as installer app"); + return; + } + if (checkDataDirValid(dataBaseDir = DATA_DIR_PATH_PREFIX + LEGACY_INSTALLER_PACKAGE_NAME + "/")) { + INSTALLER_PACKAGE_NAME = LEGACY_INSTALLER_PACKAGE_NAME; + INSTALLER_DATA_BASE_DIR = dataBaseDir; + Utils.logI("using " + LEGACY_INSTALLER_PACKAGE_NAME + "as installer app"); + return; + } + Utils.logE("no supported installer app found"); + } + + /** + * For some reason checkFileExists(dirPath) is not reliable when forkSystemServerPre + */ + private static boolean checkDataDirValid(String dirPath) { + BaseService fileService = SELinuxHelper.getAppDataFileService(); + return fileService.checkFileExists(dirPath + "code_cache") + || fileService.checkFileExists(dirPath + "cache"); + } +} 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 2b1e1a26..e10f688c 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,8 +2,7 @@ package com.elderdrivers.riru.xposed.entry; import android.text.TextUtils; -import com.elderdrivers.riru.xposed.Main; -import com.elderdrivers.riru.xposed.config.ConfigManager; +import com.elderdrivers.riru.xposed.config.InstallerChooser; import com.elderdrivers.riru.xposed.core.HookMain; import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo; import com.elderdrivers.riru.xposed.entry.bootstrap.SysBootstrapHookInfo; @@ -21,6 +20,7 @@ public class Router { public static void prepare(boolean isSystem) { // this flag is needed when loadModules XposedInit.startsSystemServer = isSystem; + InstallerChooser.setup(); } public static void checkHookState(String appDataDir) { diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/HandleBindAppHooker.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/HandleBindAppHooker.java index 17154010..0f7aa822 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/HandleBindAppHooker.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/HandleBindAppHooker.java @@ -13,11 +13,11 @@ import com.elderdrivers.riru.xposed.util.Utils; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.callbacks.XC_LoadPackage; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_PACKAGE_NAME; import static com.elderdrivers.riru.xposed.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; import static com.elderdrivers.riru.xposed.util.ClassLoaderUtils.replaceParentClassLoader; import static de.robv.android.xposed.XposedHelpers.getObjectField; import static de.robv.android.xposed.XposedHelpers.setObjectField; -import static de.robv.android.xposed.XposedInit.INSTALLER_PACKAGE_NAME; import static de.robv.android.xposed.XposedInit.loadedPackagesInProcess; import static de.robv.android.xposed.XposedInit.logD; import static de.robv.android.xposed.XposedInit.logE; diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedBlackListHooker.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedBlackListHooker.java index 083a4a92..18c2be59 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedBlackListHooker.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedBlackListHooker.java @@ -18,9 +18,9 @@ import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XSharedPreferences; import de.robv.android.xposed.XposedBridge; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_PACKAGE_NAME; import static com.elderdrivers.riru.xposed.util.FileUtils.IS_USING_PROTECTED_STORAGE; import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; -import static de.robv.android.xposed.XposedInit.INSTALLER_PACKAGE_NAME; public class XposedBlackListHooker { diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedInstallerHooker.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedInstallerHooker.java index fb66bca4..9eeb6bcc 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedInstallerHooker.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/entry/hooker/XposedInstallerHooker.java @@ -10,20 +10,19 @@ import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedBridge; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.LEGACY_INSTALLER_PACKAGE_NAME; import static de.robv.android.xposed.XposedHelpers.callStaticMethod; import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; import static de.robv.android.xposed.XposedHelpers.findClass; import static de.robv.android.xposed.XposedHelpers.getObjectField; import static de.robv.android.xposed.XposedHelpers.setObjectField; -import static de.robv.android.xposed.XposedInit.INSTALLER_LEGACY_PACKAGE_NAME; -import static de.robv.android.xposed.XposedInit.INSTALLER_PACKAGE_NAME; public class XposedInstallerHooker { public static void hookXposedInstaller(ClassLoader classLoader) { try { - final String xposedAppClass = INSTALLER_LEGACY_PACKAGE_NAME + ".XposedApp"; - final Class InstallZipUtil = findClass(INSTALLER_LEGACY_PACKAGE_NAME + final String xposedAppClass = LEGACY_INSTALLER_PACKAGE_NAME + ".XposedApp"; + final Class InstallZipUtil = findClass(LEGACY_INSTALLER_PACKAGE_NAME + ".util.InstallZipUtil", classLoader); findAndHookMethod(xposedAppClass, classLoader, "getActiveXposedVersion", XC_MethodReplacement.returnConstant(XposedBridge.getXposedVersion())); 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 6f3b5200..a52f9ca0 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java @@ -26,6 +26,8 @@ import dalvik.system.DexFile; import dalvik.system.PathClassLoader; import de.robv.android.xposed.services.BaseService; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_DATA_BASE_DIR; +import static com.elderdrivers.riru.xposed.config.InstallerChooser.INSTALLER_PACKAGE_NAME; import static com.elderdrivers.riru.xposed.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; import static de.robv.android.xposed.XposedHelpers.closeSilently; import static de.robv.android.xposed.XposedHelpers.findClass; @@ -38,12 +40,6 @@ public final class XposedInit { 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"; - public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer"; - @SuppressLint("SdCardPath") - public static final String INSTALLER_DATA_BASE_DIR = Build.VERSION.SDK_INT >= 24 - ? "/data/user_de/0/" + INSTALLER_PACKAGE_NAME + "/" - : "/data/data/" + INSTALLER_PACKAGE_NAME + "/"; private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication"; // TODO not supported yet private static boolean disableResources = true;