diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java index 727fd68b6..01ed9f7bd 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java @@ -5,8 +5,8 @@ public class BaseEdxpConfig implements EdxpConfig { @Override - public String getInstallerConfigPath(String suffix) { - return ConfigManager.getInstallerConfigPath(suffix != null ? suffix : ""); + public String getConfigPath(String suffix) { + return ConfigManager.getConfigPath(suffix != null ? suffix : ""); } @Override diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java index 14e90402a..1599784c5 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java @@ -18,7 +18,7 @@ public static boolean shouldUseCompatMode(String packageName) { && (result = compatModeCache.get(packageName)) != null) { return result; } - result = isFileExists(getInstallerConfigPath("compatlist/" + packageName)); + result = isFileExists(getConfigPath("compatlist/" + packageName)); compatModeCache.put(packageName, result); return result; } @@ -41,7 +41,9 @@ private static boolean isFileExists(String path) { public static native String getLibSandHookName(); - public static native String getInstallerConfigPath(String suffix); + public static native String getConfigPath(String suffix); + + public static native String getBaseConfigPath(); public static native String getDataPathPrefix(); diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/hooker/XposedInstallerHooker.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/hooker/XposedInstallerHooker.java index 07953b168..619865de6 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/hooker/XposedInstallerHooker.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/hooker/XposedInstallerHooker.java @@ -1,5 +1,8 @@ package com.elderdrivers.riru.edxp.hooker; +import android.app.AndroidAppHelper; +import android.view.View; + import com.elderdrivers.riru.edxp.config.ConfigManager; import com.elderdrivers.riru.edxp.util.Utils; @@ -16,7 +19,7 @@ public class XposedInstallerHooker { private static final String LEGACY_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer"; - public static void hookXposedInstaller(ClassLoader classLoader) { + public static void hookXposedInstaller(final ClassLoader classLoader) { try { final String xposedAppClass = LEGACY_INSTALLER_PACKAGE_NAME + ".XposedApp"; final Class InstallZipUtil = XposedHelpers.findClass(LEGACY_INSTALLER_PACKAGE_NAME @@ -66,6 +69,31 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable { } } }); + XposedHelpers.findAndHookMethod("org.meowcat.edxposed.manager.XposedApp", classLoader, "onCreate", new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) throws Throwable { + XposedHelpers.setStaticObjectField(param.thisObject.getClass(), "BASE_DIR", ConfigManager.getBaseConfigPath() + "/"); + XposedHelpers.setStaticObjectField(param.thisObject.getClass(), "ENABLED_MODULES_LIST_FILE", ConfigManager.getConfigPath("enabled_modules.list")); + } + }); + XposedHelpers.findAndHookMethod("org.meowcat.edxposed.manager.util.ModuleUtil", classLoader, "updateModulesList", boolean.class, View.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + final Object thisObject = param.thisObject; + synchronized (thisObject) { + XposedHelpers.setStaticObjectField(param.thisObject.getClass(), "MODULES_LIST_FILE", ConfigManager.getConfigPath("modules.list")); + } + } + }); + XposedHelpers.findAndHookMethod("org.meowcat.edxposed.manager.StatusInstallerFragment", classLoader, "getCanonicalFile", File.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + File arg = (File)param.args[0]; + if(arg.equals(new File(AndroidAppHelper.currentApplicationInfo().deviceProtectedDataDir))) { + param.args[0] = new File(ConfigManager.getBaseConfigPath()); + } + } + }); } catch (Throwable t) { Utils.logE("Could not hook Xposed Installer", t); } diff --git a/edxp-core/src/main/cpp/main/include/utils.h b/edxp-core/src/main/cpp/main/include/utils.h index 06c5e5cc4..299b26d84 100644 --- a/edxp-core/src/main/cpp/main/include/utils.h +++ b/edxp-core/src/main/cpp/main/include/utils.h @@ -6,8 +6,9 @@ #include #include #include +#include +#include #include "logging.h" -#include namespace edxp { @@ -31,9 +32,24 @@ namespace edxp { } } - static inline int32_t GetAndroidApiLevel() { - char prop_value[PROP_VALUE_MAX]; - __system_property_get("ro.build.version.sdk", prop_value); - return std::atoi(prop_value); + inline void path_chown(const std::filesystem::path &path, uid_t uid, gid_t gid, bool recursively=false) { + if (chown(path.c_str(), uid, gid) != 0) { + throw std::filesystem::filesystem_error(strerror(errno), path, + {errno, std::system_category()}); + } + if(recursively) { + for(const auto &item : std::filesystem::recursive_directory_iterator(path)) { + if (chown(item.path().c_str(), uid, gid) != 0) { + throw std::filesystem::filesystem_error(strerror(errno), item.path(), + {errno, std::system_category()}); + } + } + } + } + + inline std::tuple path_own(const std::filesystem::path& path) { + struct stat sb; + stat(path.c_str(), &sb); + return {sb.st_uid, sb.st_gid}; } } diff --git a/edxp-core/src/main/cpp/main/src/config_manager.cpp b/edxp-core/src/main/cpp/main/src/config_manager.cpp index c40419442..aff556ff5 100644 --- a/edxp-core/src/main/cpp/main/src/config_manager.cpp +++ b/edxp-core/src/main/cpp/main/src/config_manager.cpp @@ -20,23 +20,96 @@ #include "config_manager.h" #include "utils.h" +/* + * Logic: + * check if /data/adb/edxp exists and is readable, if so, read misc_path and the config base path is + * /data/misc/$misc_path; if not so, fall back to the installer's path + * config manager is const. and it should be updated if the module list is updated + * each user owns one config manager + * before the process started, update current user + * module list and modules scopes are preloaded + * can get app module list by call a const function + * for installer's pkg name, it's retrieved by /data/misc/$misc_path/$uid/conf/installer. + * if not exists, fallback + * blacklist and whitelist are instead set by blacklist.conf and whitelist.conf respectively + * dynamic mode is always on + * + * Permission: + * /data/adb/edxp should be accessible by zygote by sepolicy + * /data/misc/$misc_path is random path, and mounted by magisk + * it should have context `u:object_r:shell_data_file:s0`, which should be readable by normal app + * and zygote + * + * /data/misc/$misc_path's owner should be root:root, with permission 771 + * so does /data/misc/$misc_path/$uid + * /data/misc/$misc_path/$uid/conf should be um:root, with permission 770 + * where um is the user of manager + * /data/misc/$misc_path/$uid/prefs should be root:root, with permission 771 + * /data/misc/$misc_path/$uid/prefs/$pkg should be up:root, with permission 771 + * this path is used for XSharePreference, where up is the user of package $pkg + * other's permission is 5 because it should be read by all the other apps but not writable + * it's only writeable by $pkg itself + * root group's 7 permission's for updating the permission & deleting it + * + * Initialization: + * This is only done for config path in /data/misc + * check if /data/misc/$misc_path/$uid exists. if not create one with 771 + * check if /data/misc/$misc_path/$uid/conf exists. if not create one with 770 + * check if /data/misc/$misc_path/$uid/prefs exists. if not create one with 771 + * + * + * when the launching app is installer, change the user owner of /data/misc/$misc_path/$uid/conf + * to be the installer, and change the permission to be 770 + * + * when the launching app is in the module lists, ensure existence of + * /data/misc/$misc_path/$uid/prefs/$pkg + * with the owner the user of the pkg and permission 774 + * if this paths exists but with different owner, delete it recursively and create a new one + * this is when package reinstalled + * but I heard that some devices change uid when upgrading system, so I didn't do this + * + * Side effect: + * data exists if the module uninstalled + * One way to release the storage space is to uninstall edxp + * because /data/misc/$misc_path is mounted by magisk. + * + * edxp works without manager + * + * uninstall removes all configs (this can be restored if manager store another copy + * of the conf on its own data dir) + * + */ namespace edxp { namespace fs = std::filesystem; + fs::path ConfigManager::RetrieveBaseConfigPath() const { + fs::path misc_path("/data/adb/edxp/misc_path"); + if (path_exists(misc_path)) { + std::ifstream ifs(misc_path); + if (ifs.good()) { + return fs::path("/data/misc") / + std::string{std::istream_iterator(ifs), + std::istream_iterator()} / + std::to_string(user_); + } + } + LOGW("fallback because %s is not accessible", misc_path.c_str()); + return data_path_prefix_ / kPrimaryInstallerPkgName; + } + std::string ConfigManager::RetrieveInstallerPkgName() const { - std::string data_test_path = data_path_prefix_ / kPrimaryInstallerPkgName; - if (path_exists(data_test_path, true)) { - LOGI("using installer %s", kPrimaryInstallerPkgName.c_str()); + std::string installer_pkg_name_path = GetConfigPath("installer"); + if (!path_exists(installer_pkg_name_path, true)) { + LOGW("installer not set, using default one %s", kPrimaryInstallerPkgName.c_str()); return kPrimaryInstallerPkgName; } - data_test_path = data_path_prefix_ / kLegacyInstallerPkgName; - if (path_exists(data_test_path, true)) { - LOGI("using installer %s", kLegacyInstallerPkgName.c_str()); - return kLegacyInstallerPkgName; + std::ifstream ifs(installer_pkg_name_path); + if (!ifs.good()) { + LOGW("cannot access %s, using default one %s", installer_pkg_name_path.c_str(), + kPrimaryInstallerPkgName.c_str()); + return kPrimaryInstallerPkgName; } - LOGE("no supported installer app found, using default: %s", - kPrimaryInstallerPkgName.c_str()); - return kPrimaryInstallerPkgName; + return {std::istream_iterator(ifs), std::istream_iterator()}; } std::unordered_set ConfigManager::GetAppList(const fs::path &dir) { @@ -63,21 +136,17 @@ namespace edxp { // TODO ignore unrelated processes bool ConfigManager::IsAppNeedHook(const std::string &package_name) const { - if (!black_list_enable_ && !white_list_enable_) { - return true; - } - if (package_name == installer_pkg_name_) { return true; } if (white_list_enable_) { auto res = white_list_.count(package_name); - LOGD("using whitelist, %s -> %d", package_name.c_str(), res); + LOGD("using whitelist, %s -> %s", package_name.c_str(), BoolToString(res)); return res; } else { auto res = black_list_.count(package_name); - LOGD("using blacklist, %s -> %d", package_name.c_str(), res); + LOGD("using blacklist, %s -> %s", package_name.c_str(), BoolToString(res)); return res; } } @@ -86,27 +155,46 @@ namespace edxp { user_(user), data_path_prefix_(fs::path(use_prot_storage_ ? "/data/user_de" : "/data/user") / std::to_string(user_)), + base_config_path_(RetrieveBaseConfigPath()), + initialized_(InitConfigPath()), installer_pkg_name_(RetrieveInstallerPkgName()), - black_list_enable_(path_exists(GetConfigPath("blacklist"))), - white_list_enable_(path_exists(GetConfigPath("whiltelist"))), + white_list_enable_(path_exists(GetConfigPath("usewhitelist"))), deopt_boot_image_enabled_(path_exists(GetConfigPath("deoptbootimage"))), no_module_log_enabled_(path_exists(GetConfigPath("disable_modules_log"))), resources_hook_enabled_(path_exists(GetConfigPath("enable_resources"))), - hidden_api_bypass_enabled_(!path_exists(GetConfigPath("disable_hidden_api_bypass"))), - white_list_(white_list_enable_ ? GetAppList(GetConfigPath("whitelist/")) - : std::unordered_set{}), - black_list_(black_list_enable_ ? GetAppList(GetConfigPath("blacklist/")) - : std::unordered_set{}), + white_list_(GetAppList(GetConfigPath("whitelist/"))), + black_list_(GetAppList(GetConfigPath("blacklist/"))), modules_list_(GetModuleList()), - last_write_time_(GetLastWriteTime()){ + last_write_time_(GetLastWriteTime()) { // use_white_list snapshot - LOGI("data path prefix: %s", data_path_prefix_.c_str()); - LOGI(" using blacklist: %s", BoolToString(black_list_enable_)); + LOGI("base config path: %s", base_config_path_.c_str()); + LOGI(" using installer package name: %s", installer_pkg_name_.c_str()); LOGI(" using whitelist: %s", BoolToString(white_list_enable_)); - LOGI(" resources hook: %s", BoolToString(resources_hook_enabled_)); LOGI(" deopt boot image: %s", BoolToString(deopt_boot_image_enabled_)); LOGI(" no module log: %s", BoolToString(no_module_log_enabled_)); - LOGI(" hidden api bypass: %s", BoolToString(hidden_api_bypass_enabled_)); + LOGI(" resources hook: %s", BoolToString(resources_hook_enabled_)); + LOGI(" white list: \n %s", ([this]() { + std::ostringstream join; + std::copy(white_list_.begin(), white_list_.end(), + std::ostream_iterator(join, "\n")); + return join.str(); + })().c_str()); + LOGI(" black list: \n %s", ([this]() { + std::ostringstream join; + std::copy(black_list_.begin(), black_list_.end(), + std::ostream_iterator(join, "\n")); + return join.str(); + })().c_str()); + LOGI(" module list: \n %s", ([this]() { + std::ostringstream join; + std::vector module_list; + std::transform(modules_list_.begin(), modules_list_.end(), + std::back_inserter(module_list), + [](auto i) { return i.first; }); + std::copy(module_list.begin(), module_list.end(), + std::ostream_iterator(join, "\n")); + return join.str(); + })().c_str()); } auto ConfigManager::GetModuleList() -> std::remove_const_t { @@ -124,7 +212,8 @@ namespace edxp { std::string module; while (std::getline(ifs, module)) { const auto &module_pkg_name = GetPackageNameFromBaseApkPath(module); - modules_list.emplace_back(std::move(module), std::unordered_set{}); + auto &[module_path, scope] = modules_list[module_pkg_name]; + module_path.assign(std::move(module)); const auto &module_scope_conf = GetConfigPath(module_pkg_name + ".conf"); if (!path_exists(module_scope_conf, true)) { LOGD("module scope is not set for %s", module_pkg_name.c_str()); @@ -135,17 +224,16 @@ namespace edxp { LOGE("Cannot access path %s", module_scope_conf.c_str()); continue; } - auto &scope = modules_list.back().second; std::string app_pkg_name; while (std::getline(ifs_c, app_pkg_name)) { if (!app_pkg_name.empty()) scope.emplace(std::move(app_pkg_name)); } scope.insert(module_pkg_name); // Always add module itself - LOGD("scope of %s is:\n%s", module_pkg_name.c_str(), ([&scope]() { + LOGD("scope of %s is:\n%s", module_pkg_name.c_str(), ([&scope = scope]() { std::ostringstream join; std::copy(scope.begin(), scope.end(), - std::ostream_iterator(join, "\n")); + std::ostream_iterator(join, "\n ")); return join.str(); })().c_str()); } @@ -155,16 +243,81 @@ namespace edxp { std::vector ConfigManager::GetAppModuleList(const std::string &pkg_name) const { std::vector app_modules_list; for (const auto&[module, scope]: modules_list_) { - if (scope.empty() || scope.count(pkg_name)) app_modules_list.push_back(module); + if (scope.second.empty() || scope.second.count(pkg_name)) + app_modules_list.push_back(scope.first); } return app_modules_list; } std::filesystem::file_time_type ConfigManager::GetLastWriteTime() const { - auto dynamic_path = GetConfigPath("dynamic"); - if (!path_exists(dynamic_path, true)) + auto modules_list = GetConfigPath("modules.list"); + if (!path_exists(modules_list, true)) return {}; - return fs::last_write_time(dynamic_path); + return fs::last_write_time(modules_list); + } + + bool ConfigManager::InitConfigPath() const { + if (base_config_path_.string().rfind("/data/misc") != 0) return true; + try { + fs::create_directories(base_config_path_); + fs::permissions(base_config_path_.parent_path(), + fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec); + fs::permissions(base_config_path_, + fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec); + fs::create_directories(GetLogPath()); + fs::permissions(GetLogPath(), + fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec); + fs::create_directories(GetConfigPath()); + fs::permissions(GetConfigPath(), fs::perms::owner_all | fs::perms::group_all); + fs::create_directories(GetPrefsPath("")); + fs::permissions(GetPrefsPath(""), + fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec); + } catch (const fs::filesystem_error &e) { + LOGE("init: %s", e.what()); + return false; + } + return true; + } + + void ConfigManager::EnsurePermission(const std::string &pkg_name, uid_t uid) const { + if (!initialized_) return; + try { + if (modules_list_.count(pkg_name)) { + auto prefs_path = GetPrefsPath(pkg_name); + if (!path_exists(prefs_path, true)) { + fs::create_directories(prefs_path); + } else { + const auto &[r_uid, r_gid] = path_own(prefs_path); + if (r_uid != uid) { + fs::remove_all(prefs_path); + fs::create_directories(prefs_path); + } + } + fs::permissions(prefs_path, fs::perms::owner_all | fs::perms::group_all | + fs::perms::others_exec); + path_chown(prefs_path, uid, 0); + } + if (pkg_name == installer_pkg_name_) { + auto conf_path = GetConfigPath(); + if (!path_exists(conf_path, true)) { + fs::create_directories(conf_path); + } + auto log_path = GetLogPath(); + if (!path_exists(log_path, true)) { + fs::create_directories(log_path); + } + fs::permissions(conf_path, fs::perms::owner_all | fs::perms::group_all); + fs::permissions(log_path, fs::perms::owner_all | fs::perms::group_all); + if (const auto &[r_uid, r_gid] = path_own(conf_path); r_uid != uid) { + path_chown(conf_path, uid, 0, true); + } + if (const auto &[r_uid, r_gid] = path_own(log_path); r_uid != uid) { + path_chown(log_path, uid, 0, true); + } + } + } catch (const fs::filesystem_error &e) { + LOGE("%s", e.what()); + } } } \ No newline at end of file diff --git a/edxp-core/src/main/cpp/main/src/config_manager.h b/edxp-core/src/main/cpp/main/src/config_manager.h index bc8d81f33..7a31ffacb 100644 --- a/edxp-core/src/main/cpp/main/src/config_manager.h +++ b/edxp-core/src/main/cpp/main/src/config_manager.h @@ -15,7 +15,6 @@ namespace edxp { static const std::string kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager"; - static const std::string kLegacyInstallerPkgName = "de.robv.android.xposed.installer"; static const std::string kXposedPropPath = "/system/framework/edconfig.jar"; class ConfigManager { @@ -26,7 +25,7 @@ namespace edxp { inline static void SetCurrentUser(uid_t user) { if (auto instance = instances_.find(user); - !instance->second || instance->second->NeedUpdateConfig()) { + instance == instances_.end() || !instance->second || instance->second->NeedUpdateConfig()) { instances_[user] = std::make_unique(user); } } @@ -35,9 +34,8 @@ namespace edxp { return std::move(instances_); } - inline auto IsBlackWhiteListEnabled() const { - return black_list_enable_ || white_list_enable_; - } + // Always true now + inline auto IsBlackWhiteListEnabled() const { return true; } inline auto IsResourcesHookEnabled() const { return resources_hook_enabled_; } @@ -45,8 +43,6 @@ namespace edxp { inline auto IsNoModuleLogEnabled() const { return no_module_log_enabled_; } - inline auto IsHiddenAPIBypassEnabled() const { return hidden_api_bypass_enabled_; } - inline auto GetInstallerPackageName() const { return installer_pkg_name_; } inline auto GetXposedPropPath() const { return kXposedPropPath; } @@ -55,8 +51,18 @@ namespace edxp { inline auto GetDataPathPrefix() const { return data_path_prefix_; } - inline auto GetConfigPath(const std::string &suffix) const { - return data_path_prefix_ / installer_pkg_name_ / "conf" / suffix; + inline auto GetConfigPath(const std::string &suffix = {}) const { + return base_config_path_ / "conf" / suffix; + } + + inline auto GetLogPath(const std::string &suffix = {}) const { + return base_config_path_ / "log" / suffix; + } + + inline auto GetBaseConfigPath() const { return base_config_path_; } + + inline auto GetPrefsPath(const std::string &pkg_name) const { + return base_config_path_ / "prefs" / pkg_name; } std::vector GetAppModuleList(const std::string &pkg_name) const; @@ -67,26 +73,27 @@ namespace edxp { return last_write_time_ < GetLastWriteTime(); } + void EnsurePermission(const std::string &pkg_name, uid_t uid) const; private: inline static std::unordered_map> instances_{}; inline static uid_t current_user = 0u; - inline static bool use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__; + inline static const bool use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__; const uid_t user_; const std::filesystem::path data_path_prefix_; + const std::filesystem::path base_config_path_; + const bool initialized_ = false; const std::filesystem::path installer_pkg_name_; - const bool black_list_enable_ = false; const bool white_list_enable_ = false; const bool deopt_boot_image_enabled_ = false; const bool no_module_log_enabled_ = false; const bool resources_hook_enabled_ = false; - const bool hidden_api_bypass_enabled_ = false; // snapshot at boot const std::unordered_set white_list_; const std::unordered_set black_list_; - const std::vector>> modules_list_; + const std::unordered_map>> modules_list_; const std::filesystem::file_time_type last_write_time_; @@ -102,8 +109,11 @@ namespace edxp { std::filesystem::file_time_type GetLastWriteTime() const; + bool InitConfigPath() const; + friend std::unique_ptr std::make_unique(uid_t &); + std::filesystem::path RetrieveBaseConfigPath() const; }; } // namespace edxp diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.cpp b/edxp-core/src/main/cpp/main/src/edxp_context.cpp index 0afc9f634..f9fa4022d 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp +++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -354,6 +353,7 @@ namespace edxp { ConfigManager::SetCurrentUser(user); app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList(package_name); skip_ = ShouldSkipInject(package_name, user, uid, res, app_modules_list_, is_child_zygote); + ConfigManager::GetInstance()->EnsurePermission(package_name, uid % PER_USER_RANGE); app_data_dir_ = app_data_dir; nice_name_ = nice_name; PreLoadDex(env, kInjectDexPath); @@ -372,7 +372,7 @@ namespace edxp { res, app_data_dir_, nice_name_); LOGD("injected xposed into %s", process_name.get()); } else { - auto config_manager = ConfigManager::ReleaseInstances(); + [[maybe_unused]] auto config_manager = ConfigManager::ReleaseInstances(); auto context = Context::ReleaseInstance(); LOGD("skipped %s", process_name.get()); } diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.h b/edxp-core/src/main/cpp/main/src/edxp_context.h index d246b37ce..07023bd7d 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.h +++ b/edxp-core/src/main/cpp/main/src/edxp_context.h @@ -121,7 +121,6 @@ namespace edxp { static std::tuple GetAppInfoFromDir(JNIEnv *env, jstring dir); friend std::unique_ptr std::make_unique(); - }; } diff --git a/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp b/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp index cc1fa0ddb..503f1bf07 100644 --- a/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp +++ b/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp @@ -39,12 +39,16 @@ namespace edxp { return env->NewStringUTF(ConfigManager::GetInstance()->GetDataPathPrefix().c_str()); } - static jstring ConfigManager_getInstallerConfigPath(JNI_START, jstring jSuffix) { + static jstring ConfigManager_getConfigPath(JNI_START, jstring jSuffix) { const char *suffix = env->GetStringUTFChars(jSuffix, JNI_FALSE); auto result = ConfigManager::GetInstance()->GetConfigPath(suffix); env->ReleaseStringUTFChars(jSuffix, suffix); return env->NewStringUTF(result.c_str()); + } + static jstring ConfigManager_getBaseConfigPath(JNI_START) { + auto result = ConfigManager::GetInstance()->GetBaseConfigPath(); + return env->NewStringUTF(result.c_str()); } static jstring ConfigManager_getModulesList(JNI_START) { @@ -65,8 +69,9 @@ namespace edxp { NATIVE_METHOD(ConfigManager, getXposedPropPath, "()Ljava/lang/String;"), NATIVE_METHOD(ConfigManager, getLibSandHookName, "()Ljava/lang/String;"), NATIVE_METHOD(ConfigManager, getDataPathPrefix, "()Ljava/lang/String;"), - NATIVE_METHOD(ConfigManager, getInstallerConfigPath, + NATIVE_METHOD(ConfigManager, getConfigPath, "(Ljava/lang/String;)Ljava/lang/String;"), + NATIVE_METHOD(ConfigManager, getBaseConfigPath,"()Ljava/lang/String;"), NATIVE_METHOD(ConfigManager, getModulesList, "()Ljava/lang/String;"), }; diff --git a/edxp-core/src/main/cpp/main/src/main.cpp b/edxp-core/src/main/cpp/main/src/main.cpp index 2c8a92a13..0eab6f463 100644 --- a/edxp-core/src/main/cpp/main/src/main.cpp +++ b/edxp-core/src/main/cpp/main/src/main.cpp @@ -11,11 +11,12 @@ #include #include #include -#include "native_hook.h" #include "logging.h" #include "config.h" #include "edxp_context.h" #include "riru.h" +#include "config_manager.h" +#include "native_hook.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" diff --git a/edxp-core/template_override/customize.sh b/edxp-core/template_override/customize.sh index dd1502161..e4017cae4 100644 --- a/edxp-core/template_override/customize.sh +++ b/edxp-core/template_override/customize.sh @@ -353,6 +353,22 @@ cp "${MODPATH}/module.prop" "${RIRU_TARGET}/module.prop" || abort "! Can't creat set_perm_recursive "${MODPATH}" 0 0 0755 0644 +ui_print "- Creating configuration directories" +if [[ -f /data/adb/edxp/misc_path ]]; then + MISC_PATH=$(cat /data/adb/edxp/misc_path) + ui_print "- Use previous path $MISC_PATH" +else + MISC_PATH="edxp_$(tr -cd 'A-Za-z0-9' < /dev/urandom | head -c16)" + ui_print "- Use new path $MISC_PATH" + mkdir -p /data/adb/edxp || abort "! Can't create adb path" + echo "$MISC_PATH" > /data/adb/edxp/misc_path || abort "! Can't store configuration path" +fi +set_perm_recursive /data/adb/edxp root root 0700 0600 "u:object_r:magisk_file:s0" || abort "! Can't set permission" +mkdir -p /data/misc/$MISC_PATH || abort "! Can't create configuration path" +set_perm /data/misc/$MISC_PATH root root 0771 "u:object_r:magisk_file:s0" || abort "! Can't set permission" +echo "rm -rf /data/misc/$MISC_PATH" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh" +echo "rm -rf /data/adb/edxp" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh" + ui_print "- Welcome to EdXposed ${VERSION}!" # before Magisk 16e4c67, sepolicy.rule is copied on the second reboot diff --git a/edxp-core/template_override/post-fs-data.sh b/edxp-core/template_override/post-fs-data.sh index b0de91309..c809d0407 100644 --- a/edxp-core/template_override/post-fs-data.sh +++ b/edxp-core/template_override/post-fs-data.sh @@ -35,9 +35,9 @@ RIRU_APICODE=$(cat "${RIRU_PATH}/api_version") MAGISK_VERSION=$(su -v) MAGISK_VERCODE=$(su -V) -EDXP_MANAGER="org.meowcat.edxposed.manager" -XP_INSTALLER="de.robv.android.xposed.installer" -PATH_PREFIX="/data/user_de/0/" +#EDXP_MANAGER="org.meowcat.edxposed.manager" +#XP_INSTALLER="de.robv.android.xposed.installer" +#PATH_PREFIX="/data/user_de/0/" #PATH_PREFIX_LEGACY="/data/user/0/" sepolicy() { @@ -55,14 +55,7 @@ sepolicy() { #fi DEFAULT_BASE_PATH="${PATH_PREFIX}${EDXP_MANAGER}" -BASE_PATH="${DEFAULT_BASE_PATH}" - -if [[ ! -d ${BASE_PATH} ]]; then - BASE_PATH="${PATH_PREFIX}${XP_INSTALLER}" - if [[ ! -d ${BASE_PATH} ]]; then - BASE_PATH="${DEFAULT_BASE_PATH}" - fi -fi +BASE_PATH="/data/misc/$(cat /data/adb/edxp/misc_path)/0" LOG_PATH="${BASE_PATH}/log" CONF_PATH="${BASE_PATH}/conf" @@ -165,8 +158,8 @@ start_log_cather all "EdXposed:V XSharedPreferences:V EdXposed-Bridge:V EdXposed start_log_cather error "XSharedPreferences:V EdXposed-Bridge:V" true true -if [[ -f "/data/misc/riru/modules/edxp.prop" ]]; then - CONFIG=$(cat "/data/misc/riru/modules/edxp.prop") +if [[ -f "/data/adb/riru/modules/edxp.prop" ]]; then + CONFIG=$(cat "/data/adb/riru/modules/edxp.prop") [[ -d "${TARGET}/${CONFIG}" ]] || mkdir -p "${TARGET}/${CONFIG}" cp "${MODDIR}/module.prop" "${TARGET}/${CONFIG}/module.prop" fi diff --git a/edxp-core/template_override/sepolicy.rule b/edxp-core/template_override/sepolicy.rule index 3a9f6385d..b4b0d6d60 100644 --- a/edxp-core/template_override/sepolicy.rule +++ b/edxp-core/template_override/sepolicy.rule @@ -1,4 +1,4 @@ allow system_server system_server process execmem allow system_server system_server memprotect mmap_zero -allow zygote app_data_file dir { getattr search read open } -allow zygote app_data_file file { getattr read open } \ No newline at end of file +# TODO: use rirud +allow zygote adb_data_file file { getattr read } diff --git a/edxp-core/template_override/uninstall.sh b/edxp-core/template_override/uninstall.sh index 6e74769bd..0720d701d 100644 --- a/edxp-core/template_override/uninstall.sh +++ b/edxp-core/template_override/uninstall.sh @@ -25,5 +25,3 @@ if [[ "${REMOVE}" == true ]]; then rm "/data/misc/riru/modules/edxp.prop" fi fi - - diff --git a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java index 0d18b690f..2ba46e175 100644 --- a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java +++ b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java @@ -2,7 +2,7 @@ public interface EdxpConfig { - String getInstallerConfigPath(String suffix); + String getConfigPath(String suffix); String getDataPathPrefix();