From 993ba2961651aeb656ba4a938540d2921362ab90 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Thu, 3 Dec 2020 01:49:02 +0800 Subject: [PATCH] Move dex/jar to /data/misc --- edxp-core/src/main/cpp/main/include/config.h | 4 -- edxp-core/src/main/cpp/main/include/utils.h | 17 +++--- .../src/main/cpp/main/src/config_manager.cpp | 55 +++++++++++++------ .../src/main/cpp/main/src/config_manager.h | 32 +++++++++-- .../src/main/cpp/main/src/edxp_context.cpp | 49 +++++++++-------- .../src/main/cpp/main/src/edxp_context.h | 5 +- edxp-core/template_override/customize.sh | 55 +++++++------------ 7 files changed, 124 insertions(+), 93 deletions(-) diff --git a/edxp-core/src/main/cpp/main/include/config.h b/edxp-core/src/main/cpp/main/include/config.h index c01d4279..a1b5bb43 100644 --- a/edxp-core/src/main/cpp/main/include/config.h +++ b/edxp-core/src/main/cpp/main/include/config.h @@ -29,10 +29,6 @@ inline constexpr bool is64 = Is64(); # define LP_SELECT(lp32, lp64) (lp32) #endif - static const auto kInjectDexPath = "/system/framework/edxp.dex:" - "/system/framework/eddalvikdx.dex:" - "/system/framework/eddexmaker.dex"_str; - static const auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main"_str; static const auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker"; static const auto kSandHookClassName = "com.swift.sandhook.SandHook"_str; diff --git a/edxp-core/src/main/cpp/main/include/utils.h b/edxp-core/src/main/cpp/main/include/utils.h index 299b26d8..5b37308f 100644 --- a/edxp-core/src/main/cpp/main/include/utils.h +++ b/edxp-core/src/main/cpp/main/include/utils.h @@ -22,23 +22,26 @@ namespace edxp { return {str, size}; } - inline bool path_exists(const std::filesystem::path &path, bool quite = false) { + template + inline bool path_exists(const std::filesystem::path &path) { try { return std::filesystem::exists(path); } catch (const std::filesystem::filesystem_error &e) { - if (!quite) + if constexpr(!quite) { LOGE("%s", e.what()); + } return false; } } - inline void path_chown(const std::filesystem::path &path, uid_t uid, gid_t gid, bool recursively=false) { + 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()}); + {errno, std::system_category()}); } - if(recursively) { - for(const auto &item : std::filesystem::recursive_directory_iterator(path)) { + 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()}); @@ -47,7 +50,7 @@ namespace edxp { } } - inline std::tuple path_own(const std::filesystem::path& path) { + 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 4691dbd1..8b85bfaa 100644 --- a/edxp-core/src/main/cpp/main/src/config_manager.cpp +++ b/edxp-core/src/main/cpp/main/src/config_manager.cpp @@ -85,23 +85,16 @@ namespace edxp { namespace fs = std::filesystem; fs::path ConfigManager::RetrieveBaseConfigPath() const { - fs::path misc_path("/data/adb/edxp/misc_path"); - try { - RirudSocket rirud_socket{}; - auto path = rirud_socket.ReadFile(misc_path); - path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) { - return !std::isspace(ch); - }).base(), path.end()); - return fs::path("/data/misc") / path / std::to_string(user_); - } catch (const RirudSocket::RirudSocketException &e) { - LOGE("%s", e.what()); + if (auto misc_path = GetMiscPath(); !misc_path.empty()) { + return misc_path / std::to_string(user_); + } else { return {}; } } std::string ConfigManager::RetrieveInstallerPkgName() const { std::string installer_pkg_name_path = GetConfigPath("installer"); - if (!path_exists(installer_pkg_name_path, true)) { + if (!path_exists(installer_pkg_name_path)) { LOGW("installer not set, using default one %s", kPrimaryInstallerPkgName.c_str()); return kPrimaryInstallerPkgName; } @@ -217,7 +210,7 @@ namespace edxp { 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)) { + if (!path_exists(module_scope_conf)) { LOGD("module scope is not set for %s", module_pkg_name.c_str()); continue; } @@ -253,7 +246,7 @@ namespace edxp { std::filesystem::file_time_type ConfigManager::GetLastWriteTime() const { auto modules_list = GetConfigPath("modules.list"); - if (!path_exists(modules_list, true)) + if (!path_exists(modules_list)) return {}; return fs::last_write_time(modules_list); } @@ -262,7 +255,7 @@ namespace edxp { if (base_config_path_.empty()) return false; try { fs::create_directories(base_config_path_); - fs::permissions(base_config_path_.parent_path(), + fs::permissions(GetMiscPath(), 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); @@ -286,7 +279,7 @@ namespace edxp { try { if (modules_list_.count(pkg_name)) { auto prefs_path = GetPrefsPath(pkg_name); - if (!path_exists(prefs_path, true)) { + if (!path_exists(prefs_path)) { fs::create_directories(prefs_path); } else { const auto &[r_uid, r_gid] = path_own(prefs_path); @@ -301,11 +294,11 @@ namespace edxp { } if (pkg_name == installer_pkg_name_) { auto conf_path = GetConfigPath(); - if (!path_exists(conf_path, true)) { + if (!path_exists(conf_path)) { fs::create_directories(conf_path); } auto log_path = GetLogPath(); - if (!path_exists(log_path, true)) { + if (!path_exists(log_path)) { fs::create_directories(log_path); } fs::permissions(conf_path, fs::perms::owner_all | fs::perms::group_all); @@ -322,4 +315,32 @@ namespace edxp { } } + auto ConfigManager::GetMiscPath() -> decltype(misc_path_) { + if (misc_path_.empty()) { + fs::path misc_path("/data/adb/edxp/misc_path"); + try { + RirudSocket rirud_socket{}; + auto path = rirud_socket.ReadFile(misc_path); + path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) { + return !std::isspace(ch); + }).base(), path.end()); + misc_path_ = fs::path("/data/misc") / path; + } catch (const RirudSocket::RirudSocketException &e) { + LOGE("%s", e.what()); + } + } + return misc_path_; + } + + auto ConfigManager::GetInjectDexPaths() -> decltype(inject_dex_paths_) { + if (inject_dex_paths_.empty()) { + std::transform(kXposedInjectDexPath.begin(), kXposedInjectDexPath.end(), + std::back_inserter(inject_dex_paths_), + [](auto i) { + return GetFrameworkPath(i); + }); + } + return inject_dex_paths_; + } + } \ 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 7a31ffac..2ebc527f 100644 --- a/edxp-core/src/main/cpp/main/src/config_manager.h +++ b/edxp-core/src/main/cpp/main/src/config_manager.h @@ -14,10 +14,17 @@ namespace edxp { - static const std::string kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager"; - static const std::string kXposedPropPath = "/system/framework/edconfig.jar"; class ConfigManager { + private: + inline static const auto kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager"_str; + inline static const auto kXposedPropName = "edconfig.jar"_str; + inline static const std::vector kXposedInjectDexPath = { + "edxp.dex", + "eddalvikdx.dex", + "eddexmaker.dex", + }; + public: inline static ConfigManager *GetInstance() { return instances_[current_user].get(); @@ -25,7 +32,8 @@ namespace edxp { inline static void SetCurrentUser(uid_t user) { if (auto instance = instances_.find(user); - instance == instances_.end() || !instance->second || instance->second->NeedUpdateConfig()) { + instance == instances_.end() || !instance->second || + instance->second->NeedUpdateConfig()) { instances_[user] = std::make_unique(user); } } @@ -34,6 +42,8 @@ namespace edxp { return std::move(instances_); } + inline auto IsInitialized() const { return initialized_; } + // Always true now inline auto IsBlackWhiteListEnabled() const { return true; } @@ -45,12 +55,16 @@ namespace edxp { inline auto GetInstallerPackageName() const { return installer_pkg_name_; } - inline auto GetXposedPropPath() const { return kXposedPropPath; } - inline auto GetLibSandHookName() const { return kLibSandHookName; } inline auto GetDataPathPrefix() const { return data_path_prefix_; } + inline static auto GetFrameworkPath(const std::string &suffix = {}) { + return GetMiscPath() / "framework" / suffix; + } + + inline auto GetXposedPropPath() const { return GetFrameworkPath(kXposedPropName); } + inline auto GetConfigPath(const std::string &suffix = {}) const { return base_config_path_ / "conf" / suffix; } @@ -75,11 +89,16 @@ namespace edxp { 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 std::filesystem::path misc_path_; + inline static std::vector inject_dex_paths_; inline static const bool use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__; + static decltype(misc_path_) GetMiscPath(); + const uid_t user_; const std::filesystem::path data_path_prefix_; const std::filesystem::path base_config_path_; @@ -114,6 +133,9 @@ namespace edxp { friend std::unique_ptr std::make_unique(uid_t &); std::filesystem::path RetrieveBaseConfigPath() const; + + public: + static decltype(inject_dex_paths_) GetInjectDexPaths(); }; } // 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 a51e4bfd..7c4675b8 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp +++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp @@ -58,17 +58,8 @@ namespace edxp { CallPostFixupStaticTrampolinesCallback(class_ptr, post_fixup_static_mid_); } - void Context::PreLoadDex(JNIEnv *env, const std::string &dex_path) { - if (LIKELY(!dexes.empty())) return; - std::vector paths; - { - std::istringstream is(dex_path); - std::string path; - while (std::getline(is, path, ':')) { - paths.emplace_back(std::move(path)); - } - } - for (const auto &path: paths) { + void Context::PreLoadDex(const std::vector &dex_paths) { + for (const auto &path: dex_paths) { std::ifstream is(path, std::ios::binary); if (!is.good()) { LOGE("Cannot load path %s", path.c_str()); @@ -234,15 +225,20 @@ namespace edxp { app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList( "android"); // I don't think we need this, but anyway skip_ = false; - if (!ConfigManager::GetInstance()->IsAppNeedHook("android")) { + if (!ConfigManager::GetInstance()->IsInitialized()) { + LOGE("skip injecting into android because configurations are not loaded properly"); + } + if (skip_ && !ConfigManager::GetInstance()->IsAppNeedHook("android")) { skip_ = true; - LOGW("skip injecting xposed into android because it's whitelisted/blacklisted"); + LOGW("skip injecting into android because it's whitelisted/blacklisted"); } if (!skip_ && app_modules_list_.empty()) { skip_ = true; LOGW("skip injecting into android because no module hooks it"); } - PreLoadDex(env, kInjectDexPath); + if(!skip_) { + PreLoadDex(ConfigManager::GetInjectDexPaths()); + } } @@ -278,10 +274,11 @@ namespace edxp { } std::tuple - Context::GetAppInfoFromDir(JNIEnv *env, jstring dir) { + Context::GetAppInfoFromDir(JNIEnv *env, jstring dir, jstring nice_name) { uid_t uid = 0; JUTFString app_data_dir(env, dir); - if (!app_data_dir) return {false, 0, {}}; + JUTFString name(env, nice_name); + if (!app_data_dir) return {false, 0, name.get()}; fs::path path(app_data_dir.get()); std::vector splits(path.begin(), path.end()); if (splits.size() < 5u) { @@ -304,7 +301,11 @@ namespace edxp { bool is_child_zygote) { const auto app_id = uid % PER_USER_RANGE; bool skip = false; - if (!info_res) { + if (!ConfigManager::GetInstance()->IsInitialized()) { + LOGE("skip injecting into %s because configurations are not loaded properly", package_name.c_str()); + skip = true; + } + if (!skip && !info_res) { LOGW("skip injecting into %s because it has no data dir", package_name.c_str()); skip = true; } @@ -349,14 +350,16 @@ namespace edxp { jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { - const auto&[res, user, package_name] = GetAppInfoFromDir(env, app_data_dir); - 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); + const auto&[res, user, package_name] = GetAppInfoFromDir(env, app_data_dir, nice_name); app_data_dir_ = app_data_dir; nice_name_ = nice_name; - PreLoadDex(env, kInjectDexPath); + ConfigManager::SetCurrentUser(user); + skip_ = ShouldSkipInject(package_name, user, uid, res, app_modules_list_, is_child_zygote); + if(!skip_) { + app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList(package_name); + ConfigManager::GetInstance()->EnsurePermission(package_name, uid % PER_USER_RANGE); + PreLoadDex(ConfigManager::GetInjectDexPaths()); + } } int 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 07023bd7..c14921f9 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.h +++ b/edxp-core/src/main/cpp/main/src/edxp_context.h @@ -10,7 +10,6 @@ #include "utils.h" namespace edxp { - static const auto SYSTEM_SERVER_DATA_DIR = "/data/user/0/android"_str; enum Variant { NONE = 0, YAHFA = 1, @@ -99,7 +98,7 @@ namespace edxp { Context() {} - void PreLoadDex(JNIEnv *env, const std::string &dex_path); + void PreLoadDex(const std::vector &dex_path); void InjectDexAndInit(JNIEnv *env); @@ -118,7 +117,7 @@ namespace edxp { const std::vector &app_module_list, bool is_child_zygote); - static std::tuple GetAppInfoFromDir(JNIEnv *env, jstring dir); + static std::tuple GetAppInfoFromDir(JNIEnv *env, jstring dir, jstring nice_name); friend std::unique_ptr std::make_unique(); }; diff --git a/edxp-core/template_override/customize.sh b/edxp-core/template_override/customize.sh index e4017cae..9a69d633 100644 --- a/edxp-core/template_override/customize.sh +++ b/edxp-core/template_override/customize.sh @@ -36,18 +36,6 @@ PROP_PRODUCT=$(getprop ro.build.product) PROP_BRAND=$(getprop ro.product.brand) PROP_MANUFACTURER=$(getprop ro.product.manufacturer) -JAR_EDXP="$(getRandomNameExist 8 "" ".dex" " -/system/framework -").dex" -JAR_EDDALVIKDX="$(getRandomNameExist 8 "" ".dex" " -/system/framework -").dex" -JAR_EDDEXMAKER="$(getRandomNameExist 8 "" ".dex" " -/system/framework -").dex" -#JAR_EDCONFIG="$(getRandomNameExist 8 "" ".jar" " -#/system/framework -#").jar" LIB_RIRU_EDXP="libriru_${RIRU_EDXP}.so" LIB_SANDHOOK_EDXP="lib$(getRandomNameExist 13 "lib" ".so" " /system/lib @@ -287,14 +275,30 @@ if [[ "${OLD_MAGISK}" == true ]]; then rm "${MODPATH}"/sepolicy.rule fi +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 "- Copying framework libraries" -mv "${MODPATH}/system/framework/eddalvikdx.dex" "${MODPATH}/system/framework/${JAR_EDDALVIKDX}" -mv "${MODPATH}/system/framework/edxp.dex" "${MODPATH}/system/framework/${JAR_EDXP}" -mv "${MODPATH}/system/framework/eddexmaker.dex" "${MODPATH}/system/framework/${JAR_EDDEXMAKER}" -#mv "${MODPATH}/system/framework/edconfig.jar" "${MODPATH}/system/framework/${JAR_EDCONFIG}" -mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}" +rm -rf "/data/misc/$MISC_PATH/framework" +mv "${MODPATH}/system/framework" "/data/misc/$MISC_PATH/framework" +set_perm_recursive /data/misc/$MISC_PATH/framework root root 0755 0644 "u:object_r:magisk_file:s0" || abort "! Can't set permission" +mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}" if [[ "${IS64BIT}" == true ]]; then mv "${MODPATH}/system/lib64/libriru_edxp.so" "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}" fi @@ -352,23 +356,6 @@ rm "${RIRU_TARGET}/module.prop" cp "${MODPATH}/module.prop" "${RIRU_TARGET}/module.prop" || abort "! Can't create ${RIRU_TARGET}/module.prop" 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