You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
Refine unmount
This commit is contained in:
@@ -58,6 +58,17 @@ namespace zygiskd {
|
||||
return socket_utils::read_string(fd);
|
||||
}
|
||||
|
||||
uint32_t GetProcessFlags(uid_t uid) {
|
||||
UniqueFd fd = Connect(1);
|
||||
if (fd == -1) {
|
||||
PLOGE("GetProcessFlags");
|
||||
return 0;
|
||||
}
|
||||
socket_utils::write_u8(fd, (uint8_t) SocketAction::GetProcessFlags);
|
||||
socket_utils::write_u32(fd, uid);
|
||||
return socket_utils::read_u32(fd);
|
||||
}
|
||||
|
||||
std::vector<Module> ReadModules() {
|
||||
std::vector<Module> modules;
|
||||
UniqueFd fd = Connect(1);
|
||||
|
||||
@@ -90,6 +90,10 @@ namespace socket_utils {
|
||||
return read_exact_or<uint8_t>(fd, 0);
|
||||
}
|
||||
|
||||
uint32_t read_u32(int fd) {
|
||||
return read_exact_or<uint32_t>(fd, 0);
|
||||
}
|
||||
|
||||
size_t read_usize(int fd) {
|
||||
return read_exact_or<size_t>(fd, 0);
|
||||
}
|
||||
@@ -110,6 +114,10 @@ namespace socket_utils {
|
||||
return write_exact<uint8_t>(fd, val);
|
||||
}
|
||||
|
||||
bool write_u32(int fd, uint32_t val) {
|
||||
return write_exact<uint32_t>(fd, val);
|
||||
}
|
||||
|
||||
bool write_string(int fd, std::string_view str) {
|
||||
return write_usize(fd, str.size()) && str.size() == xwrite(fd, str.data(), str.size());
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace zygiskd {
|
||||
PingHeartBeat,
|
||||
RequestLogcatFd,
|
||||
ReadNativeBridge,
|
||||
GetProcessFlags,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
GetModuleDir,
|
||||
@@ -67,6 +68,8 @@ namespace zygiskd {
|
||||
|
||||
std::vector<Module> ReadModules();
|
||||
|
||||
uint32_t GetProcessFlags(uid_t uid);
|
||||
|
||||
int ConnectCompanion(size_t index);
|
||||
|
||||
int GetModuleDir(size_t index);
|
||||
|
||||
@@ -13,12 +13,16 @@ namespace socket_utils {
|
||||
|
||||
uint8_t read_u8(int fd);
|
||||
|
||||
uint32_t read_u32(int fd);
|
||||
|
||||
size_t read_usize(int fd);
|
||||
|
||||
std::string read_string(int fd);
|
||||
|
||||
bool write_u8(int fd, uint8_t val);
|
||||
|
||||
bool write_u32(int fd, uint32_t val);
|
||||
|
||||
int recv_fd(int fd);
|
||||
|
||||
bool write_usize(int fd, size_t val);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "misc.hpp"
|
||||
#include "zygisk.hpp"
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static void lazy_unmount(const char* mountpoint) {
|
||||
if (umount2(mountpoint, MNT_DETACH) != -1)
|
||||
LOGD("Unmounted (%s)", mountpoint);
|
||||
}
|
||||
|
||||
void revert_unmount() {
|
||||
parse_mnt("/proc/self/mounts", [](mntent* mentry) {
|
||||
if (mentry->mnt_fsname == "/data/adb/ksu/modules"sv ||
|
||||
std::string_view(mentry->mnt_opts).find("/data/adb/ksu/modules") != std::string_view::npos) {
|
||||
lazy_unmount(mentry->mnt_fsname);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -566,15 +566,13 @@ void HookContext::run_modules_post() {
|
||||
/* Zygisksu changed: Load module fds */
|
||||
void HookContext::app_specialize_pre() {
|
||||
flags[APP_SPECIALIZE] = true;
|
||||
info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);
|
||||
run_modules_pre();
|
||||
}
|
||||
|
||||
|
||||
void HookContext::app_specialize_post() {
|
||||
run_modules_post();
|
||||
if (info_flags & PROCESS_IS_MAGISK_APP) {
|
||||
setenv("ZYGISK_ENABLED", "1", 1);
|
||||
}
|
||||
|
||||
// Cleanups
|
||||
env->ReleaseStringUTFChars(args.app->nice_name, process);
|
||||
|
||||
@@ -35,6 +35,31 @@ void parse_mnt(const char* file, const std::function<bool(mntent*)>& fn) {
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::string> split_str(std::string_view s, std::string_view delimiter) {
|
||||
std::list<std::string> ret;
|
||||
size_t pos = 0;
|
||||
while (pos < s.size()) {
|
||||
auto next = s.find(delimiter, pos);
|
||||
if (next == std::string_view::npos) {
|
||||
ret.emplace_back(s.substr(pos));
|
||||
break;
|
||||
}
|
||||
ret.emplace_back(s.substr(pos, next - pos));
|
||||
pos = next + delimiter.size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string join_str(const std::list<std::string>& list, std::string_view delimiter) {
|
||||
std::string ret;
|
||||
for (auto& s : list) {
|
||||
if (!ret.empty())
|
||||
ret += delimiter;
|
||||
ret += s;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
sDIR make_dir(DIR *dp) {
|
||||
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <dirent.h>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mntent.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "logging.h"
|
||||
@@ -34,6 +36,16 @@ private:
|
||||
using thread_entry = void *(*)(void *);
|
||||
int new_daemon_thread(thread_entry entry, void *arg);
|
||||
|
||||
static inline bool str_contains(std::string_view s, std::string_view ss) {
|
||||
return s.find(ss) != std::string_view::npos;
|
||||
}
|
||||
static inline bool str_starts(std::string_view s, std::string_view ss) {
|
||||
return s.size() >= ss.size() && s.compare(0, ss.size(), ss) == 0;
|
||||
}
|
||||
static inline bool str_ends(std::string_view s, std::string_view ss) {
|
||||
return s.size() >= ss.size() && s.compare(s.size() - ss.size(), std::string_view::npos, ss) == 0;
|
||||
}
|
||||
|
||||
template<typename T, typename Impl>
|
||||
class stateless_allocator {
|
||||
public:
|
||||
@@ -78,6 +90,25 @@ static inline sFILE xopen_file(int fd, const char *mode) {
|
||||
return make_file(fdopen(fd, mode));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class reversed_container {
|
||||
public:
|
||||
reversed_container(T &base) : base(base) {}
|
||||
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
|
||||
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
|
||||
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
|
||||
decltype(std::declval<T>().rend()) end() { return base.rend(); }
|
||||
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
|
||||
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
|
||||
private:
|
||||
T &base;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
reversed_container<T> reversed(T &base) {
|
||||
return reversed_container<T>(base);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void default_new(T *&p) { p = new T(); }
|
||||
|
||||
@@ -97,6 +128,10 @@ int parse_int(std::string_view s);
|
||||
|
||||
void parse_mnt(const char* file, const std::function<bool(mntent*)>& fn);
|
||||
|
||||
std::list<std::string> split_str(std::string_view s, std::string_view delimiter);
|
||||
|
||||
std::string join_str(const std::list<std::string>& list, std::string_view delimiter);
|
||||
|
||||
template <typename T>
|
||||
static inline T align_to(T v, int a) {
|
||||
static_assert(std::is_integral<T>::value);
|
||||
|
||||
@@ -111,12 +111,10 @@ namespace {
|
||||
PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT,
|
||||
PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST,
|
||||
|
||||
PROCESS_IS_SYS_UI = (1u << 29),
|
||||
DENYLIST_ENFORCING = (1u << 30),
|
||||
PROCESS_IS_MAGISK_APP = (1u << 31),
|
||||
PROCESS_IS_SYS_UI = (1u << 30),
|
||||
PROCESS_IS_KSU_APP = (1u << 31),
|
||||
|
||||
UNMOUNT_MASK = (PROCESS_ON_DENYLIST | DENYLIST_ENFORCING),
|
||||
PRIVATE_MASK = (PROCESS_IS_SYS_UI | DENYLIST_ENFORCING | PROCESS_IS_MAGISK_APP)
|
||||
PRIVATE_MASK = (PROCESS_IS_SYS_UI | PROCESS_IS_KSU_APP)
|
||||
};
|
||||
|
||||
struct api_abi_base {
|
||||
|
||||
73
loader/src/injector/unmount.cpp
Normal file
73
loader/src/injector/unmount.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "misc.hpp"
|
||||
#include "zygisk.hpp"
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static void lazy_unmount(const char* mountpoint) {
|
||||
if (umount2(mountpoint, MNT_DETACH) != -1) {
|
||||
LOGD("Unmounted (%s)", mountpoint);
|
||||
} else {
|
||||
PLOGE("Failed to unmount: %s (%s)", strerror(errno), mountpoint);
|
||||
}
|
||||
}
|
||||
|
||||
#define PARSE_OPT(name, flag) \
|
||||
if (opt == name) { \
|
||||
flags |= (flag); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
void revert_unmount() {
|
||||
std::vector<std::string> targets;
|
||||
std::list<std::pair<std::string, std::string>> backups;
|
||||
|
||||
targets.emplace_back("/data/adb/ksu/modules");
|
||||
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
|
||||
if (str_starts(mentry->mnt_fsname, "/data/adb/")) {
|
||||
targets.emplace_back(mentry->mnt_dir);
|
||||
}
|
||||
if (mentry->mnt_type == "overlay"sv) {
|
||||
if (str_contains(mentry->mnt_opts, "/data/adb/ksu/modules")) {
|
||||
targets.emplace_back(mentry->mnt_dir);
|
||||
} else {
|
||||
backups.emplace_back(mentry->mnt_dir, mentry->mnt_opts);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (auto& s: reversed(targets)) {
|
||||
lazy_unmount(s.data());
|
||||
}
|
||||
|
||||
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
|
||||
if (mentry->mnt_type == "overlay"sv) {
|
||||
for (auto it = backups.begin(); it != backups.end(); it++) {
|
||||
backups.remove_if([&](auto& mnt) {
|
||||
return mnt.first == mentry->mnt_dir && mnt.second == mentry->mnt_opts;
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (auto& mnt: backups) {
|
||||
auto opts = split_str(mnt.second, ",");
|
||||
unsigned long flags = 0;
|
||||
opts.remove_if([&](auto& opt) {
|
||||
PARSE_OPT(MNTOPT_RO, MS_RDONLY)
|
||||
PARSE_OPT(MNTOPT_NOSUID, MS_NOSUID)
|
||||
PARSE_OPT("relatime", MS_RELATIME)
|
||||
return false;
|
||||
});
|
||||
auto mnt_data = join_str(opts, ",");
|
||||
if (mount("overlay", mnt.first.data(), "overlay", flags, mnt_data.data()) != -1) {
|
||||
LOGD("Remounted (%s)", mnt.first.data());
|
||||
} else {
|
||||
LOGW("Failed to remount: %s (%s, %s)", strerror(errno), mnt.first.data(), mnt_data.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,10 +72,8 @@ ui_print "- Extracting module files"
|
||||
extract "$ZIPFILE" 'daemon.sh' "$MODPATH"
|
||||
extract "$ZIPFILE" 'module.prop' "$MODPATH"
|
||||
extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH"
|
||||
extract "$ZIPFILE" 'sepolicy.rule' "$MODPATH"
|
||||
extract "$ZIPFILE" 'service.sh' "$MODPATH"
|
||||
if [ "$KSU" ]; then
|
||||
extract "$ZIPFILE" 'sepolicy.rule' "$MODPATH"
|
||||
fi
|
||||
|
||||
HAS32BIT=false && [ -d "/system/lib" ] && HAS32BIT=true
|
||||
HAS64BIT=false && [ -d "/system/lib64" ] && HAS64BIT=true
|
||||
|
||||
@@ -21,4 +21,4 @@ if [ $(which magisk) ] && [ ".." -ef "/data/adb/modules" ]; then
|
||||
done
|
||||
fi
|
||||
|
||||
unshare -m sh -c "./daemon.sh $@&"
|
||||
sh -c "./daemon.sh $@&"
|
||||
|
||||
@@ -10,3 +10,6 @@ allow * magisk_file lnk_file *
|
||||
allow * magisk_file sock_file *
|
||||
|
||||
allow system_server system_server process execmem
|
||||
allow zygote mnt_vendor_file dir search
|
||||
allow zygote system_file dir mounton
|
||||
allow zygote labeledfs filesystem mount
|
||||
|
||||
Reference in New Issue
Block a user