diff --git a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl index 18451ad0..f1af7013 100644 --- a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl +++ b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl @@ -3,9 +3,17 @@ package io.github.lsposed.lspd.service; interface ILSPApplicationService { void registerHeartBeat(IBinder handle) = 1; - int getVariant() = 2; + IBinder requestModuleBinder() = 2; - IBinder requestModuleBinder() = 3; + IBinder requestManagerBinder() = 3; - IBinder requestManagerBinder() = 4; + int getVariant() = 4; + + boolean isResourcesHookEnabled() = 5; + + List getModulesList() = 6; + + String getPrefsPath(String packageName) = 7; + + String getCachePath(String fileName) = 8; } diff --git a/core/src/main/cpp/main/include/art/runtime/runtime.h b/core/src/main/cpp/main/include/art/runtime/runtime.h index d8cde054..a9c34b0f 100644 --- a/core/src/main/cpp/main/include/art/runtime/runtime.h +++ b/core/src/main/cpp/main/include/art/runtime/runtime.h @@ -21,7 +21,6 @@ #pragma once #include -#include namespace art { diff --git a/core/src/main/cpp/main/include/config.h b/core/src/main/cpp/main/include/config.h index 1078ef39..18b35f44 100644 --- a/core/src/main/cpp/main/include/config.h +++ b/core/src/main/cpp/main/include/config.h @@ -51,6 +51,7 @@ inline constexpr bool is64 = Is64(); static const auto kEntryClassName = "io.github.lsposed.lspd.core.Main"s; static const auto kClassLinkerClassName = "io.github.lsposed.lspd.nativebridge.ClassLinker"s; static const auto kBridgeServiceClassName = "io.github.lsposed.lspd.service.BridgeService"s; + static const auto kDexPath = "/data/adb/lspd/framework/lspd.dex"s; static const auto kSandHookClassName = "com.swift.sandhook.SandHook"s; static const auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall"s; diff --git a/core/src/main/cpp/main/src/config_manager.cpp b/core/src/main/cpp/main/src/config_manager.cpp deleted file mode 100644 index 9019ee45..00000000 --- a/core/src/main/cpp/main/src/config_manager.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "art/runtime/native/native_util.h" -#include "config_manager.h" -#include "utils.h" -#include "rirud_socket.h" - -/* - * Logic: - * check if /data/adb/lspd 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. - * - * Permission: - * /data/adb/lspd 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:magisk_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 lspd - * because /data/misc/$misc_path is mounted by magisk. - * - * lspd 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 lspd { - namespace fs = std::filesystem; - - fs::path ConfigManager::RetrieveBaseConfigPath() const { - if (!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)) { - LOGW("installer not set, using default one %s", kPrimaryInstallerPkgName.c_str()); - return kPrimaryInstallerPkgName; - } - 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; - } - return {std::istream_iterator(ifs), std::istream_iterator()}; - } - - std::string ConfigManager::GetPackageNameFromBaseApkPath(const fs::path &path) { - std::vector paths(path.begin(), path.end()); - if (paths.empty()) return {}; - auto base_apk = paths.back(); // base.apk - if (base_apk != "base.apk") return {}; - paths.pop_back(); - auto pkg_name_with_obfuscation = paths.back(); - if (auto pos = pkg_name_with_obfuscation.find('-'); pos != std::string::npos) { - return pkg_name_with_obfuscation.substr(0, pos); - } - return {}; - } - - ConfigManager::ConfigManager(uid_t user, bool initialized) : - user_(user), - data_path_prefix_(fs::path("/data/user_de") / - std::to_string(user_)), - base_config_path_(RetrieveBaseConfigPath()), - initialized_(initialized || InitConfigPath()), - installer_pkg_name_(RetrieveInstallerPkgName()), - no_module_log_enabled_(path_exists(GetConfigPath("disable_modules_log"))), - resources_hook_enabled_(path_exists(GetConfigPath("enable_resources"))), - modules_list_(GetModuleList()), - last_write_time_(GetLastWriteTime()), - variant_(ReadInt(GetVariantPath())), - selinux_permissive_(ReadInt(GetSelinuxStatusPath()) != 1) { - LOGI("base config path: %s", base_config_path_.c_str()); - LOGI(" using installer package name: %s", installer_pkg_name_.c_str()); - LOGI(" no module log: %s", BoolToString(no_module_log_enabled_)); - LOGI(" resources hook: %s", BoolToString(resources_hook_enabled_)); - LOGI(" selinux permissive: %s", BoolToString(selinux_permissive_)); - 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()); - } - - int ConfigManager::ReadInt(const fs::path &dir) { - if (!path_exists(dir)) { - return 0; - } - std::ifstream ifs(dir); - if (!ifs.good()) { - return 0; - } - int result; - ifs >> result; - return result; - } - - auto ConfigManager::GetModuleList() -> std::remove_const_t { - std::remove_const_t modules_list; - auto global_modules_list = GetConfigPath("modules.list"); - if (!path_exists(global_modules_list)) { - LOGE("Cannot access path %s", global_modules_list.c_str()); - return modules_list; - } - std::ifstream ifs(global_modules_list); - if (!ifs.good()) { - LOGE("Cannot access path %s", global_modules_list.c_str()); - return modules_list; - } - std::string module; - while (std::getline(ifs, module)) { - const auto &module_pkg_name = GetPackageNameFromBaseApkPath(module); - auto &[module_path, scope] = modules_list[module_pkg_name]; - scope.insert(module_pkg_name); // Always add module itself - module_path.assign(std::move(module)); - const auto &module_scope_conf = GetConfigPath(module_pkg_name + ".conf"); - if (!path_exists(module_scope_conf)) { - LOGD("module scope is not set for %s", module_pkg_name.c_str()); - continue; - } - std::ifstream ifs_c(module_scope_conf); - if (!ifs_c.good()) { - LOGE("Cannot access path %s", module_scope_conf.c_str()); - continue; - } - 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)); - } - if (IsInstaller(module_pkg_name)) scope.erase("android"); - LOGI("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 ")); - return join.str(); - })().c_str()); - } - return modules_list; - } - - std::vector ConfigManager::GetAppModuleList(const std::string &pkg_name) const { - std::vector app_modules_list; - for (const auto&[module, scope]: modules_list_) { - if (scope.second.count(pkg_name)) - app_modules_list.push_back(scope.first); - } - return app_modules_list; - } - - fs::file_time_type ConfigManager::GetLastWriteTime() const { - auto last_write_time = [](std::string_view path) __attribute__((always_inline)) { - return path_exists(path) ? fs::last_write_time(path) : fs::file_time_type{}; - }; - std::string config_path = GetConfigPath(); - std::string list_path = GetConfigPath("modules.list"); - std::string variant_path = GetVariantPath(); - return std::max({ - last_write_time(config_path), - last_write_time(list_path), - last_write_time(variant_path) - }); - } - - bool ConfigManager::InitConfigPath() const { - if (base_config_path_.empty()) return false; - try { - fs::create_directories(base_config_path_); - fs::permissions(misc_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); - auto log_path = GetLogPath(); - auto modules_log_path = GetModulesLogPath(); - if (!fs::is_directory(log_path)) { - fs::remove(log_path); - } - if (!path_exists(log_path)) { - fs::create_directories(modules_log_path); - } - if (!path_exists(modules_log_path)) { - std::ofstream(modules_log_path, std::ios::out); - } - fs::permissions(log_path, - fs::perms::owner_all | fs::perms::group_all | fs::perms::others_all); - recursive_permissions(log_path, - fs::perms::owner_read | fs::perms::owner_write | - fs::perms::group_read | - fs::perms::group_write | fs::perms::others_read | - fs::perms::others_write, fs::perm_options::add); - } 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)) { - 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 | fs::perms::set_gid); - if (const auto &[r_uid, r_gid] = path_own(prefs_path); - (uid != -1 && r_uid != uid) || r_gid != 1000u) { - path_chown(prefs_path, uid, 1000u, false); - } - } - if (IsInstaller(pkg_name) || pkg_name == "android") { - auto conf_path = GetConfigPath(); - if (!path_exists(conf_path)) { - fs::create_directories(conf_path); - } - recursive_permissions(conf_path, fs::perms::owner_all | fs::perms::group_all | - fs::perms::set_gid); - if (pkg_name == "android") uid = -1; - path_chown(conf_path, uid, 1000u, true); - if (current_user_ == 0) { - auto variant = GetVariantPath(); - fs::permissions(variant, fs::perms::owner_all | fs::perms::group_all); - path_chown(variant, uid, 1000u); - auto disable_verbose_log = misc_path_ / "disable_verbose_log"; - fs::permissions(disable_verbose_log, - fs::perms::owner_all | fs::perms::group_all); - path_chown(disable_verbose_log, uid, 1000u); - } - - if (pkg_name == kPrimaryInstallerPkgName) { - umask(0007); - auto installer_pkg_name_path = GetConfigPath("installer"); - if (path_exists(installer_pkg_name_path)) { - fs::remove(installer_pkg_name_path); - } - } - } - } catch (const fs::filesystem_error &e) { - LOGE("%s", e.what()); - } - } - - void ConfigManager::Init() { - fs::path misc_path("/data/adb/lspd/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; - inject_dex_path_ = GetFrameworkPath(kXposedInjectDexPath); - LOGI("Got base config path: %s", misc_path_.c_str()); - } catch (const RirudSocket::RirudSocketException &e) { - LOGE("%s", e.what()); - } - } -} \ No newline at end of file diff --git a/core/src/main/cpp/main/src/config_manager.h b/core/src/main/cpp/main/src/config_manager.h deleted file mode 100644 index 91170ac5..00000000 --- a/core/src/main/cpp/main/src/config_manager.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -#pragma once - -#include -#include -#include "JNIHelper.h" -#include -#include -#include -#include -#include -#include "config.h" -#include "utils.h" - -namespace lspd { - - class ConfigManager { - private: - inline static const auto kPrimaryInstallerPkgName = "io.github.lsposed.manager"s; - inline static const auto kXposedInjectDexPath = "lspd.dex"; - - public: - static void Init(); - - inline static ConfigManager *GetInstance() { - return instances_[current_user_].get(); - } - - inline auto IsInitialized() const { return initialized_; } - - inline static void SetCurrentUser(uid_t user) { - if (auto instance = instances_.find(user); - instance == instances_.end() || !instance->second) { - instances_[user] = std::make_unique(user); - } else if (instance->second->NeedUpdateConfig()) { - instances_[user] = std::make_unique(user, - instance->second->IsInitialized()); - } - current_user_ = user; - } - - inline static auto ReleaseInstances() { - return std::move(instances_); - } - - inline const auto &GetVariant() const { return variant_; } - - inline const auto &IsResourcesHookEnabled() const { return resources_hook_enabled_; } - - inline const auto &IsNoModuleLogEnabled() const { return no_module_log_enabled_; } - - inline const auto &GetInstallerPackageName() const { return installer_pkg_name_; } - - inline const auto &GetDataPathPrefix() const { return data_path_prefix_; } - - inline static const auto &GetMiscPath() { return misc_path_; } - - inline static auto GetFrameworkPath(const std::string &suffix = {}) { - return misc_path_ / "framework" / suffix; - } - - inline static auto GetCachePath(const std::string &suffix = {}) { - return misc_path_ / "cache" / suffix; - } - - inline auto GetConfigPath(const std::string &suffix = {}) const { - return base_config_path_ / "conf" / suffix; - } - - inline static auto GetLogPath(const std::string &suffix = {}) { - return misc_path_ / "log" / suffix; - } - - inline const auto &GetBaseConfigPath() const { return base_config_path_; } - - inline auto GetPrefsPath(const std::string &pkg_name) const { - return base_config_path_ / "prefs" / pkg_name; - } - - inline static auto GetVariantPath() { - return misc_path_ / "variant"; - } - - inline static std::filesystem::path GetSelinuxStatusPath() { - return "/sys/fs/selinux/enforce"; - } - - inline static auto GetModulesLogPath() { - return GetLogPath("modules.log"); - } - - std::vector GetAppModuleList(const std::string &pkg_name) const; - - bool NeedUpdateConfig() const { - return last_write_time_ < GetLastWriteTime(); - } - - void EnsurePermission(const std::string &pkg_name, uid_t uid) const; - - static const auto &GetInjectDexPath() { return inject_dex_path_; }; - - bool IsInstaller(const std::string &pkg_name) const { - return pkg_name == installer_pkg_name_ || pkg_name == kPrimaryInstallerPkgName; - } - - bool IsPermissive() const { - return selinux_permissive_; - } - - - private: - inline static std::unordered_map> instances_{}; - inline static uid_t current_user_ = 0u; - inline static std::filesystem::path misc_path_; // /data/misc/lspd_xxxx - inline static std::filesystem::path inject_dex_path_; - - const uid_t user_; - const int variant_; - const std::filesystem::path data_path_prefix_; // /data/user_de/{user} - const std::filesystem::path base_config_path_; // /data/misc/lspd_xxxx/{user} - const bool initialized_ = false; - const std::filesystem::path installer_pkg_name_; - const bool no_module_log_enabled_ = false; - const bool resources_hook_enabled_ = false; - const bool selinux_permissive_ = false; - - const std::unordered_map>> modules_list_; - - const std::filesystem::file_time_type last_write_time_; - - ConfigManager(uid_t uid, bool initialized = false); - - std::string RetrieveInstallerPkgName() const; - - static std::string GetPackageNameFromBaseApkPath(const std::filesystem::path &path); - - std::remove_const_t GetModuleList(); - - std::filesystem::file_time_type GetLastWriteTime() const; - - bool InitConfigPath() const; - - friend std::unique_ptr std::make_unique(uid_t &); - - friend std::unique_ptr std::make_unique(uid_t &, bool &&); - - std::filesystem::path RetrieveBaseConfigPath() const; - - static int ReadInt(const std::filesystem::path &dir); - }; - -} // namespace lspd - diff --git a/core/src/main/cpp/main/src/context.cpp b/core/src/main/cpp/main/src/context.cpp index 3d1ee057..df90a388 100644 --- a/core/src/main/cpp/main/src/context.cpp +++ b/core/src/main/cpp/main/src/context.cpp @@ -21,7 +21,6 @@ #include #include #include "JNIHelper.h" -#include "jni/config_manager.h" #include "jni/art_class_linker.h" #include "jni/yahfa.h" #include "jni/resources_hook.h" @@ -32,12 +31,13 @@ #include #include #include +#include #include "context.h" -#include "config_manager.h" #include "native_hook.h" #include "jni/logger.h" #include "jni/native_api.h" #include "service.h" +#include "rirud_socket.h" namespace lspd { namespace fs = std::filesystem; @@ -66,13 +66,14 @@ namespace lspd { void Context::PreLoadDex(const fs::path &dex_path) { if (LIKELY(!dex.empty())) return; - std::ifstream is(dex_path, std::ios::binary); - if (!is.good()) { - LOGE("Cannot load path %s", dex_path.c_str()); + try { + RirudSocket socket; + auto dex_content = socket.ReadFile(dex_path); + dex.assign(dex_content.begin(), dex_content.end()); + } catch (RirudSocket::RirudSocketException &e) { + LOGE("%s", e.what()); return; } - dex.assign(std::istreambuf_iterator(is), - std::istreambuf_iterator()); LOGI("Loaded %s with size %zu", dex_path.c_str(), dex.size()); } @@ -108,9 +109,6 @@ namespace lspd { env->DeleteLocalRef(my_cl); env->GetJavaVM(&vm_); - - // Make sure config manager is always working - RegisterConfigManagerMethods(env); } void Context::Init(JNIEnv *env) { @@ -193,7 +191,6 @@ namespace lspd { void Context::OnNativeForkSystemServerPre(JNIEnv *env) { Service::instance()->InitService(env); - PreLoadDex(ConfigManager::GetInjectDexPath()); skip_ = false; } @@ -226,7 +223,6 @@ namespace lspd { jstring nice_name, jboolean is_child_zygote, jstring app_data_dir) { - PreLoadDex(ConfigManager::GetInjectDexPath()); Service::instance()->InitService(env); const auto app_id = uid % PER_USER_RANGE; nice_name_ = nice_name; diff --git a/core/src/main/cpp/main/src/context.h b/core/src/main/cpp/main/src/context.h index ff1cc6d0..553d7194 100644 --- a/core/src/main/cpp/main/src/context.h +++ b/core/src/main/cpp/main/src/context.h @@ -64,6 +64,7 @@ namespace lspd { void OnNativeForkSystemServerPre(JNIEnv *env); + void PreLoadDex(const std::filesystem::path &dex_paths); private: inline static std::unique_ptr instance_ = std::make_unique(); @@ -79,8 +80,6 @@ namespace lspd { Context() {} - void PreLoadDex(const std::filesystem::path &dex_paths); - void LoadDex(JNIEnv *env); void Init(JNIEnv *env); diff --git a/core/src/main/cpp/main/src/jni/art_class_linker.cpp b/core/src/main/cpp/main/src/jni/art_class_linker.cpp index d4dade4b..035e51f2 100644 --- a/core/src/main/cpp/main/src/jni/art_class_linker.cpp +++ b/core/src/main/cpp/main/src/jni/art_class_linker.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "art_class_linker.h" namespace lspd { diff --git a/core/src/main/cpp/main/src/jni/config_manager.cpp b/core/src/main/cpp/main/src/jni/config_manager.cpp deleted file mode 100644 index 590e58ae..00000000 --- a/core/src/main/cpp/main/src/jni/config_manager.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -#include -#include -#include -#include -#include "config_manager.h" - -namespace lspd { - - LSP_DEF_NATIVE_METHOD(jboolean, ConfigManager, isResourcesHookEnabled) { - return (jboolean) ConfigManager::GetInstance()->IsResourcesHookEnabled(); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getInstallerPackageName) { - return env->NewStringUTF(ConfigManager::GetInstance()->GetInstallerPackageName().c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getDataPathPrefix) { - return env->NewStringUTF(ConfigManager::GetInstance()->GetDataPathPrefix().c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getLogPath) { - return env->NewStringUTF(ConfigManager::GetLogPath().c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getConfigPath, 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()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getPrefsPath, jstring jSuffix) { - const char *suffix = env->GetStringUTFChars(jSuffix, JNI_FALSE); - auto result = ConfigManager::GetInstance()->GetPrefsPath(suffix); - env->ReleaseStringUTFChars(jSuffix, suffix); - return env->NewStringUTF(result.c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getCachePath, jstring jSuffix) { - const char *suffix = env->GetStringUTFChars(jSuffix, JNI_FALSE); - auto result = ConfigManager::GetCachePath(suffix); - env->ReleaseStringUTFChars(jSuffix, suffix); - return env->NewStringUTF(result.c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getBaseConfigPath) { - auto result = ConfigManager::GetInstance()->GetBaseConfigPath(); - return env->NewStringUTF(result.c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getMiscPath) { - auto result = ConfigManager::GetMiscPath(); - return env->NewStringUTF(result.c_str()); - } - - LSP_DEF_NATIVE_METHOD(jstring, ConfigManager, getModulesList) { - return nullptr; - } - - LSP_DEF_NATIVE_METHOD(jboolean, ConfigManager, isPermissive) { - return ConfigManager::GetInstance()->IsPermissive(); - } - - static JNINativeMethod gMethods[] = { - LSP_NATIVE_METHOD(ConfigManager, isResourcesHookEnabled, "()Z"), - LSP_NATIVE_METHOD(ConfigManager, getInstallerPackageName, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getDataPathPrefix, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getMiscPath, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getLogPath, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getPrefsPath, - "(Ljava/lang/String;)Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getCachePath, - "(Ljava/lang/String;)Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getBaseConfigPath, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, getModulesList, "()Ljava/lang/String;"), - LSP_NATIVE_METHOD(ConfigManager, isPermissive, "()Z"), - }; - - void RegisterConfigManagerMethods(JNIEnv *env) { - REGISTER_LSP_NATIVE_METHODS(ConfigManager); - } - -} \ No newline at end of file diff --git a/core/src/main/cpp/main/src/jni/config_manager.h b/core/src/main/cpp/main/src/jni/config_manager.h deleted file mode 100644 index 829d4b6a..00000000 --- a/core/src/main/cpp/main/src/jni/config_manager.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -#pragma once - -#include "jni.h" - -namespace lspd { - - void RegisterConfigManagerMethods(JNIEnv *env); - -} diff --git a/core/src/main/cpp/main/src/jni/logger.cpp b/core/src/main/cpp/main/src/jni/logger.cpp index 20a4a81b..6aeb5362 100644 --- a/core/src/main/cpp/main/src/jni/logger.cpp +++ b/core/src/main/cpp/main/src/jni/logger.cpp @@ -22,22 +22,22 @@ #include "nativehelper/jni_macros.h" #include "native_util.h" #include "JNIHelper.h" -#include "../config_manager.h" #include #include namespace lspd { LSP_DEF_NATIVE_METHOD(void, Logger, nativeLog, jstring jstr) { - static int fd = open(ConfigManager::GetModulesLogPath().c_str(), O_APPEND | O_WRONLY); - if (fd < 0) { - LOGD("Logger fail: %s", strerror(errno)); - return; - } - JUTFString str(env, jstr); - int res = write(fd, str.get(), std::strlen(str.get())); - if (res < 0) { - LOGD("Logger fail: %s", strerror(errno)); - } + // TODO: get log path +// static int fd = open(ConfigManager::GetModulesLogPath().c_str(), O_APPEND | O_WRONLY); +// if (fd < 0) { +// LOGD("Logger fail: %s", strerror(errno)); +// return; +// } +// JUTFString str(env, jstr); +// int res = write(fd, str.get(), std::strlen(str.get())); +// if (res < 0) { +// LOGD("Logger fail: %s", strerror(errno)); +// } } static JNINativeMethod gMethods[] = { diff --git a/core/src/main/cpp/main/src/main.cpp b/core/src/main/cpp/main/src/main.cpp index 2d8e5170..3e6a7603 100644 --- a/core/src/main/cpp/main/src/main.cpp +++ b/core/src/main/cpp/main/src/main.cpp @@ -26,15 +26,14 @@ #include "config.h" #include "context.h" #include -#include "config_manager.h" #include "symbol_cache.h" namespace lspd { static void onModuleLoaded() { LOGI("onModuleLoaded: welcome to LSPosed!"); // rirud must be used in onModuleLoaded + Context::GetInstance()->PreLoadDex(kDexPath); InitSymbolCache(); - ConfigManager::Init(); } static int shouldSkipUid(int) { diff --git a/core/src/main/cpp/main/src/native_hook.cpp b/core/src/main/cpp/main/src/native_hook.cpp index 1000f942..b21fbc81 100644 --- a/core/src/main/cpp/main/src/native_hook.cpp +++ b/core/src/main/cpp/main/src/native_hook.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/core/src/main/cpp/main/src/service.cpp b/core/src/main/cpp/main/src/service.cpp index 20453b80..f4ea7648 100644 --- a/core/src/main/cpp/main/src/service.cpp +++ b/core/src/main/cpp/main/src/service.cpp @@ -152,8 +152,10 @@ namespace lspd { jobject service = nullptr; if (res) { - JNI_CallVoidMethod(env, reply, readExceptionMethod_); - service = JNI_CallObjectMethod(env, reply, readStrongBinderMethod_); + env->CallVoidMethod(reply, readExceptionMethod_); + if (!ClearException(env)) { + service = JNI_CallObjectMethod(env, reply, readStrongBinderMethod_); + } } JNI_CallVoidMethod(env, data, recycleMethod_); JNI_CallVoidMethod(env, reply, recycleMethod_); diff --git a/core/src/main/java/de/robv/android/xposed/XSharedPreferences.java b/core/src/main/java/de/robv/android/xposed/XSharedPreferences.java index 87fec8d0..36a55b90 100644 --- a/core/src/main/java/de/robv/android/xposed/XSharedPreferences.java +++ b/core/src/main/java/de/robv/android/xposed/XSharedPreferences.java @@ -52,6 +52,8 @@ import java.util.Set; import de.robv.android.xposed.services.FileResult; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; + /** * This class is basically the same as SharedPreferencesImpl from AOSP, but * read-only and without listeners support. Instead, it is made to be @@ -180,8 +182,9 @@ public final class XSharedPreferences implements SharedPreferences { newModule = isModule && (xposedminversion > 92 || xposedsharedprefs); } } - if (newModule && XposedInit.prefsBasePath != null) { - mFile = new File(XposedInit.prefsBasePath, packageName + "/" + prefFileName + ".xml"); + if (newModule) { + + mFile = new File(serviceClient.getPrefsPath( packageName ), prefFileName + ".xml"); } else { mFile = new File(Environment.getDataDirectory(), "data/" + packageName + "/shared_prefs/" + prefFileName + ".xml"); } @@ -198,7 +201,8 @@ public final class XSharedPreferences implements SharedPreferences { Path path = mFile.toPath(); try { if (sWatcher == null) { - sWatcher = new File(XposedInit.prefsBasePath).toPath().getFileSystem().newWatchService(); + // TODO +// sWatcher = new File(XposedInit.prefsBasePath).toPath().getFileSystem().newWatchService(); if (BuildConfig.DEBUG) Log.d(TAG, "Created WatchService instance"); } mWatchKey = path.getParent().register(sWatcher, StandardWatchEventKinds.ENTRY_CREATE, diff --git a/core/src/main/java/de/robv/android/xposed/XposedBridge.java b/core/src/main/java/de/robv/android/xposed/XposedBridge.java index 35a01f9d..2a081feb 100644 --- a/core/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/core/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -25,7 +25,6 @@ import android.content.res.TypedArray; import android.util.Log; import io.github.lsposed.lspd.BuildConfig; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.config.LSPdConfigGlobal; import java.lang.reflect.AccessibleObject; @@ -98,15 +97,6 @@ public final class XposedBridge { private XposedBridge() {} - /** - * Called when native methods and other things are initialized, but before preloading classes etc. - * @hide - */ - @SuppressWarnings("deprecation") - public static void main(String[] args) { - // ed: moved - } - /** @hide */ // protected static final class ToolEntryPoint { // protected static void main(String[] args) { diff --git a/core/src/main/java/de/robv/android/xposed/XposedInit.java b/core/src/main/java/de/robv/android/xposed/XposedInit.java index 85697e6f..cbe53bc8 100644 --- a/core/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/core/src/main/java/de/robv/android/xposed/XposedInit.java @@ -34,7 +34,6 @@ import android.util.Log; import com.android.internal.os.ZygoteInit; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.config.LSPdConfigGlobal; import java.io.BufferedReader; @@ -49,6 +48,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -77,6 +77,7 @@ import static de.robv.android.xposed.XposedHelpers.getParameterIndexByType; import static de.robv.android.xposed.XposedHelpers.setStaticBooleanField; import static de.robv.android.xposed.XposedHelpers.setStaticLongField; import static de.robv.android.xposed.XposedHelpers.setStaticObjectField; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; public final class XposedInit { private static final String TAG = XposedBridge.TAG; @@ -86,7 +87,6 @@ public final class XposedInit { private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication"; public static volatile boolean disableResources = false; private static final String[] XRESOURCES_CONFLICTING_PACKAGES = {"com.sygic.aura"}; - public static String prefsBasePath = null; private XposedInit() { } @@ -113,7 +113,7 @@ public final class XposedInit { @ApiSensitive(Level.MIDDLE) private static void hookResources() throws Throwable { - if (!ConfigManager.isResourcesHookEnabled() || disableResources) { + if (!serviceClient.isResourcesHookEnabled() || disableResources) { return; } @@ -353,12 +353,9 @@ public final class XposedInit { topClassLoader = parent; } - String moduleList = ConfigManager.getModulesList(); - InputStream stream = new ByteArrayInputStream(moduleList.getBytes()); - BufferedReader apks = new BufferedReader(new InputStreamReader(stream)); + List moduleList = serviceClient.getModulesList(); ArraySet newLoadedApk = new ArraySet<>(); - String apk; - while ((apk = apks.readLine()) != null) { + for (String apk : moduleList) if (loadedModules.contains(apk)) { newLoadedApk.add(apk); } else { @@ -368,10 +365,9 @@ public final class XposedInit { newLoadedApk.add(apk); } } - } + loadedModules.clear(); loadedModules.addAll(newLoadedApk); - apks.close(); // refresh callback according to current loaded module list pruneCallbacks(loadedModules); diff --git a/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java b/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java new file mode 100644 index 00000000..b80f7189 --- /dev/null +++ b/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java @@ -0,0 +1,121 @@ +package io.github.lsposed.lspd.config; + +import android.os.IBinder; +import android.os.RemoteException; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import io.github.lsposed.lspd.service.ILSPApplicationService; +import io.github.lsposed.lspd.util.Utils; + +public class LSPApplicationServiceClient implements ILSPApplicationService { + static ILSPApplicationService service = null; + static IBinder serviceBinder = null; + + static String baseCachePath = null; + static String basePrefsPath = null; + + public static LSPApplicationServiceClient serviceClient = null; + + public static void Init(IBinder binder) { + if (serviceClient == null && binder != null && serviceBinder == null && service == null) { + serviceBinder = binder; + try { + serviceBinder.linkToDeath(() -> { + serviceBinder = null; + service = null; + }, 0); + } catch (RemoteException e) { + Utils.logE("link to death error: ", e); + } + service = ILSPApplicationService.Stub.asInterface(binder); + serviceClient = new LSPApplicationServiceClient(); + } + } + + @Override + public void registerHeartBeat(IBinder handle) { + if (service == null || serviceBinder == null) { + Utils.logE("Register Failed: service is null"); + } + try { + service.registerHeartBeat(handle); + } catch (RemoteException e) { + Utils.logE("register heart beat failed", e); + } + } + + @Override + public IBinder requestModuleBinder() { + try { + return service.requestModuleBinder(); + } catch (RemoteException | NullPointerException ignored) { + } + return null; + } + + @Override + public IBinder requestManagerBinder() { + try { + return service.requestManagerBinder(); + } catch (RemoteException | NullPointerException ignored) { + } + return null; + } + + @Override + public int getVariant() { + try { + return service.getVariant(); + } catch (RemoteException | NullPointerException ignored) { + } + return -1; + } + + @Override + public boolean isResourcesHookEnabled() { + try { + return service.isResourcesHookEnabled(); + } catch (RemoteException | NullPointerException ignored) { + } + return false; + } + + @Override + public List getModulesList() { + try { + return service.getModulesList(); + } catch (RemoteException | NullPointerException ignored) { + } + return Collections.emptyList(); + } + + @Override + public String getPrefsPath(String packageName) { + try { + if (basePrefsPath == null) + basePrefsPath = service.getPrefsPath(""); + return basePrefsPath + File.separator + packageName; + } catch (RemoteException | NullPointerException ignored) { + } + return null; + } + + @Override + public String getCachePath(String fileName) { + try { + if (baseCachePath == null) + baseCachePath = service.getCachePath(""); + return baseCachePath + File.separator + fileName; + } catch (RemoteException | NullPointerException ignored) { + } + return null; + } + + @Override + public IBinder asBinder() { + return serviceBinder; + } +} diff --git a/core/src/main/java/io/github/lsposed/lspd/core/Main.java b/core/src/main/java/io/github/lsposed/lspd/core/Main.java index a4d1c413..d41d566e 100644 --- a/core/src/main/java/io/github/lsposed/lspd/core/Main.java +++ b/core/src/main/java/io/github/lsposed/lspd/core/Main.java @@ -29,12 +29,14 @@ import android.util.Log; import android.ddm.DdmHandleAppName; import io.github.lsposed.common.KeepAll; +import io.github.lsposed.lspd.config.LSPApplicationServiceClient; import io.github.lsposed.lspd.service.ILSPApplicationService; import io.github.lsposed.lspd.service.ServiceManager; import io.github.lsposed.lspd.util.Utils; import java.util.concurrent.atomic.AtomicReference; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; import static io.github.lsposed.lspd.service.ServiceManager.TAG; @SuppressLint("DefaultLocale") @@ -43,15 +45,9 @@ public class Main implements KeepAll { private static final Binder heartBeatBinder = new Binder(); public static void forkAndSpecializePost(String appDataDir, String niceName, IBinder binder) { - ILSPApplicationService service = ILSPApplicationService.Stub.asInterface(binder); - final int variant; - try { - service.registerHeartBeat(heartBeatBinder); - variant = service.getVariant(); - } catch (RemoteException e) { - Utils.logW("Register fail", e); - return; - } + LSPApplicationServiceClient.Init(binder); + serviceClient.registerHeartBeat(heartBeatBinder); + final int variant = serviceClient.getVariant(); EdxpImpl lspd = getEdxpImpl(variant); if (lspd == null || !lspd.isInitialized()) { Utils.logE("Not started up"); @@ -61,15 +57,9 @@ public class Main implements KeepAll { } public static void forkSystemServerPost(IBinder binder) { - ILSPApplicationService service = ILSPApplicationService.Stub.asInterface(binder); - final int variant; - try { - service.registerHeartBeat(heartBeatBinder); - variant = service.getVariant(); - } catch (RemoteException e) { - Utils.logW("Register fail", e); - return; - } + LSPApplicationServiceClient.Init(binder); + serviceClient.registerHeartBeat(heartBeatBinder); + final int variant = serviceClient.getVariant(); EdxpImpl lspd = getEdxpImpl(variant); if (lspd == null || !lspd.isInitialized()) { return; diff --git a/core/src/main/java/io/github/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java b/core/src/main/java/io/github/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java index 28ef5518..6f2bd779 100644 --- a/core/src/main/java/io/github/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java +++ b/core/src/main/java/io/github/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java @@ -22,7 +22,6 @@ package io.github.lsposed.lspd.deopt; import android.text.TextUtils; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.config.LSPdConfigGlobal; import io.github.lsposed.lspd.util.Utils; @@ -30,6 +29,7 @@ import java.util.Arrays; import de.robv.android.xposed.XposedHelpers; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; import static io.github.lsposed.lspd.deopt.InlinedMethodCallers.KEY_BOOT_IMAGE; import static io.github.lsposed.lspd.deopt.InlinedMethodCallers.KEY_BOOT_IMAGE_MIUI_RES; import static io.github.lsposed.lspd.deopt.InlinedMethodCallers.KEY_SYSTEM_SERVER; @@ -62,7 +62,7 @@ public class PrebuiltMethodsDeopter { // todo check if has been done before deoptMethods(KEY_BOOT_IMAGE, null); if (!TextUtils.isEmpty(Utils.getSysProp("ro.miui.ui.version.code")) - && ConfigManager.isResourcesHookEnabled()) { + && serviceClient.isResourcesHookEnabled()) { //deopt these only for MIUI with resources hook enabled deoptMethods(KEY_BOOT_IMAGE_MIUI_RES, null); } diff --git a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/HandleBindApp.java b/core/src/main/java/io/github/lsposed/lspd/hooker/HandleBindAppHooker.java similarity index 91% rename from core/src/main/java/io/github/lsposed/lspd/_hooker/impl/HandleBindApp.java rename to core/src/main/java/io/github/lsposed/lspd/hooker/HandleBindAppHooker.java index 7aa87f0a..18935dea 100644 --- a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/HandleBindApp.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/HandleBindAppHooker.java @@ -18,7 +18,7 @@ * Copyright (C) 2021 LSPosed Contributors */ -package io.github.lsposed.lspd._hooker.impl; +package io.github.lsposed.lspd.hooker; import android.annotation.SuppressLint; import android.app.ActivityThread; @@ -30,7 +30,6 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.XResources; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.Hookers; import io.github.lsposed.lspd.util.MetaDataReader; import io.github.lsposed.lspd.util.Utils; @@ -46,8 +45,15 @@ import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; + // normal process initialization (for new Activity, Service, BroadcastReceiver etc.) -public class HandleBindApp extends XC_MethodHook { +public class HandleBindAppHooker extends XC_MethodHook { + String appDataDir = null; + + public HandleBindAppHooker(String appDataDir) { + this.appDataDir = appDataDir; + } @Override protected void beforeHookedMethod(MethodHookParam param) { @@ -57,10 +63,10 @@ public class HandleBindApp extends XC_MethodHook { Object bindData = param.args[0]; final ApplicationInfo appInfo = (ApplicationInfo) XposedHelpers.getObjectField(bindData, "appInfo"); // save app process name here for later use - ConfigManager.appProcessName = (String) XposedHelpers.getObjectField(bindData, "processName"); + String appProcessName = (String) XposedHelpers.getObjectField(bindData, "processName"); String reportedPackageName = appInfo.packageName.equals("android") ? "system" : appInfo.packageName; - Utils.logD("processName=" + ConfigManager.appProcessName + - ", packageName=" + reportedPackageName + ", appDataDir=" + ConfigManager.appDataDir); + Utils.logD("processName=" + appProcessName + + ", packageName=" + reportedPackageName + ", appDataDir=" + appDataDir); ComponentName instrumentationName = (ComponentName) XposedHelpers.getObjectField(bindData, "instrumentationName"); if (instrumentationName != null) { @@ -118,7 +124,7 @@ public class HandleBindApp extends XC_MethodHook { XposedHelpers.findAndHookMethod(ContextImpl.class, "getPreferencesDir", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) { - File newDir = new File(ConfigManager.getPrefsPath(appInfo.packageName)); + File newDir = new File(serviceClient.getPrefsPath(appInfo.packageName)); if (migratePrefs) { File oldDir = (File) param.getResult(); for (File oldFile : oldDir.listFiles()) { @@ -143,7 +149,7 @@ public class HandleBindApp extends XC_MethodHook { } }); } - LoadedApkGetCL hook = new LoadedApkGetCL(loadedApk, reportedPackageName, + LoadedApkGetCLHooker hook = new LoadedApkGetCLHooker(loadedApk, reportedPackageName, processName, true); hook.setUnhook(XposedHelpers.findAndHookMethod( LoadedApk.class, "getClassLoader", hook)); diff --git a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkCstr.java b/core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkCstrHooker.java similarity index 94% rename from core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkCstr.java rename to core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkCstrHooker.java index b674c718..0c52a9a3 100644 --- a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkCstr.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkCstrHooker.java @@ -18,7 +18,7 @@ * Copyright (C) 2021 LSPosed Contributors */ -package io.github.lsposed.lspd._hooker.impl; +package io.github.lsposed.lspd.hooker; import android.app.AndroidAppHelper; import android.app.LoadedApk; @@ -33,7 +33,7 @@ import de.robv.android.xposed.XposedInit; // when a package is loaded for an existing process, trigger the callbacks as well // ed: remove resources related hooking -public class LoadedApkCstr extends XC_MethodHook { +public class LoadedApkCstrHooker extends XC_MethodHook { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { @@ -70,7 +70,7 @@ public class LoadedApkCstr extends XC_MethodHook { return; } - LoadedApkGetCL hook = new LoadedApkGetCL(loadedApk, packageName, + LoadedApkGetCLHooker hook = new LoadedApkGetCLHooker(loadedApk, packageName, AndroidAppHelper.currentProcessName(), false); hook.setUnhook(XposedHelpers.findAndHookMethod( LoadedApk.class, "getClassLoader", hook)); diff --git a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkGetCL.java b/core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkGetCLHooker.java similarity index 87% rename from core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkGetCL.java rename to core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkGetCLHooker.java index e59097a7..fec28f8d 100644 --- a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/LoadedApkGetCL.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/LoadedApkGetCLHooker.java @@ -18,20 +18,22 @@ * Copyright (C) 2021 LSPosed Contributors */ -package io.github.lsposed.lspd._hooker.impl; +package io.github.lsposed.lspd.hooker; import android.app.LoadedApk; +import android.os.IBinder; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.lsposed.lspd.hooker.XposedInstallerHooker; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.Hookers; import io.github.lsposed.lspd.util.InstallerVerifier; -public class LoadedApkGetCL extends XC_MethodHook { +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; + +public class LoadedApkGetCLHooker extends XC_MethodHook { private final LoadedApk loadedApk; private final String packageName; @@ -39,8 +41,8 @@ public class LoadedApkGetCL extends XC_MethodHook { private final boolean isFirstApplication; private Unhook unhook; - public LoadedApkGetCL(LoadedApk loadedApk, String packageName, String processName, - boolean isFirstApplication) { + public LoadedApkGetCLHooker(LoadedApk loadedApk, String packageName, String processName, + boolean isFirstApplication) { this.loadedApk = loadedApk; this.packageName = packageName; this.processName = processName; @@ -76,9 +78,10 @@ public class LoadedApkGetCL extends XC_MethodHook { lpparam.appInfo = loadedApk.getApplicationInfo(); lpparam.isFirstApplication = this.isFirstApplication; - if (packageName.equals(ConfigManager.getInstallerPackageName())) { + IBinder binder = serviceClient.requestManagerBinder(); + if (binder != null) { if (InstallerVerifier.verifyInstallerSignature(loadedApk.getApplicationInfo())) { - XposedInstallerHooker.hookXposedInstaller(lpparam.classLoader); + XposedInstallerHooker.hookXposedInstaller(lpparam.classLoader, binder); } else { InstallerVerifier.hookXposedInstaller(classLoader); } diff --git a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/StartBootstrapServices.java b/core/src/main/java/io/github/lsposed/lspd/hooker/StartBootstrapServicesHooker.java similarity index 89% rename from core/src/main/java/io/github/lsposed/lspd/_hooker/impl/StartBootstrapServices.java rename to core/src/main/java/io/github/lsposed/lspd/hooker/StartBootstrapServicesHooker.java index 0472da3b..ddc34bce 100644 --- a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/StartBootstrapServices.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/StartBootstrapServicesHooker.java @@ -18,7 +18,7 @@ * Copyright (C) 2021 LSPosed Contributors */ -package io.github.lsposed.lspd._hooker.impl; +package io.github.lsposed.lspd.hooker; import android.os.Build; @@ -34,7 +34,7 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import static io.github.lsposed.lspd.util.Utils.logD; import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; -public class StartBootstrapServices extends XC_MethodHook { +public class StartBootstrapServicesHooker extends XC_MethodHook { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { @@ -50,7 +50,7 @@ public class StartBootstrapServices extends XC_MethodHook { XC_LoadPackage.LoadPackageParam lpparam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks); lpparam.packageName = "android"; lpparam.processName = "android"; // it's actually system_server, but other functions return this as well - lpparam.classLoader = SystemMain.systemServerCL; + lpparam.classLoader = SystemMainHooker.systemServerCL; lpparam.appInfo = null; lpparam.isFirstApplication = true; XC_LoadPackage.callAll(lpparam); @@ -58,14 +58,14 @@ public class StartBootstrapServices extends XC_MethodHook { // Huawei try { findAndHookMethod("com.android.server.pm.HwPackageManagerService", - SystemMain.systemServerCL, "isOdexMode", + SystemMainHooker.systemServerCL, "isOdexMode", XC_MethodReplacement.returnConstant(false)); } catch (XposedHelpers.ClassNotFoundError | NoSuchMethodError ignored) { } try { String className = "com.android.server.pm." + (Build.VERSION.SDK_INT >= 23 ? "PackageDexOptimizer" : "PackageManagerService"); - findAndHookMethod(className, SystemMain.systemServerCL, + findAndHookMethod(className, SystemMainHooker.systemServerCL, "dexEntryExists", String.class, XC_MethodReplacement.returnConstant(true)); } catch (XposedHelpers.ClassNotFoundError | NoSuchMethodError ignored) { diff --git a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/SystemMain.java b/core/src/main/java/io/github/lsposed/lspd/hooker/SystemMainHooker.java similarity index 95% rename from core/src/main/java/io/github/lsposed/lspd/_hooker/impl/SystemMain.java rename to core/src/main/java/io/github/lsposed/lspd/hooker/SystemMainHooker.java index 3a9b827c..5f920085 100644 --- a/core/src/main/java/io/github/lsposed/lspd/_hooker/impl/SystemMain.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/SystemMainHooker.java @@ -18,7 +18,7 @@ * Copyright (C) 2021 LSPosed Contributors */ -package io.github.lsposed.lspd._hooker.impl; +package io.github.lsposed.lspd.hooker; import io.github.lsposed.lspd.core.Main; import io.github.lsposed.lspd.deopt.PrebuiltMethodsDeopter; @@ -29,7 +29,7 @@ import de.robv.android.xposed.XposedBridge; // system_server initialization // ed: only support sdk >= 21 for now -public class SystemMain extends XC_MethodHook { +public class SystemMainHooker extends XC_MethodHook { public static volatile ClassLoader systemServerCL; diff --git a/core/src/main/java/io/github/lsposed/lspd/hooker/XposedInstallerHooker.java b/core/src/main/java/io/github/lsposed/lspd/hooker/XposedInstallerHooker.java index fca2bb20..cf1eec77 100644 --- a/core/src/main/java/io/github/lsposed/lspd/hooker/XposedInstallerHooker.java +++ b/core/src/main/java/io/github/lsposed/lspd/hooker/XposedInstallerHooker.java @@ -20,19 +20,16 @@ package io.github.lsposed.lspd.hooker; -import de.robv.android.xposed.XC_MethodReplacement; -import de.robv.android.xposed.XposedBridge; +import android.os.IBinder; + import de.robv.android.xposed.XposedHelpers; -import io.github.lsposed.lspd.BuildConfig; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.core.EdxpImpl; import io.github.lsposed.lspd.core.Main; -import io.github.lsposed.lspd.service.BridgeService; import io.github.lsposed.lspd.util.Utils; public class XposedInstallerHooker { - public static void hookXposedInstaller(final ClassLoader classLoader) { + public static void hookXposedInstaller(final ClassLoader classLoader, IBinder binder) { final String variant; switch (Main.getEdxpVariant()) { case EdxpImpl.YAHFA: @@ -51,72 +48,8 @@ public class XposedInstallerHooker { // LSPosed Manager R try { - Class ConstantsClass = XposedHelpers.findClass("io.github.lsposed.manager.Constants", classLoader); - try { - XposedHelpers.setStaticIntField(ConstantsClass, "xposedApiVersion", XposedBridge.getXposedVersion()); - XposedHelpers.setStaticObjectField(ConstantsClass, "xposedVersion", BuildConfig.VERSION_NAME); - XposedHelpers.setStaticIntField(ConstantsClass, "xposedVersionCode", BuildConfig.VERSION_CODE); - XposedHelpers.setStaticObjectField(ConstantsClass, "xposedVariant", variant); - XposedHelpers.setStaticObjectField(ConstantsClass, "baseDir", ConfigManager.getBaseConfigPath() + "/"); - XposedHelpers.setStaticObjectField(ConstantsClass, "logDir", ConfigManager.getLogPath()); - XposedHelpers.setStaticObjectField(ConstantsClass, "miscDir", ConfigManager.getMiscPath()); - XposedHelpers.setStaticBooleanField(ConstantsClass, "permissive", ConfigManager.isPermissive()); - - Utils.logI("Hooked LSPosed Manager"); - return; - } catch (Throwable ignored) { - // fallback - } - XposedHelpers.findAndHookMethod(ConstantsClass, "getXposedApiVersion", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return XposedBridge.getXposedVersion(); - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getXposedVersion", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return BuildConfig.VERSION_NAME; - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getXposedVersionCode", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return BuildConfig.VERSION_CODE; - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getXposedVariant", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return variant; - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getBaseDir", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return ConfigManager.getBaseConfigPath() + "/"; - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "isPermissive", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return ConfigManager.isPermissive(); - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getLogDir", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return ConfigManager.getLogPath(); - } - }); - XposedHelpers.findAndHookMethod(ConstantsClass, "getMiscDir", new XC_MethodReplacement() { - @Override - protected Object replaceHookedMethod(MethodHookParam param) { - return ConfigManager.getMiscPath(); - } - }); Class serviceClass = XposedHelpers.findClass("io.github.lsposed.manager.receivers.LSPosedManagerServiceClient", classLoader); -// XposedHelpers.setStaticObjectField(serviceClass, "binder", BridgeService.requireBinder()); + XposedHelpers.setStaticObjectField(serviceClass, "binder", binder); Utils.logI("Hooked LSPosed Manager"); } catch (Throwable t) { diff --git a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ConfigManager.java b/core/src/main/java/io/github/lsposed/lspd/nativebridge/ConfigManager.java deleted file mode 100644 index 152d745d..00000000 --- a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ConfigManager.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package io.github.lsposed.lspd.nativebridge; - -public class ConfigManager { - - public static String appDataDir = ""; - public static String niceName = ""; - public static String appProcessName = ""; - - public static native boolean isResourcesHookEnabled(); - - public static native String getInstallerPackageName(); - - public static native String getPrefsPath(String suffix); - - public static native String getCachePath(String suffix); - - public static native String getLogPath(); - - public static native String getMiscPath(); - - public static native String getBaseConfigPath(); - - public static native String getDataPathPrefix(); - - public static native String getModulesList(); - - public static native boolean isPermissive(); -} diff --git a/core/src/main/java/io/github/lsposed/lspd/proxy/BaseRouter.java b/core/src/main/java/io/github/lsposed/lspd/proxy/BaseRouter.java index cf97e75d..0e3b3723 100644 --- a/core/src/main/java/io/github/lsposed/lspd/proxy/BaseRouter.java +++ b/core/src/main/java/io/github/lsposed/lspd/proxy/BaseRouter.java @@ -25,10 +25,10 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.text.TextUtils; -import io.github.lsposed.lspd._hooker.impl.HandleBindApp; -import io.github.lsposed.lspd._hooker.impl.LoadedApkCstr; -import io.github.lsposed.lspd._hooker.impl.StartBootstrapServices; -import io.github.lsposed.lspd._hooker.impl.SystemMain; +import io.github.lsposed.lspd.hooker.HandleBindAppHooker; +import io.github.lsposed.lspd.hooker.LoadedApkCstrHooker; +import io.github.lsposed.lspd.hooker.StartBootstrapServicesHooker; +import io.github.lsposed.lspd.hooker.SystemMainHooker; import io.github.lsposed.lspd.util.Utils; import io.github.lsposed.lspd.util.Versions; @@ -53,13 +53,13 @@ public abstract class BaseRouter implements Router { XposedInit.startsSystemServer = isSystem; } - public void installBootstrapHooks(boolean isSystem) { + public void installBootstrapHooks(boolean isSystem, String appDataDir) { // Initialize the Xposed framework try { if (!bootstrapHooked.compareAndSet(false, true)) { return; } - startBootstrapHook(isSystem); + startBootstrapHook(isSystem, appDataDir); XposedInit.initForZygote(isSystem); } catch (Throwable t) { Utils.logE("error during Xposed initialization", t); @@ -88,30 +88,30 @@ public abstract class BaseRouter implements Router { @ApiSensitive(Level.LOW) - public void startBootstrapHook(boolean isSystem) { + public void startBootstrapHook(boolean isSystem, String appDataDir) { Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); ClassLoader classLoader = BaseRouter.class.getClassLoader(); if (isSystem) { XposedHelpers.findAndHookMethod("android.app.ActivityThread", classLoader, - "systemMain", new SystemMain()); + "systemMain", new SystemMainHooker()); } XposedHelpers.findAndHookMethod("android.app.ActivityThread", classLoader, "handleBindApplication", "android.app.ActivityThread$AppBindData", - new HandleBindApp()); + new HandleBindAppHooker(appDataDir)); XposedHelpers.findAndHookConstructor("android.app.LoadedApk", classLoader, ActivityThread.class, ApplicationInfo.class, CompatibilityInfo.class, ClassLoader.class, boolean.class, boolean.class, boolean.class, - new LoadedApkCstr()); + new LoadedApkCstrHooker()); } public void startSystemServerHook() { - StartBootstrapServices sbsHooker = new StartBootstrapServices(); + StartBootstrapServicesHooker sbsHooker = new StartBootstrapServicesHooker(); Object[] paramTypesAndCallback = Versions.hasR() ? new Object[]{"com.android.server.utils.TimingsTraceAndSlog", sbsHooker} : new Object[]{sbsHooker}; XposedHelpers.findAndHookMethod("com.android.server.SystemServer", - SystemMain.systemServerCL, + SystemMainHooker.systemServerCL, "startBootstrapServices", paramTypesAndCallback); } } diff --git a/core/src/main/java/io/github/lsposed/lspd/proxy/NormalProxy.java b/core/src/main/java/io/github/lsposed/lspd/proxy/NormalProxy.java index ddf91bf2..900f5c45 100644 --- a/core/src/main/java/io/github/lsposed/lspd/proxy/NormalProxy.java +++ b/core/src/main/java/io/github/lsposed/lspd/proxy/NormalProxy.java @@ -20,15 +20,16 @@ package io.github.lsposed.lspd.proxy; -import io.github.lsposed.lspd.nativebridge.ConfigManager; +import android.os.Environment; + +import java.io.File; + import io.github.lsposed.lspd.deopt.PrebuiltMethodsDeopter; import io.github.lsposed.lspd.util.Utils; import de.robv.android.xposed.SELinuxHelper; import de.robv.android.xposed.XposedInit; -import static io.github.lsposed.lspd.util.FileUtils.getDataPathPrefix; - public class NormalProxy extends BaseProxy { public NormalProxy(Router router) { @@ -41,7 +42,7 @@ public class NormalProxy extends BaseProxy { public void forkSystemServerPost() { forkPostCommon(true, - getDataPathPrefix() + "android", "system_server"); + new File(Environment.getDataDirectory(), "android").toString(), "system_server"); } @@ -50,10 +51,7 @@ public class NormalProxy extends BaseProxy { mRouter.initResourcesHook(); mRouter.prepare(isSystem); PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote - ConfigManager.appDataDir = appDataDir; - ConfigManager.niceName = niceName; - mRouter.installBootstrapHooks(isSystem); - XposedInit.prefsBasePath = ConfigManager.getPrefsPath(""); + mRouter.installBootstrapHooks(isSystem, appDataDir); mRouter.onEnterChildProcess(); Utils.logI("Loading modules for " + niceName); mRouter.loadModulesSafely(true); diff --git a/core/src/main/java/io/github/lsposed/lspd/proxy/Router.java b/core/src/main/java/io/github/lsposed/lspd/proxy/Router.java index b3b4257f..c61c67d1 100644 --- a/core/src/main/java/io/github/lsposed/lspd/proxy/Router.java +++ b/core/src/main/java/io/github/lsposed/lspd/proxy/Router.java @@ -26,13 +26,11 @@ public interface Router { void prepare(boolean isSystem); - String parsePackageName(String appDataDir); - - void installBootstrapHooks(boolean isSystem); + void installBootstrapHooks(boolean isSystem, String appDataDir); void loadModulesSafely(boolean callInitZygote); - void startBootstrapHook(boolean isSystem); + void startBootstrapHook(boolean isSystem, String appDataDir); void startSystemServerHook(); diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookRouter.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookRouter.java index d3e2127a..ae9863bd 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookRouter.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookRouter.java @@ -23,45 +23,13 @@ package io.github.lsposed.lspd.sandhook.core; import io.github.lsposed.lspd.config.LSPdConfigGlobal; import io.github.lsposed.lspd.proxy.BaseRouter; import io.github.lsposed.lspd.sandhook.config.SandHookProvider; -import io.github.lsposed.lspd.sandhook.entry.AppBootstrapHookInfo; -import io.github.lsposed.lspd.sandhook.entry.SysBootstrapHookInfo; -import io.github.lsposed.lspd.sandhook.entry.SysInnerHookInfo; -import io.github.lsposed.lspd.sandhook.hooker.SystemMainHooker; -import io.github.lsposed.lspd.util.Utils; -import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; -import de.robv.android.xposed.XposedBridge; - public class SandHookRouter extends BaseRouter { public SandHookRouter() { } - private static boolean useSandHook = false; - - public void startBootstrapHook(boolean isSystem) { - if (useSandHook) { - Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); - ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER; - if (isSystem) { - XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems); - } else { - XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems); - } - } else { - super.startBootstrapHook(isSystem); - } - } - - public void startSystemServerHook() { - if (useSandHook) { - XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems); - } else { - super.startSystemServerHook(); - } - } - public void onEnterChildProcess() { SandHookXposedBridge.onForkPost(); //enable compile in child process diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/AppBootstrapHookInfo.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/AppBootstrapHookInfo.java deleted file mode 100644 index 768b425e..00000000 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/AppBootstrapHookInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package io.github.lsposed.lspd.sandhook.entry; - -import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd.sandhook.hooker.HandleBindAppHooker; -import io.github.lsposed.lspd.sandhook.hooker.LoadedApkConstructorHooker; - -public class AppBootstrapHookInfo implements KeepMembers { - public static String[] hookItemNames = { - HandleBindAppHooker.class.getName(), - LoadedApkConstructorHooker.class.getName(), - }; - - public static Class[] hookItems = { - HandleBindAppHooker.class, - LoadedApkConstructorHooker.class, - }; -} diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysBootstrapHookInfo.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysBootstrapHookInfo.java deleted file mode 100644 index f7644a13..00000000 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysBootstrapHookInfo.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package io.github.lsposed.lspd.sandhook.entry; - -import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd.sandhook.hooker.HandleBindAppHooker; -import io.github.lsposed.lspd.sandhook.hooker.LoadedApkConstructorHooker; -import io.github.lsposed.lspd.sandhook.hooker.SystemMainHooker; - -public class SysBootstrapHookInfo implements KeepMembers { - public static String[] hookItemNames = { - HandleBindAppHooker.class.getName(), - SystemMainHooker.class.getName(), - LoadedApkConstructorHooker.class.getName() - }; - - public static Class[] hookItems = { - HandleBindAppHooker.class, - SystemMainHooker.class, - LoadedApkConstructorHooker.class, - }; -} diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysInnerHookInfo.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysInnerHookInfo.java deleted file mode 100644 index 409050ac..00000000 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/entry/SysInnerHookInfo.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package io.github.lsposed.lspd.sandhook.entry; - -import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd.sandhook.hooker.StartBootstrapServicesHooker; -import io.github.lsposed.lspd.sandhook.hooker.StartBootstrapServicesHooker11; -import io.github.lsposed.lspd.util.Versions; - -public class SysInnerHookInfo implements KeepMembers { - - public static Class getSysInnerHookerClass() { - return Versions.hasR() ? - StartBootstrapServicesHooker11.class : - StartBootstrapServicesHooker.class; - } - - public static String[] hookItemNames = { - getSysInnerHookerClass().getName() - }; - - public static Class[] hookItems = { - getSysInnerHookerClass() - }; -} diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/HandleBindAppHooker.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/HandleBindAppHooker.java deleted file mode 100644 index d01eb6af..00000000 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/HandleBindAppHooker.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of LSPosed. - * - * LSPosed is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LSPosed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LSPosed. If not, see . - * - * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors - */ - -package io.github.lsposed.lspd.sandhook.hooker; - -import android.app.ActivityThread; - -import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd._hooker.impl.HandleBindApp; -import com.swift.sandhook.SandHook; -import com.swift.sandhook.annotation.HookClass; -import com.swift.sandhook.annotation.HookMethod; -import com.swift.sandhook.annotation.HookMethodBackup; -import com.swift.sandhook.annotation.Param; -import com.swift.sandhook.annotation.SkipParamCheck; -import com.swift.sandhook.annotation.ThisObject; - -import java.lang.reflect.Method; - -import de.robv.android.xposed.XC_MethodHook; -import de.robv.android.xposed.annotation.ApiSensitive; -import de.robv.android.xposed.annotation.Level; - -@ApiSensitive(Level.LOW) -@HookClass(ActivityThread.class) -public class HandleBindAppHooker implements KeepMembers { - - public static String className = "android.app.ActivityThread"; - public static String methodName = "handleBindApplication"; - public static String methodSig = "(Landroid/app/ActivityThread$AppBindData;)V"; - - @HookMethodBackup("handleBindApplication") - @SkipParamCheck - static Method backup; - - @HookMethod("handleBindApplication") - public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.ActivityThread$AppBindData") Object bindData) throws Throwable { - final XC_MethodHook methodHook = new HandleBindApp(); - final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); - param.thisObject = thiz; - param.args = new Object[]{bindData}; - methodHook.callBeforeHookedMethod(param); - if (!param.returnEarly) { - backup(thiz, bindData); - } - methodHook.callAfterHookedMethod(param); - } - - public static void backup(Object thiz, Object bindData) throws Throwable { - SandHook.callOriginByBackup(backup, thiz, bindData); - } -} \ No newline at end of file diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/LoadedApkConstructorHooker.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/LoadedApkConstructorHooker.java index 892b2d53..2656b6e9 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/LoadedApkConstructorHooker.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/LoadedApkConstructorHooker.java @@ -26,7 +26,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd._hooker.impl.LoadedApkCstr; +import io.github.lsposed.lspd.hooker.LoadedApkCstrHooker; import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; @@ -59,7 +59,7 @@ public class LoadedApkConstructorHooker implements KeepMembers { ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) throws Throwable { - final XC_MethodHook methodHook = new LoadedApkCstr(); + final XC_MethodHook methodHook = new LoadedApkCstrHooker(); final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); param.thisObject = thiz; param.args = new Object[]{activityThread, aInfo, compatInfo, baseLoader, securityViolation, diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker.java index 8de96bcc..dab2027e 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker.java @@ -21,7 +21,7 @@ package io.github.lsposed.lspd.sandhook.hooker; import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd._hooker.impl.StartBootstrapServices; + import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; @@ -45,7 +45,7 @@ public class StartBootstrapServicesHooker implements KeepMembers { @HookMethod("startBootstrapServices") public static void hook(@ThisObject Object systemServer) throws Throwable { - final XC_MethodHook methodHook = new StartBootstrapServices(); + final XC_MethodHook methodHook = new io.github.lsposed.lspd.hooker.StartBootstrapServicesHooker(); final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); param.thisObject = systemServer; param.args = new Object[]{}; diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker11.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker11.java index 3301edaa..a3ea0275 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker11.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/StartBootstrapServicesHooker11.java @@ -21,7 +21,7 @@ package io.github.lsposed.lspd.sandhook.hooker; import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd._hooker.impl.StartBootstrapServices; +import io.github.lsposed.lspd.hooker.StartBootstrapServicesHooker; import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; @@ -49,7 +49,7 @@ public class StartBootstrapServicesHooker11 implements KeepMembers { @HookMethod("startBootstrapServices") public static void hook(@ThisObject Object systemServer, @Param("com.android.server.utils.TimingsTraceAndSlog") Object traceAndSlog) throws Throwable { - final XC_MethodHook methodHook = new StartBootstrapServices(); + final XC_MethodHook methodHook = new StartBootstrapServicesHooker(); final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); param.thisObject = systemServer; param.args = new Object[]{traceAndSlog}; diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/SystemMainHooker.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/SystemMainHooker.java index 75068866..cc79775a 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/SystemMainHooker.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/hooker/SystemMainHooker.java @@ -23,7 +23,7 @@ package io.github.lsposed.lspd.sandhook.hooker; import android.app.ActivityThread; import io.github.lsposed.common.KeepMembers; -import io.github.lsposed.lspd._hooker.impl.SystemMain; + import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; @@ -53,7 +53,7 @@ public class SystemMainHooker implements KeepMembers { @HookMethod("systemMain") public static ActivityThread hook() throws Throwable { - final XC_MethodHook methodHook = new SystemMain(); + final XC_MethodHook methodHook = new io.github.lsposed.lspd.hooker.SystemMainHooker(); final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); param.thisObject = null; param.args = new Object[]{}; diff --git a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java index 1e2f60ae..17ba73d9 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java @@ -29,7 +29,6 @@ import static io.github.lsposed.lspd.service.ServiceManager.TAG; // This config manager assume uid won't change when our service is off. // Otherwise, user should maintain it manually. -// TODO: manager package name supports public class ConfigManager { static ConfigManager instance = null; @@ -52,6 +51,9 @@ public class ConfigManager { private String manager = null; private int managerUid = -1; + final private File miscFile = new File(basePath, "misc_path"); + private String miscPath = null; + final private File selinuxPath = new File("/sys/fs/selinux/enforce"); // only check on boot final private boolean isPermissive; @@ -69,7 +71,7 @@ public class ConfigManager { }; private String readText(@NonNull File file) throws IOException { - return new String(Files.readAllBytes(file.toPath())); + return new String(Files.readAllBytes(file.toPath())).trim(); } private String readText(@NonNull File file, String defaultValue) { @@ -108,6 +110,7 @@ public class ConfigManager { resourceHook = resourceHookSwitch.exists(); variant = readInt(variantSwitch, -1); verboseLog = readInt(verboseLogSwitch, 0) == 1; + miscPath = "/data/misc/" + readText(miscFile, "lspd"); updateManager(); } @@ -333,4 +336,12 @@ public class ConfigManager { public boolean isManager(int uid) { return uid == managerUid; } + + public String getCachePath(String fileName) { + return miscPath + File.separator + "cache" + File.separator + fileName; + } + + public String getPrefsPath(String fileName) { + return miscPath + File.separator + "prefs" + File.separator + fileName; + } } diff --git a/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java b/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java index 0542a846..ce6f9997 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java @@ -6,6 +6,7 @@ import android.os.RemoteException; import android.util.Log; import android.util.Pair; +import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -35,6 +36,30 @@ public class LSPApplicationService extends ILSPApplicationService.Stub { return ConfigManager.getInstance().variant(); } + @Override + public boolean isResourcesHookEnabled() throws RemoteException { + ensureRegistered(); + return ConfigManager.getInstance().resourceHook(); + } + + @Override + public List getModulesList() throws RemoteException { + ensureRegistered(); + return ConfigManager.getInstance().getModulesPathForUid(Binder.getCallingUid()); + } + + @Override + public String getPrefsPath(String packageName) throws RemoteException { + ensureRegistered(); + return ConfigManager.getInstance().getPrefsPath(packageName); + } + + @Override + public String getCachePath(String fileName) throws RemoteException { + ensureRegistered(); + return ConfigManager.getInstance().getCachePath(fileName); + } + // TODO: check if module @Override public IBinder requestModuleBinder() throws RemoteException { @@ -42,7 +67,6 @@ public class LSPApplicationService extends ILSPApplicationService.Stub { return ServiceManager.getModuleService(); } - // TODO: check if manager @Override public IBinder requestManagerBinder() throws RemoteException { ensureRegistered(); diff --git a/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java b/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java index 418a4af9..0c2cc835 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java @@ -36,7 +36,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.widget.Toast; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.Utils; import java.io.File; @@ -78,63 +77,65 @@ public class PackageReceiver { private Map loadEnabledModules(int uid) { HashMap result = new HashMap<>(); - try { - File enabledModules = new File(ConfigManager.getMiscPath(), uid + "/" + ENABLED_MODULES_LIST_FILENAME); - if (!enabledModules.exists()) return result; - Scanner scanner = new Scanner(enabledModules); - while (scanner.hasNextLine()) { - String packageName = scanner.nextLine(); - PackageInfo info = getPackageInfo(packageName, 0); - if (info != null && isXposedModule(info.applicationInfo)) - result.put(packageName, info.applicationInfo.sourceDir); - else if (info == null) - result.put(packageName, null); - } - } catch (Throwable e) { - Utils.logE("Unable to read enabled modules", e); - } + // TODO: FIXME +// try { +// File enabledModules = new File(ConfigManager.getMiscPath(), uid + "/" + ENABLED_MODULES_LIST_FILENAME); +// if (!enabledModules.exists()) return result; +// Scanner scanner = new Scanner(enabledModules); +// while (scanner.hasNextLine()) { +// String packageName = scanner.nextLine(); +// PackageInfo info = getPackageInfo(packageName, 0); +// if (info != null && isXposedModule(info.applicationInfo)) +// result.put(packageName, info.applicationInfo.sourceDir); +// else if (info == null) +// result.put(packageName, null); +// } +// } catch (Throwable e) { +// Utils.logE("Unable to read enabled modules", e); +// } return result; } private boolean updateModuleList(int uid, String packageName) { Map enabledModules = loadEnabledModules(uid); - - if (!enabledModules.containsKey(packageName)) return false; - - try { - File moduleListFile = new File(ConfigManager.getMiscPath(), uid + "/" + MODULES_LIST_FILENAME); - File enabledModuleListFile = new File(ConfigManager.getMiscPath(), uid + "/" + ENABLED_MODULES_LIST_FILENAME); - if (moduleListFile.exists() && !moduleListFile.canWrite()) { - moduleListFile.delete(); - moduleListFile.createNewFile(); - } - if (enabledModuleListFile.exists() && !enabledModuleListFile.canWrite()) { - enabledModuleListFile.delete(); - enabledModuleListFile.createNewFile(); - } - PrintWriter modulesList = new PrintWriter(moduleListFile); - PrintWriter enabledModulesList = new PrintWriter(enabledModuleListFile); - for (Map.Entry module : enabledModules.entrySet()) { - String apkPath = module.getValue(); - if (apkPath != null) { - modulesList.println(module.getValue()); - enabledModulesList.println(module.getKey()); - } else { - Utils.logI(String.format("remove obsolete package %s", packageName)); - File prefsDir = new File(ConfigManager.getMiscPath(), uid + "/prefs/" + packageName); - File[] fileList = prefsDir.listFiles(); - if (fileList != null) { - for (File childFile : fileList) { - childFile.delete(); - } - } - } - } - modulesList.close(); - enabledModulesList.close(); - } catch (Throwable e) { - Utils.logE("Fail to update module list", e); - } + // TODO: FIXME +// +// if (!enabledModules.containsKey(packageName)) return false; +// +// try { +// File moduleListFile = new File(ConfigManager.getMiscPath(), uid + "/" + MODULES_LIST_FILENAME); +// File enabledModuleListFile = new File(ConfigManager.getMiscPath(), uid + "/" + ENABLED_MODULES_LIST_FILENAME); +// if (moduleListFile.exists() && !moduleListFile.canWrite()) { +// moduleListFile.delete(); +// moduleListFile.createNewFile(); +// } +// if (enabledModuleListFile.exists() && !enabledModuleListFile.canWrite()) { +// enabledModuleListFile.delete(); +// enabledModuleListFile.createNewFile(); +// } +// PrintWriter modulesList = new PrintWriter(moduleListFile); +// PrintWriter enabledModulesList = new PrintWriter(enabledModuleListFile); +// for (Map.Entry module : enabledModules.entrySet()) { +// String apkPath = module.getValue(); +// if (apkPath != null) { +// modulesList.println(module.getValue()); +// enabledModulesList.println(module.getKey()); +// } else { +// Utils.logI(String.format("remove obsolete package %s", packageName)); +// File prefsDir = new File(ConfigManager.getMiscPath(), uid + "/prefs/" + packageName); +// File[] fileList = prefsDir.listFiles(); +// if (fileList != null) { +// for (File childFile : fileList) { +// childFile.delete(); +// } +// } +// } +// } +// modulesList.close(); +// enabledModulesList.close(); +// } catch (Throwable e) { +// Utils.logE("Fail to update module list", e); +// } return true; } @@ -168,36 +169,37 @@ public class PackageReceiver { PackageInfo pkgInfo = getPackageInfo(packageName, intent.getIntExtra(Intent.EXTRA_USER, 0)); if (pkgInfo != null && !isXposedModule(pkgInfo.applicationInfo)) return; - - try { - for (int uid : UserService.getUsers()) { - Utils.logI("updating uid: " + uid); - boolean activated = updateModuleList(uid, packageName); - UserHandle userHandle = null; - try { - userHandle = (UserHandle) XposedHelpers.callStaticMethod(UserHandle.class, "of", uid); - } catch (Throwable t) { - Utils.logW("get user handle failed", t); - } - if (userHandle != null) { - try { - Intent broadCast = new Intent(activated ? MODULE_UPDATED : MODULE_NOT_ACTIVATAED); - broadCast.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | 0x01000000); - broadCast.setData(intent.getData()); - broadCast.setPackage(ConfigManager.getInstallerPackageName()); - XposedHelpers.callMethod(context, "sendBroadcastAsUser", broadCast, userHandle); - Utils.logI("broadcast to " + ConfigManager.getInstallerPackageName()); - } catch (Throwable t) { - Utils.logW("send broadcast failed", t); - Toast.makeText(context, "LSPosed: Updated " + packageName, Toast.LENGTH_SHORT).show(); - } - } else if (activated) { - Toast.makeText(context, "LSPosed: Updated " + packageName, Toast.LENGTH_SHORT).show(); - } - } - } catch (Throwable e) { - Utils.logW("update failed", e); - } + // TODO: FIXME +// +// try { +// for (int uid : UserService.getUsers()) { +// Utils.logI("updating uid: " + uid); +// boolean activated = updateModuleList(uid, packageName); +// UserHandle userHandle = null; +// try { +// userHandle = (UserHandle) XposedHelpers.callStaticMethod(UserHandle.class, "of", uid); +// } catch (Throwable t) { +// Utils.logW("get user handle failed", t); +// } +// if (userHandle != null) { +// try { +// Intent broadCast = new Intent(activated ? MODULE_UPDATED : MODULE_NOT_ACTIVATAED); +// broadCast.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | 0x01000000); +// broadCast.setData(intent.getData()); +// broadCast.setPackage(ConfigManager.getInstallerPackageName()); +// XposedHelpers.callMethod(context, "sendBroadcastAsUser", broadCast, userHandle); +// Utils.logI("broadcast to " + ConfigManager.getInstallerPackageName()); +// } catch (Throwable t) { +// Utils.logW("send broadcast failed", t); +// Toast.makeText(context, "LSPosed: Updated " + packageName, Toast.LENGTH_SHORT).show(); +// } +// } else if (activated) { +// Toast.makeText(context, "LSPosed: Updated " + packageName, Toast.LENGTH_SHORT).show(); +// } +// } +// } catch (Throwable e) { +// Utils.logW("update failed", e); +// } } }; diff --git a/core/src/main/java/io/github/lsposed/lspd/service/PackageService.java b/core/src/main/java/io/github/lsposed/lspd/service/PackageService.java index b1e54d61..5bf8cb2f 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/PackageService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/PackageService.java @@ -8,7 +8,6 @@ import android.os.ServiceManager; import java.util.ArrayList; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.utils.ParceledListSlice; public class PackageService { @@ -35,15 +34,6 @@ public class PackageService { return pm.getPackagesForUid(uid); } - public static boolean isInstaller(int uid) throws RemoteException { - boolean res = false; - String InstallerPackageName = ConfigManager.getInstallerPackageName(); - for (String pkg : getPackagesForUid(uid)) { - res = res || InstallerPackageName.equals(pkg); - } - return res; - } - public static ParceledListSlice getInstalledPackagesFromAllUsers(int flags) throws RemoteException { ArrayList res = new ArrayList<>(); IPackageManager pm = getPackageManager(); diff --git a/core/src/main/java/io/github/lsposed/lspd/util/FileUtils.java b/core/src/main/java/io/github/lsposed/lspd/util/FileUtils.java index e9e40b3e..5d280700 100644 --- a/core/src/main/java/io/github/lsposed/lspd/util/FileUtils.java +++ b/core/src/main/java/io/github/lsposed/lspd/util/FileUtils.java @@ -22,8 +22,6 @@ package io.github.lsposed.lspd.util; import android.text.TextUtils; -import io.github.lsposed.lspd.nativebridge.ConfigManager; - import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -90,8 +88,4 @@ public class FileUtils { } return dataDir.substring(lastIndex + 1); } - - public static String getDataPathPrefix() { - return ConfigManager.getDataPathPrefix() + "/"; - } } diff --git a/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/DexMakerUtils.java b/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/DexMakerUtils.java index d41e03ec..434a3a08 100644 --- a/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/DexMakerUtils.java +++ b/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/DexMakerUtils.java @@ -20,7 +20,6 @@ package io.github.lsposed.lspd.yahfa.dexmaker; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.Utils; import java.io.File; @@ -33,15 +32,17 @@ import external.com.android.dx.Code; import external.com.android.dx.Local; import external.com.android.dx.TypeId; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; + @SuppressWarnings({"rawtypes", "unchecked"}) public class DexMakerUtils { public static boolean canCache = true; static { - File cacheDir = new File(ConfigManager.getCachePath("")); + File cacheDir = new File(serviceClient.getCachePath("")); if(!cacheDir.canRead() || !cacheDir.canWrite()) { - Utils.logW("Cache disabled"); + Utils.logW("Cache disabled with path " + cacheDir.getAbsolutePath()); canCache = false; } } diff --git a/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/HookerDexMaker.java b/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/HookerDexMaker.java index 6a41e266..f45fc080 100644 --- a/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/HookerDexMaker.java +++ b/core/src/main/java/io/github/lsposed/lspd/yahfa/dexmaker/HookerDexMaker.java @@ -24,7 +24,6 @@ import android.annotation.TargetApi; import android.os.Build; import io.github.lsposed.lspd.BuildConfig; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.core.yahfa.HookMain; import io.github.lsposed.lspd.util.ProxyClassLoader; @@ -46,6 +45,7 @@ import external.com.android.dx.Local; import external.com.android.dx.MethodId; import external.com.android.dx.TypeId; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; import static io.github.lsposed.lspd.yahfa.dexmaker.DexMakerUtils.autoBoxIfNecessary; import static io.github.lsposed.lspd.yahfa.dexmaker.DexMakerUtils.autoUnboxIfNecessary; import static io.github.lsposed.lspd.yahfa.dexmaker.DexMakerUtils.canCache; @@ -167,17 +167,17 @@ public class HookerDexMaker { String suffix = DexMakerUtils.getSha1Hex(mMember.toString()); className = className + suffix; String dexFileName = className + ".jar"; - File dexFile = new File(ConfigManager.getCachePath(dexFileName)); + File dexFile = new File(serviceClient.getCachePath(dexFileName)); if (!dexFile.exists()) { // if file exists, reuse it and skip generating DexLog.d("Generating " + dexFileName); doGenerate(className); - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexFileName, false); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(serviceClient.getCachePath("")), dexFileName, false); dexFile.setWritable(true, false); dexFile.setReadable(true, false); } else { DexLog.d("Using cache " + dexFileName); - loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexFileName); + loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(serviceClient.getCachePath("")), dexFileName); } usedCache = true; } catch (Throwable ignored) {} diff --git a/core/src/main/java/io/swift/sandhook/xposedcompat/XposedCompat.java b/core/src/main/java/io/swift/sandhook/xposedcompat/XposedCompat.java index 62314de1..cec9d9c2 100644 --- a/core/src/main/java/io/swift/sandhook/xposedcompat/XposedCompat.java +++ b/core/src/main/java/io/swift/sandhook/xposedcompat/XposedCompat.java @@ -3,7 +3,6 @@ package com.swift.sandhook.xposedcompat; import android.os.Process; import android.text.TextUtils; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.FileUtils; import io.github.lsposed.lspd.util.ProcessUtils; import io.github.lsposed.lspd.util.ProxyClassLoader; @@ -16,8 +15,6 @@ import java.lang.reflect.Member; import de.robv.android.xposed.XposedBridge; -import static io.github.lsposed.lspd.util.FileUtils.getDataPathPrefix; - public class XposedCompat { // TODO initialize these variables @@ -49,11 +46,12 @@ public class XposedCompat { } public static File getCacheDir() { - if (cacheDir == null) { - String fixedAppDataDir = getDataPathPrefix() + getPackageName(ConfigManager.appDataDir) + "/"; - cacheDir = new File(fixedAppDataDir, "/cache/sandhook/" - + ProcessUtils.getProcessName(Process.myPid()).replace(":", "_") + "/"); - } + // TODO: cache path? +// if (cacheDir == null) { +// String fixedAppDataDir = getDataPathPrefix() + getPackageName(ConfigManager.appDataDir) + "/"; +// cacheDir = new File(fixedAppDataDir, "/cache/sandhook/" +// + ProcessUtils.getProcessName(Process.myPid()).replace(":", "_") + "/"); +// } return cacheDir; } diff --git a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java index edf03db9..3218e147 100644 --- a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java +++ b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java @@ -1,6 +1,5 @@ package com.swift.sandhook.xposedcompat.methodgen; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import com.swift.sandhook.SandHook; import com.swift.sandhook.SandHookMethodResolver; import com.swift.sandhook.wrapper.HookWrapper; @@ -34,6 +33,7 @@ import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.canCache; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getSha1Hex; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; public class HookerDexMaker implements HookMaker { @@ -187,7 +187,7 @@ public class HookerDexMaker implements HookMaker { HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(serviceClient.getCachePath("")), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -215,8 +215,8 @@ public class HookerDexMaker implements HookMaker { ClassLoader loader; if (canCache) { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName, true); - File dexFile = new File(ConfigManager.getCachePath(dexName)); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(serviceClient.getCachePath("")), dexName, true); + File dexFile = new File(serviceClient.getCachePath(dexName)); dexFile.setWritable(true, false); dexFile.setReadable(true, false); } else { diff --git a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java index 7e9ccf4b..22f94aa2 100644 --- a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java +++ b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java @@ -1,6 +1,5 @@ package com.swift.sandhook.xposedcompat.methodgen; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import com.swift.sandhook.SandHook; import com.swift.sandhook.wrapper.HookWrapper; import com.swift.sandhook.xposedcompat.hookstub.HookStubManager; @@ -30,6 +29,7 @@ import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.canCache; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getSha1Hex; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; public class HookerDexMakerNew implements HookMaker { @@ -148,7 +148,7 @@ public class HookerDexMakerNew implements HookMaker { HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(serviceClient.getCachePath("")), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -176,8 +176,8 @@ public class HookerDexMakerNew implements HookMaker { } // Create the dex file and load it. try { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName, true); - File dexFile = new File(ConfigManager.getCachePath(dexName)); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(serviceClient.getCachePath("")), dexName, true); + File dexFile = new File(serviceClient.getCachePath(dexName)); dexFile.setWritable(true, false); dexFile.setReadable(true, false); } catch (IOException e) { diff --git a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java index 66c38131..fa1ffa1f 100644 --- a/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java +++ b/core/src/main/java/io/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java @@ -4,7 +4,6 @@ import android.os.Build; import android.os.Process; import android.os.Trace; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.nativebridge.Yahfa; import io.github.lsposed.lspd.util.ClassLoaderUtils; import io.github.lsposed.lspd.util.FileUtils; diff --git a/core/src/main/java/io/swift/sandhook/xposedcompat/utils/DexMakerUtils.java b/core/src/main/java/io/swift/sandhook/xposedcompat/utils/DexMakerUtils.java index 8f2adcbe..b4ec8dc0 100644 --- a/core/src/main/java/io/swift/sandhook/xposedcompat/utils/DexMakerUtils.java +++ b/core/src/main/java/io/swift/sandhook/xposedcompat/utils/DexMakerUtils.java @@ -1,5 +1,4 @@ package com.swift.sandhook.xposedcompat.utils; -import io.github.lsposed.lspd.nativebridge.ConfigManager; import io.github.lsposed.lspd.util.Utils; import java.io.File; @@ -15,12 +14,14 @@ import external.com.android.dx.Code; import external.com.android.dx.Local; import external.com.android.dx.TypeId; +import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; + public class DexMakerUtils { public static boolean canCache = true; static { - File cacheDir = new File(ConfigManager.getCachePath("")); + File cacheDir = new File(serviceClient.getCachePath("")); if(!cacheDir.canRead() || !cacheDir.canWrite()) { Utils.logW("Cache disabled"); canCache = false; diff --git a/core/template_override/customize.sh b/core/template_override/customize.sh index d26836c6..1259c725 100644 --- a/core/template_override/customize.sh +++ b/core/template_override/customize.sh @@ -223,6 +223,10 @@ else fi fi touch /data/adb/lspd/new_install || abortC "! ${LANG_CUST_ERR_CONF_FIRST}" +ui_print "- ${LANG_CUST_INST_COPY_LIB}" +mkdir -p /data/adb/lspd/config +rm -rf "/data/adb/lspd/framework" +mv "${MODPATH}/system/framework" "/data/adb/lspd/framework" set_perm_recursive /data/adb/lspd root root 0700 0600 "u:object_r:magisk_file:s0" || abortC "! ${LANG_CUST_ERR_PERM}" mkdir -p /data/misc/$MISC_PATH/0/conf/ || abortC "! ${LANG_CUST_ERR_CONF_CREATE}" set_perm /data/misc/$MISC_PATH root root 0771 "u:object_r:magisk_file:s0" || abortC "! ${LANG_CUST_ERR_PERM}" @@ -230,9 +234,9 @@ echo "rm -rf /data/misc/$MISC_PATH" >> "${MODPATH}/uninstall.sh" || abortC "! ${ echo "[[ -f /data/adb/lspd/new_install ]] || rm -rf /data/adb/lspd" >> "${MODPATH}/uninstall.sh" || abortC "! ${LANG_CUST_ERR_CONF_UNINST}" if [ $VARIANT == 17 ]; then # YAHFA - echo "1" > /data/misc/$MISC_PATH/variant + echo "1" > /data/adb/lspd/config/variant elif [ $VARIANT == 18 ]; then # SandHook - echo "2" > /data/misc/$MISC_PATH/variant + echo "2" > /data/adb/lspd/config/variant else abortC "${LANG_UTIL_ERR_VARIANT_UNSUPPORT} ${VARIANT}" fi @@ -241,12 +245,6 @@ if [[ ! -e /data/misc/$MISC_PATH/disable_verbose_log ]]; then echo "1" > /data/misc/$MISC_PATH/disable_verbose_log fi -ui_print "- ${LANG_CUST_INST_COPY_LIB}" - -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" || abortC "! ${LANG_CUST_ERR_PERM}" mkdir -p /data/misc/$MISC_PATH/cache rm /data/misc/$MISC_PATH/cache/* diff --git a/core/template_override/service.sh b/core/template_override/service.sh index f2b03e3a..d80fdb74 100644 --- a/core/template_override/service.sh +++ b/core/template_override/service.sh @@ -27,7 +27,4 @@ if [[ -f "${MODDIR}/reboot_twice_flag" ]]; then reboot fi -MISC_PATH=$(cat /data/adb/lspd/misc_path) -BASE_PATH="/data/misc/$MISC_PATH" - -/system/bin/app_process -Djava.class.path=${BASE_PATH}/framework/lspd.dex /system/bin --nice-name=lspd io.github.lsposed.lspd.core.Main +/system/bin/app_process -Djava.class.path=/data/adb/lspd/framework/lspd.dex /system/bin --nice-name=lspd io.github.lsposed.lspd.core.Main