diff --git a/.gitattributes b/.gitattributes index 30bc3e75..00a421d2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,6 +6,8 @@ META-INF/** text eol=lf *.prop text eol=lf *.sh text eol=lf *.md text eol=lf +update-binary text eol=lf +update-script text eol=lf # Denote all files that are truly binary and should not be modified. *.so binary 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 472c8347..a5f23288 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,10 +14,12 @@ 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 = "/data/misc/riru/modules/edxposed/compatlist/"; + private static final String COMPAT_LIST_PATH = INSTALLER_DATA_BASE_DIR + "conf/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 32d8de19..06675fbd 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,65 +2,19 @@ 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.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; +import static de.robv.android.xposed.XposedInit.INSTALLER_LEGACY_PACKAGE_NAME; public class XposedInstallerHooker { public static void hookXposedInstaller(ClassLoader classLoader) { try { - final String xposedAppClass = INSTALLER_PACKAGE_NAME + ".XposedApp"; - final Class InstallZipUtil = findClass(INSTALLER_PACKAGE_NAME - + ".util.InstallZipUtil", classLoader); + final String xposedAppClass = INSTALLER_LEGACY_PACKAGE_NAME + ".XposedApp"; 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 04c0036a..fade0346 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedInit.java @@ -37,9 +37,10 @@ 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 = "de.robv.android.xposed.installer"; + public static final String INSTALLER_PACKAGE_NAME = "org.meowcat.edxposed.manager"; + public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer"; @SuppressLint("SdCardPath") - private static final String BASE_DIR = Build.VERSION.SDK_INT >= 24 + 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"; @@ -88,7 +89,7 @@ public final class XposedInit { } /** - * Try to load all modules defined in BASE_DIR/conf/modules.list + * Try to load all modules defined in INSTALLER_DATA_BASE_DIR/conf/modules.list */ private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false); @@ -96,7 +97,7 @@ public final class XposedInit { if (!modulesLoaded.compareAndSet(false, true)) { return; } - final String filename = BASE_DIR + "conf/modules.list"; + final String filename = INSTALLER_DATA_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 ded568e0..28b70e3a 100644 --- a/Core/jni/main/inject/config_manager.cpp +++ b/Core/jni/main/inject/config_manager.cpp @@ -11,23 +11,51 @@ #include #include #include +#include #include "config_manager.h" -#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" +#define INSTALLER_PACKAGE_NAME "org.meowcat.edxposed.manager" 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 "/"; -void initOnce() { +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() { if (!inited) { - global_mode = access(GLOBAL_MODE, F_OK) == 0; - dynamic_modules = access(DYNAMIC_MODULES, F_OK) == 0; + global_mode = access(get_force_global_file(), F_OK) == 0; + dynamic_modules = access(get_dynamic_modules_file(), F_OK) == 0; inited = true; } } @@ -51,18 +79,21 @@ int is_app_need_hook(JNIEnv *env, jstring appDataDir) { } } env->ReleaseStringUTFChars(appDataDir, app_data_dir); - 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; + 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; if (use_white_list && white_list_exists) { char path[PATH_MAX]; - snprintf(path, PATH_MAX, WHITE_LIST_PATH "%s", package_name); + LOGE("package_name: %s", package_name); + snprintf(path, PATH_MAX, "%s%s", white_list_path, 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, BLACK_LIST_PATH "%s", package_name); + snprintf(path, PATH_MAX, "%s%s", black_list_path, package_name); int res = access(path, F_OK) != 0; LOGD("use blacklist, res=%d", res); return res; @@ -73,11 +104,11 @@ int is_app_need_hook(JNIEnv *env, jstring appDataDir) { } bool is_global_mode() { - initOnce(); + init_once(); return global_mode; } bool is_dynamic_modules() { - initOnce(); + init_once(); return dynamic_modules; }