diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/dexmaker/DexMakerUtils.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/dexmaker/DexMakerUtils.java index a5f23288..472c8347 100644 --- a/Bridge/src/main/java/com/elderdrivers/riru/xposed/dexmaker/DexMakerUtils.java +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/dexmaker/DexMakerUtils.java @@ -14,12 +14,10 @@ import external.com.android.dx.Code; import external.com.android.dx.Local; import external.com.android.dx.TypeId; -import static de.robv.android.xposed.XposedInit.INSTALLER_DATA_BASE_DIR; - public class DexMakerUtils { private static final boolean IN_MEMORY_DEX_ELIGIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - private static final String COMPAT_LIST_PATH = INSTALLER_DATA_BASE_DIR + "conf/compatlist/"; + private static final String COMPAT_LIST_PATH = "/data/misc/riru/modules/edxposed/compatlist/"; public static boolean shouldUseInMemoryHook() { if (!IN_MEMORY_DEX_ELIGIBLE) { 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 06675fbd..32d8de19 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 @@ -2,19 +2,65 @@ package com.elderdrivers.riru.xposed.entry.hooker; import com.elderdrivers.riru.xposed.util.Utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedBridge; +import static de.robv.android.xposed.XposedHelpers.callStaticMethod; import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; -import static de.robv.android.xposed.XposedInit.INSTALLER_LEGACY_PACKAGE_NAME; +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_PACKAGE_NAME; public class XposedInstallerHooker { public static void hookXposedInstaller(ClassLoader classLoader) { try { - final String xposedAppClass = INSTALLER_LEGACY_PACKAGE_NAME + ".XposedApp"; + final String xposedAppClass = INSTALLER_PACKAGE_NAME + ".XposedApp"; + final Class InstallZipUtil = findClass(INSTALLER_PACKAGE_NAME + + ".util.InstallZipUtil", classLoader); findAndHookMethod(xposedAppClass, classLoader, "getActiveXposedVersion", XC_MethodReplacement.returnConstant(XposedBridge.getXposedVersion())); + findAndHookMethod(xposedAppClass, classLoader, + "reloadXposedProp", new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + Utils.logD("before reloadXposedProp..."); + final String propFieldName = "mXposedProp"; + final Object thisObject = param.thisObject; + if (getObjectField(thisObject, propFieldName) != null) { + param.setResult(null); + Utils.logD("reloadXposedProp already done, skip..."); + return; + } + File file = new File("/system/framework/edconfig.dex"); + FileInputStream is = null; + try { + is = new FileInputStream(file); + Object props = callStaticMethod(InstallZipUtil, + "parseXposedProp", is); + synchronized (thisObject) { + setObjectField(thisObject, propFieldName, props); + } + Utils.logD("reloadXposedProp done..."); + param.setResult(null); + } catch (IOException e) { + Utils.logE("Could not read " + file.getPath(), e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ignored) { + } + } + } + } + }); } catch (Throwable t) { Utils.logE("Could not hook Xposed Installer", t); } 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 fade0346..04c0036a 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java @@ -37,10 +37,9 @@ public final class XposedInit { private static boolean startsSystemServer = false; private static final String startClassName = ""; // ed: no support for tool process anymore - public static final String INSTALLER_PACKAGE_NAME = "org.meowcat.edxposed.manager"; - public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer"; + public static final String INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer"; @SuppressLint("SdCardPath") - public static final String INSTALLER_DATA_BASE_DIR = Build.VERSION.SDK_INT >= 24 + private static final String 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"; @@ -89,7 +88,7 @@ public final class XposedInit { } /** - * Try to load all modules defined in INSTALLER_DATA_BASE_DIR/conf/modules.list + * Try to load all modules defined in BASE_DIR/conf/modules.list */ private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false); @@ -97,7 +96,7 @@ public final class XposedInit { if (!modulesLoaded.compareAndSet(false, true)) { return; } - final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list"; + final String filename = BASE_DIR + "conf/modules.list"; BaseService service = SELinuxHelper.getAppDataFileService(); if (!service.checkFileExists(filename)) { Log.e(TAG, "Cannot load any modules because " + filename + " was not found"); diff --git a/Core/jni/main/inject/config_manager.cpp b/Core/jni/main/inject/config_manager.cpp index 28b70e3a..ded568e0 100644 --- a/Core/jni/main/inject/config_manager.cpp +++ b/Core/jni/main/inject/config_manager.cpp @@ -11,51 +11,23 @@ #include #include #include -#include #include "config_manager.h" -#define INSTALLER_PACKAGE_NAME "org.meowcat.edxposed.manager" +#define BLACK_LIST_PATH "/data/misc/riru/modules/edxposed/blacklist/" +#define WHITE_LIST_PATH "/data/misc/riru/modules/edxposed/whitelist/" +#define USE_WHITE_LIST "/data/misc/riru/modules/edxposed/usewhitelist" +#define GLOBAL_MODE "/data/misc/riru/modules/edxposed/forceglobal" +#define DYNAMIC_MODULES "/data/misc/riru/modules/edxposed/dynamicmodules" static char package_name[256]; static bool global_mode = false; static bool dynamic_modules = false; static bool inited = false; -static char sdk[PROP_VALUE_MAX + 1]; -static bool use_protected_storage = - __system_property_get("ro.build.version.sdk", sdk) > 0 && atoi(sdk) >= 24; -static const char *data_dir = use_protected_storage ? - "/data/user_de/0/" INSTALLER_PACKAGE_NAME "/" : - "/data/user/0/" INSTALLER_PACKAGE_NAME "/"; -const char *get_black_list_path() { - char *result = new char[256]; - return strcat(strcpy(result, data_dir), "conf/blacklist/"); -} - -const char *get_white_list_path() { - char *result = new char[256]; - return strcat(strcpy(result, data_dir), "conf/whitelist/"); -} - -const char *get_use_white_list_file() { - char *result = new char[256]; - return strcat(strcpy(result, data_dir), "conf/usewhitelist"); -} - -const char *get_force_global_file() { - char *result = new char[256]; - return strcat(strcpy(result, data_dir), "conf/forceglobal"); -} - -const char *get_dynamic_modules_file() { - char *result = new char[256]; - return strcat(strcpy(result, data_dir), "conf/dynamicmodules"); -} - -void init_once() { +void initOnce() { if (!inited) { - global_mode = access(get_force_global_file(), F_OK) == 0; - dynamic_modules = access(get_dynamic_modules_file(), F_OK) == 0; + global_mode = access(GLOBAL_MODE, F_OK) == 0; + dynamic_modules = access(DYNAMIC_MODULES, F_OK) == 0; inited = true; } } @@ -79,21 +51,18 @@ int is_app_need_hook(JNIEnv *env, jstring appDataDir) { } } env->ReleaseStringUTFChars(appDataDir, app_data_dir); - const char *white_list_path = get_white_list_path(); - const char *black_list_path = get_black_list_path(); - bool use_white_list = access(get_use_white_list_file(), F_OK) == 0; - bool white_list_exists = access(white_list_path, F_OK) == 0; - bool black_list_exists = access(black_list_path, F_OK) == 0; + bool use_white_list = access(USE_WHITE_LIST, F_OK) == 0; + bool white_list_exists = access(WHITE_LIST_PATH, F_OK) == 0; + bool black_list_exists = access(BLACK_LIST_PATH, F_OK) == 0; if (use_white_list && white_list_exists) { char path[PATH_MAX]; - LOGE("package_name: %s", package_name); - snprintf(path, PATH_MAX, "%s%s", white_list_path, package_name); + snprintf(path, PATH_MAX, WHITE_LIST_PATH "%s", package_name); int res = access(path, F_OK) == 0; LOGD("use whitelist, res=%d", res); return res; } else if (!use_white_list && black_list_exists) { char path[PATH_MAX]; - snprintf(path, PATH_MAX, "%s%s", black_list_path, package_name); + snprintf(path, PATH_MAX, BLACK_LIST_PATH "%s", package_name); int res = access(path, F_OK) != 0; LOGD("use blacklist, res=%d", res); return res; @@ -104,11 +73,11 @@ int is_app_need_hook(JNIEnv *env, jstring appDataDir) { } bool is_global_mode() { - init_once(); + initOnce(); return global_mode; } bool is_dynamic_modules() { - init_once(); + initOnce(); return dynamic_modules; }