mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-07 15:34:28 +00:00
Add flag for unloaded Zygisk modules
This commit is contained in:
parent
a01a3404fe
commit
fbe17dde03
@ -715,6 +715,7 @@ static void collect_modules(bool open_zygisk) {
|
|||||||
#else
|
#else
|
||||||
#error Unsupported ABI
|
#error Unsupported ABI
|
||||||
#endif
|
#endif
|
||||||
|
unlinkat(modfd, "zygisk/unloaded", 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ignore zygisk modules when zygisk is not enabled
|
// Ignore zygisk modules when zygisk is not enabled
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#define UID_ROOT 0
|
#define UID_ROOT 0
|
||||||
#define UID_SHELL 2000
|
#define UID_SHELL 2000
|
||||||
@ -79,6 +80,24 @@ public:
|
|||||||
bool operator!=(const stateless_allocator&) { return false; }
|
bool operator!=(const stateless_allocator&) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class dynamic_bitset {
|
||||||
|
private:
|
||||||
|
using long_bits = std::bitset<sizeof(unsigned long)>;
|
||||||
|
std::vector<long_bits> bits;
|
||||||
|
public:
|
||||||
|
constexpr static int slot_size = sizeof(unsigned long);
|
||||||
|
long_bits::reference operator[] (size_t pos) {
|
||||||
|
size_t slot = pos / slot_size;
|
||||||
|
size_t index = pos % slot_size;
|
||||||
|
if (bits.size() <= slot) {
|
||||||
|
bits.resize(slot + 1);
|
||||||
|
}
|
||||||
|
return bits[slot][index];
|
||||||
|
}
|
||||||
|
size_t slots() const { return bits.size(); }
|
||||||
|
unsigned long to_ulong(size_t slot) const { return bits[slot].to_ulong(); }
|
||||||
|
};
|
||||||
|
|
||||||
int parse_int(std::string_view s);
|
int parse_int(std::string_view s);
|
||||||
|
|
||||||
using thread_entry = void *(*)(void *);
|
using thread_entry = void *(*)(void *);
|
||||||
|
@ -167,8 +167,7 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> remote_get_info(int uid, const char *process, uint32_t *flags) {
|
int remote_get_info(int uid, const char *process, uint32_t *flags, vector<int> &fds) {
|
||||||
vector<int> fds;
|
|
||||||
if (int fd = connect_daemon(); fd >= 0) {
|
if (int fd = connect_daemon(); fd >= 0) {
|
||||||
write_int(fd, ZYGISK_REQUEST);
|
write_int(fd, ZYGISK_REQUEST);
|
||||||
write_int(fd, ZYGISK_GET_INFO);
|
write_int(fd, ZYGISK_GET_INFO);
|
||||||
@ -179,9 +178,9 @@ std::vector<int> remote_get_info(int uid, const char *process, uint32_t *flags)
|
|||||||
if ((*flags & UNMOUNT_MASK) != UNMOUNT_MASK) {
|
if ((*flags & UNMOUNT_MASK) != UNMOUNT_MASK) {
|
||||||
fds = recv_fds(fd);
|
fds = recv_fds(fd);
|
||||||
}
|
}
|
||||||
close(fd);
|
return fd;
|
||||||
}
|
}
|
||||||
return fds;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following code runs in magiskd
|
// The following code runs in magiskd
|
||||||
@ -358,6 +357,27 @@ static void get_process_info(int client, const sock_cred *cred) {
|
|||||||
vector<int> fds = get_module_fds(str_ends(buf, "64"));
|
vector<int> fds = get_module_fds(str_ends(buf, "64"));
|
||||||
send_fds(client, fds.data(), fds.size());
|
send_fds(client, fds.data(), fds.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following will only happen for system_server
|
||||||
|
int slots = read_int(client);
|
||||||
|
int id = 0;
|
||||||
|
for (int i = 0; i < slots; ++i) {
|
||||||
|
unsigned long l = 0;
|
||||||
|
xxread(client, &l, sizeof(l));
|
||||||
|
bitset<sizeof(unsigned long)> bits(l);
|
||||||
|
for (int j = 0; id < module_list->size(); ++j, ++id) {
|
||||||
|
if (!bits[j]) {
|
||||||
|
// Either not a zygisk module, or incompatible
|
||||||
|
char buf[4096];
|
||||||
|
snprintf(buf, sizeof(buf), MODULEROOT "/%s/zygisk",
|
||||||
|
module_list->operator[](id).name.data());
|
||||||
|
if (int dirfd = open(buf, O_RDONLY | O_CLOEXEC); dirfd >= 0) {
|
||||||
|
close(xopenat(dirfd, "unloaded", O_CREAT | O_RDONLY, 0644));
|
||||||
|
close(dirfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_log_pipe(int fd) {
|
static void send_log_pipe(int fd) {
|
||||||
|
@ -450,14 +450,16 @@ void HookContext::nativeSpecializeAppProcess_pre() {
|
|||||||
ZLOGV("pre specialize [%s]\n", process);
|
ZLOGV("pre specialize [%s]\n", process);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto module_fds = remote_get_info(args->uid, process, &flags);
|
vector<int> module_fds;
|
||||||
|
int fd = remote_get_info(args->uid, process, &flags, module_fds);
|
||||||
if ((flags & UNMOUNT_MASK) == UNMOUNT_MASK) {
|
if ((flags & UNMOUNT_MASK) == UNMOUNT_MASK) {
|
||||||
// TODO: Handle MOUNT_EXTERNAL_NONE on older platforms
|
|
||||||
ZLOGI("[%s] is on the denylist\n", process);
|
ZLOGI("[%s] is on the denylist\n", process);
|
||||||
state[DO_UNMOUNT] = true;
|
state[DO_UNMOUNT] = true;
|
||||||
} else {
|
} else if (fd >= 0) {
|
||||||
run_modules_pre(module_fds);
|
run_modules_pre(module_fds);
|
||||||
|
write_int(fd, 0);
|
||||||
}
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
close_fds();
|
close_fds();
|
||||||
android_logging();
|
android_logging();
|
||||||
@ -486,7 +488,29 @@ void HookContext::nativeForkSystemServer_pre() {
|
|||||||
state[SERVER_SPECIALIZE] = true;
|
state[SERVER_SPECIALIZE] = true;
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
ZLOGV("pre forkSystemServer\n");
|
ZLOGV("pre forkSystemServer\n");
|
||||||
run_modules_pre(remote_get_info(1000, "system_server", &flags));
|
vector<int> module_fds;
|
||||||
|
int fd = remote_get_info(1000, "system_server", &flags, module_fds);
|
||||||
|
if (fd >= 0) {
|
||||||
|
if (module_fds.empty()) {
|
||||||
|
write_int(fd, 0);
|
||||||
|
} else {
|
||||||
|
run_modules_pre(module_fds);
|
||||||
|
|
||||||
|
// Send the bitset of module status back to magiskd from system_server
|
||||||
|
dynamic_bitset bits;
|
||||||
|
// Pre-allocate enough bits
|
||||||
|
bits[module_fds.size() - 1] = false;
|
||||||
|
for (const auto &m : modules) {
|
||||||
|
bits[m.getId()] = true;
|
||||||
|
}
|
||||||
|
write_int(fd, bits.slots());
|
||||||
|
for (int i = 0; i < bits.slots(); ++i) {
|
||||||
|
unsigned long l = bits.to_ulong(i);
|
||||||
|
xwrite(fd, &l, sizeof(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
close_fds();
|
close_fds();
|
||||||
android_logging();
|
android_logging();
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ struct ZygiskModule {
|
|||||||
void setOption(zygisk::Option opt);
|
void setOption(zygisk::Option opt);
|
||||||
static uint32_t getFlags();
|
static uint32_t getFlags();
|
||||||
void doUnload() const { if (unload) dlclose(handle); }
|
void doUnload() const { if (unload) dlclose(handle); }
|
||||||
|
int getId() const { return id; }
|
||||||
|
|
||||||
ZygiskModule(int id, void *handle, void *entry);
|
ZygiskModule(int id, void *handle, void *entry);
|
||||||
|
|
||||||
|
@ -41,5 +41,5 @@ extern void *self_handle;
|
|||||||
|
|
||||||
void unload_first_stage();
|
void unload_first_stage();
|
||||||
void hook_functions();
|
void hook_functions();
|
||||||
std::vector<int> remote_get_info(int uid, const char *process, uint32_t *flags);
|
int remote_get_info(int uid, const char *process, uint32_t *flags, std::vector<int> &fds);
|
||||||
int remote_request_unmount();
|
int remote_request_unmount();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user