Move dex/jar to /data/misc

This commit is contained in:
LoveSy 2020-12-03 01:49:02 +08:00 committed by solohsu
parent b585d722c8
commit 993ba29616
7 changed files with 124 additions and 93 deletions

View File

@ -29,10 +29,6 @@ inline constexpr bool is64 = Is64();
# define LP_SELECT(lp32, lp64) (lp32)
#endif
static const auto kInjectDexPath = "/system/framework/edxp.dex:"
"/system/framework/eddalvikdx.dex:"
"/system/framework/eddexmaker.dex"_str;
static const auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main"_str;
static const auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
static const auto kSandHookClassName = "com.swift.sandhook.SandHook"_str;

View File

@ -22,23 +22,26 @@ namespace edxp {
return {str, size};
}
inline bool path_exists(const std::filesystem::path &path, bool quite = false) {
template<bool quite = false>
inline bool path_exists(const std::filesystem::path &path) {
try {
return std::filesystem::exists(path);
} catch (const std::filesystem::filesystem_error &e) {
if (!quite)
if constexpr(!quite) {
LOGE("%s", e.what());
}
return false;
}
}
inline void path_chown(const std::filesystem::path &path, uid_t uid, gid_t gid, bool recursively=false) {
inline void
path_chown(const std::filesystem::path &path, uid_t uid, gid_t gid, bool recursively = false) {
if (chown(path.c_str(), uid, gid) != 0) {
throw std::filesystem::filesystem_error(strerror(errno), path,
{errno, std::system_category()});
{errno, std::system_category()});
}
if(recursively) {
for(const auto &item : std::filesystem::recursive_directory_iterator(path)) {
if (recursively) {
for (const auto &item : std::filesystem::recursive_directory_iterator(path)) {
if (chown(item.path().c_str(), uid, gid) != 0) {
throw std::filesystem::filesystem_error(strerror(errno), item.path(),
{errno, std::system_category()});
@ -47,7 +50,7 @@ namespace edxp {
}
}
inline std::tuple<uid_t, gid_t> path_own(const std::filesystem::path& path) {
inline std::tuple<uid_t, gid_t> path_own(const std::filesystem::path &path) {
struct stat sb;
stat(path.c_str(), &sb);
return {sb.st_uid, sb.st_gid};

View File

@ -85,23 +85,16 @@ namespace edxp {
namespace fs = std::filesystem;
fs::path ConfigManager::RetrieveBaseConfigPath() const {
fs::path misc_path("/data/adb/edxp/misc_path");
try {
RirudSocket rirud_socket{};
auto path = rirud_socket.ReadFile(misc_path);
path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), path.end());
return fs::path("/data/misc") / path / std::to_string(user_);
} catch (const RirudSocket::RirudSocketException &e) {
LOGE("%s", e.what());
if (auto misc_path = GetMiscPath(); !misc_path.empty()) {
return misc_path / std::to_string(user_);
} else {
return {};
}
}
std::string ConfigManager::RetrieveInstallerPkgName() const {
std::string installer_pkg_name_path = GetConfigPath("installer");
if (!path_exists(installer_pkg_name_path, true)) {
if (!path_exists<true>(installer_pkg_name_path)) {
LOGW("installer not set, using default one %s", kPrimaryInstallerPkgName.c_str());
return kPrimaryInstallerPkgName;
}
@ -217,7 +210,7 @@ namespace edxp {
auto &[module_path, scope] = modules_list[module_pkg_name];
module_path.assign(std::move(module));
const auto &module_scope_conf = GetConfigPath(module_pkg_name + ".conf");
if (!path_exists(module_scope_conf, true)) {
if (!path_exists<true>(module_scope_conf)) {
LOGD("module scope is not set for %s", module_pkg_name.c_str());
continue;
}
@ -253,7 +246,7 @@ namespace edxp {
std::filesystem::file_time_type ConfigManager::GetLastWriteTime() const {
auto modules_list = GetConfigPath("modules.list");
if (!path_exists(modules_list, true))
if (!path_exists<true>(modules_list))
return {};
return fs::last_write_time(modules_list);
}
@ -262,7 +255,7 @@ namespace edxp {
if (base_config_path_.empty()) return false;
try {
fs::create_directories(base_config_path_);
fs::permissions(base_config_path_.parent_path(),
fs::permissions(GetMiscPath(),
fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec);
fs::permissions(base_config_path_,
fs::perms::owner_all | fs::perms::group_all | fs::perms::others_exec);
@ -286,7 +279,7 @@ namespace edxp {
try {
if (modules_list_.count(pkg_name)) {
auto prefs_path = GetPrefsPath(pkg_name);
if (!path_exists(prefs_path, true)) {
if (!path_exists<true>(prefs_path)) {
fs::create_directories(prefs_path);
} else {
const auto &[r_uid, r_gid] = path_own(prefs_path);
@ -301,11 +294,11 @@ namespace edxp {
}
if (pkg_name == installer_pkg_name_) {
auto conf_path = GetConfigPath();
if (!path_exists(conf_path, true)) {
if (!path_exists<true>(conf_path)) {
fs::create_directories(conf_path);
}
auto log_path = GetLogPath();
if (!path_exists(log_path, true)) {
if (!path_exists<true>(log_path)) {
fs::create_directories(log_path);
}
fs::permissions(conf_path, fs::perms::owner_all | fs::perms::group_all);
@ -322,4 +315,32 @@ namespace edxp {
}
}
auto ConfigManager::GetMiscPath() -> decltype(misc_path_) {
if (misc_path_.empty()) {
fs::path misc_path("/data/adb/edxp/misc_path");
try {
RirudSocket rirud_socket{};
auto path = rirud_socket.ReadFile(misc_path);
path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), path.end());
misc_path_ = fs::path("/data/misc") / path;
} catch (const RirudSocket::RirudSocketException &e) {
LOGE("%s", e.what());
}
}
return misc_path_;
}
auto ConfigManager::GetInjectDexPaths() -> decltype(inject_dex_paths_) {
if (inject_dex_paths_.empty()) {
std::transform(kXposedInjectDexPath.begin(), kXposedInjectDexPath.end(),
std::back_inserter(inject_dex_paths_),
[](auto i) {
return GetFrameworkPath(i);
});
}
return inject_dex_paths_;
}
}

View File

@ -14,10 +14,17 @@
namespace edxp {
static const std::string kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager";
static const std::string kXposedPropPath = "/system/framework/edconfig.jar";
class ConfigManager {
private:
inline static const auto kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager"_str;
inline static const auto kXposedPropName = "edconfig.jar"_str;
inline static const std::vector<std::string> kXposedInjectDexPath = {
"edxp.dex",
"eddalvikdx.dex",
"eddexmaker.dex",
};
public:
inline static ConfigManager *GetInstance() {
return instances_[current_user].get();
@ -25,7 +32,8 @@ namespace edxp {
inline static void SetCurrentUser(uid_t user) {
if (auto instance = instances_.find(user);
instance == instances_.end() || !instance->second || instance->second->NeedUpdateConfig()) {
instance == instances_.end() || !instance->second ||
instance->second->NeedUpdateConfig()) {
instances_[user] = std::make_unique<ConfigManager>(user);
}
}
@ -34,6 +42,8 @@ namespace edxp {
return std::move(instances_);
}
inline auto IsInitialized() const { return initialized_; }
// Always true now
inline auto IsBlackWhiteListEnabled() const { return true; }
@ -45,12 +55,16 @@ namespace edxp {
inline auto GetInstallerPackageName() const { return installer_pkg_name_; }
inline auto GetXposedPropPath() const { return kXposedPropPath; }
inline auto GetLibSandHookName() const { return kLibSandHookName; }
inline auto GetDataPathPrefix() const { return data_path_prefix_; }
inline static auto GetFrameworkPath(const std::string &suffix = {}) {
return GetMiscPath() / "framework" / suffix;
}
inline auto GetXposedPropPath() const { return GetFrameworkPath(kXposedPropName); }
inline auto GetConfigPath(const std::string &suffix = {}) const {
return base_config_path_ / "conf" / suffix;
}
@ -75,11 +89,16 @@ namespace edxp {
void EnsurePermission(const std::string &pkg_name, uid_t uid) const;
private:
inline static std::unordered_map<uid_t, std::unique_ptr<ConfigManager>> instances_{};
inline static uid_t current_user = 0u;
inline static std::filesystem::path misc_path_;
inline static std::vector<std::filesystem::path> inject_dex_paths_;
inline static const bool use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__;
static decltype(misc_path_) GetMiscPath();
const uid_t user_;
const std::filesystem::path data_path_prefix_;
const std::filesystem::path base_config_path_;
@ -114,6 +133,9 @@ namespace edxp {
friend std::unique_ptr<ConfigManager> std::make_unique<ConfigManager>(uid_t &);
std::filesystem::path RetrieveBaseConfigPath() const;
public:
static decltype(inject_dex_paths_) GetInjectDexPaths();
};
} // namespace edxp

View File

@ -58,17 +58,8 @@ namespace edxp {
CallPostFixupStaticTrampolinesCallback(class_ptr, post_fixup_static_mid_);
}
void Context::PreLoadDex(JNIEnv *env, const std::string &dex_path) {
if (LIKELY(!dexes.empty())) return;
std::vector<std::string> paths;
{
std::istringstream is(dex_path);
std::string path;
while (std::getline(is, path, ':')) {
paths.emplace_back(std::move(path));
}
}
for (const auto &path: paths) {
void Context::PreLoadDex(const std::vector<fs::path> &dex_paths) {
for (const auto &path: dex_paths) {
std::ifstream is(path, std::ios::binary);
if (!is.good()) {
LOGE("Cannot load path %s", path.c_str());
@ -234,15 +225,20 @@ namespace edxp {
app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList(
"android"); // I don't think we need this, but anyway
skip_ = false;
if (!ConfigManager::GetInstance()->IsAppNeedHook("android")) {
if (!ConfigManager::GetInstance()->IsInitialized()) {
LOGE("skip injecting into android because configurations are not loaded properly");
}
if (skip_ && !ConfigManager::GetInstance()->IsAppNeedHook("android")) {
skip_ = true;
LOGW("skip injecting xposed into android because it's whitelisted/blacklisted");
LOGW("skip injecting into android because it's whitelisted/blacklisted");
}
if (!skip_ && app_modules_list_.empty()) {
skip_ = true;
LOGW("skip injecting into android because no module hooks it");
}
PreLoadDex(env, kInjectDexPath);
if(!skip_) {
PreLoadDex(ConfigManager::GetInjectDexPaths());
}
}
@ -278,10 +274,11 @@ namespace edxp {
}
std::tuple<bool, uid_t, std::string>
Context::GetAppInfoFromDir(JNIEnv *env, jstring dir) {
Context::GetAppInfoFromDir(JNIEnv *env, jstring dir, jstring nice_name) {
uid_t uid = 0;
JUTFString app_data_dir(env, dir);
if (!app_data_dir) return {false, 0, {}};
JUTFString name(env, nice_name);
if (!app_data_dir) return {false, 0, name.get()};
fs::path path(app_data_dir.get());
std::vector<std::string> splits(path.begin(), path.end());
if (splits.size() < 5u) {
@ -304,7 +301,11 @@ namespace edxp {
bool is_child_zygote) {
const auto app_id = uid % PER_USER_RANGE;
bool skip = false;
if (!info_res) {
if (!ConfigManager::GetInstance()->IsInitialized()) {
LOGE("skip injecting into %s because configurations are not loaded properly", package_name.c_str());
skip = true;
}
if (!skip && !info_res) {
LOGW("skip injecting into %s because it has no data dir", package_name.c_str());
skip = true;
}
@ -349,14 +350,16 @@ namespace edxp {
jboolean is_child_zygote,
jstring instruction_set,
jstring app_data_dir) {
const auto&[res, user, package_name] = GetAppInfoFromDir(env, app_data_dir);
ConfigManager::SetCurrentUser(user);
app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList(package_name);
skip_ = ShouldSkipInject(package_name, user, uid, res, app_modules_list_, is_child_zygote);
ConfigManager::GetInstance()->EnsurePermission(package_name, uid % PER_USER_RANGE);
const auto&[res, user, package_name] = GetAppInfoFromDir(env, app_data_dir, nice_name);
app_data_dir_ = app_data_dir;
nice_name_ = nice_name;
PreLoadDex(env, kInjectDexPath);
ConfigManager::SetCurrentUser(user);
skip_ = ShouldSkipInject(package_name, user, uid, res, app_modules_list_, is_child_zygote);
if(!skip_) {
app_modules_list_ = ConfigManager::GetInstance()->GetAppModuleList(package_name);
ConfigManager::GetInstance()->EnsurePermission(package_name, uid % PER_USER_RANGE);
PreLoadDex(ConfigManager::GetInjectDexPaths());
}
}
int

View File

@ -10,7 +10,6 @@
#include "utils.h"
namespace edxp {
static const auto SYSTEM_SERVER_DATA_DIR = "/data/user/0/android"_str;
enum Variant {
NONE = 0,
YAHFA = 1,
@ -99,7 +98,7 @@ namespace edxp {
Context() {}
void PreLoadDex(JNIEnv *env, const std::string &dex_path);
void PreLoadDex(const std::vector<std::filesystem::path> &dex_path);
void InjectDexAndInit(JNIEnv *env);
@ -118,7 +117,7 @@ namespace edxp {
const std::vector<std::string> &app_module_list,
bool is_child_zygote);
static std::tuple<bool, uid_t, std::string> GetAppInfoFromDir(JNIEnv *env, jstring dir);
static std::tuple<bool, uid_t, std::string> GetAppInfoFromDir(JNIEnv *env, jstring dir, jstring nice_name);
friend std::unique_ptr<Context> std::make_unique<Context>();
};

View File

@ -36,18 +36,6 @@ PROP_PRODUCT=$(getprop ro.build.product)
PROP_BRAND=$(getprop ro.product.brand)
PROP_MANUFACTURER=$(getprop ro.product.manufacturer)
JAR_EDXP="$(getRandomNameExist 8 "" ".dex" "
/system/framework
").dex"
JAR_EDDALVIKDX="$(getRandomNameExist 8 "" ".dex" "
/system/framework
").dex"
JAR_EDDEXMAKER="$(getRandomNameExist 8 "" ".dex" "
/system/framework
").dex"
#JAR_EDCONFIG="$(getRandomNameExist 8 "" ".jar" "
#/system/framework
#").jar"
LIB_RIRU_EDXP="libriru_${RIRU_EDXP}.so"
LIB_SANDHOOK_EDXP="lib$(getRandomNameExist 13 "lib" ".so" "
/system/lib
@ -287,14 +275,30 @@ if [[ "${OLD_MAGISK}" == true ]]; then
rm "${MODPATH}"/sepolicy.rule
fi
ui_print "- Creating configuration directories"
if [[ -f /data/adb/edxp/misc_path ]]; then
MISC_PATH=$(cat /data/adb/edxp/misc_path)
ui_print "- Use previous path $MISC_PATH"
else
MISC_PATH="edxp_$(tr -cd 'A-Za-z0-9' < /dev/urandom | head -c16)"
ui_print "- Use new path $MISC_PATH"
mkdir -p /data/adb/edxp || abort "! Can't create adb path"
echo "$MISC_PATH" > /data/adb/edxp/misc_path || abort "! Can't store configuration path"
fi
set_perm_recursive /data/adb/edxp root root 0700 0600 "u:object_r:magisk_file:s0" || abort "! Can't set permission"
mkdir -p /data/misc/$MISC_PATH || abort "! Can't create configuration path"
set_perm /data/misc/$MISC_PATH root root 0771 "u:object_r:magisk_file:s0" || abort "! Can't set permission"
echo "rm -rf /data/misc/$MISC_PATH" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh"
echo "rm -rf /data/adb/edxp" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh"
ui_print "- Copying framework libraries"
mv "${MODPATH}/system/framework/eddalvikdx.dex" "${MODPATH}/system/framework/${JAR_EDDALVIKDX}"
mv "${MODPATH}/system/framework/edxp.dex" "${MODPATH}/system/framework/${JAR_EDXP}"
mv "${MODPATH}/system/framework/eddexmaker.dex" "${MODPATH}/system/framework/${JAR_EDDEXMAKER}"
#mv "${MODPATH}/system/framework/edconfig.jar" "${MODPATH}/system/framework/${JAR_EDCONFIG}"
mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
rm -rf "/data/misc/$MISC_PATH/framework"
mv "${MODPATH}/system/framework" "/data/misc/$MISC_PATH/framework"
set_perm_recursive /data/misc/$MISC_PATH/framework root root 0755 0644 "u:object_r:magisk_file:s0" || abort "! Can't set permission"
mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
if [[ "${IS64BIT}" == true ]]; then
mv "${MODPATH}/system/lib64/libriru_edxp.so" "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
fi
@ -352,23 +356,6 @@ rm "${RIRU_TARGET}/module.prop"
cp "${MODPATH}/module.prop" "${RIRU_TARGET}/module.prop" || abort "! Can't create ${RIRU_TARGET}/module.prop"
set_perm_recursive "${MODPATH}" 0 0 0755 0644
ui_print "- Creating configuration directories"
if [[ -f /data/adb/edxp/misc_path ]]; then
MISC_PATH=$(cat /data/adb/edxp/misc_path)
ui_print "- Use previous path $MISC_PATH"
else
MISC_PATH="edxp_$(tr -cd 'A-Za-z0-9' < /dev/urandom | head -c16)"
ui_print "- Use new path $MISC_PATH"
mkdir -p /data/adb/edxp || abort "! Can't create adb path"
echo "$MISC_PATH" > /data/adb/edxp/misc_path || abort "! Can't store configuration path"
fi
set_perm_recursive /data/adb/edxp root root 0700 0600 "u:object_r:magisk_file:s0" || abort "! Can't set permission"
mkdir -p /data/misc/$MISC_PATH || abort "! Can't create configuration path"
set_perm /data/misc/$MISC_PATH root root 0771 "u:object_r:magisk_file:s0" || abort "! Can't set permission"
echo "rm -rf /data/misc/$MISC_PATH" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh"
echo "rm -rf /data/adb/edxp" >> "$MODPATH/uninstall.sh" || abort "! Can't write uninstall.sh"
ui_print "- Welcome to EdXposed ${VERSION}!"
# before Magisk 16e4c67, sepolicy.rule is copied on the second reboot