You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
improve: reset linker module counters
Two counters for module loading and unloading are introduced in the commit a2e83ab348. To remove linker traces of libzygisk.so and Zygisk modules, we should reset them properly.
This commit is contained in:
@@ -98,6 +98,9 @@ namespace SoList {
|
|||||||
static SoInfo *somain = NULL;
|
static SoInfo *somain = NULL;
|
||||||
static SoInfo **sonext = NULL;
|
static SoInfo **sonext = NULL;
|
||||||
|
|
||||||
|
static uint64_t *g_module_load_counter = NULL;
|
||||||
|
static uint64_t *g_module_unload_counter = NULL;
|
||||||
|
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -127,6 +130,27 @@ namespace SoList {
|
|||||||
return path_found;
|
return path_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ResetCounters(size_t load, size_t unload) {
|
||||||
|
if (solist == NULL && !Initialize()) {
|
||||||
|
LOGE("Failed to initialize solist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_module_load_counter == NULL || g_module_unload_counter == NULL) {
|
||||||
|
LOGI("g_module counters not defined, skip reseting them");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto loaded_modules = *g_module_load_counter;
|
||||||
|
auto unloaded_modules = *g_module_unload_counter;
|
||||||
|
if (loaded_modules >= load) {
|
||||||
|
*g_module_load_counter = loaded_modules - load;
|
||||||
|
LOGD("reset g_module_load_counter to %zu", (size_t) *g_module_load_counter);
|
||||||
|
}
|
||||||
|
if (unloaded_modules >= unload) {
|
||||||
|
*g_module_unload_counter = unloaded_modules - unload;
|
||||||
|
LOGD("reset g_module_unload_counter to %zu", (size_t) *g_module_unload_counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool Initialize() {
|
static bool Initialize() {
|
||||||
SandHook::ElfImg linker("/linker");
|
SandHook::ElfImg linker("/linker");
|
||||||
if (!ProtectedDataGuard::setup(linker)) return false;
|
if (!ProtectedDataGuard::setup(linker)) return false;
|
||||||
@@ -179,11 +203,7 @@ namespace SoList {
|
|||||||
LOGD("found symbol sonext");
|
LOGD("found symbol sonext");
|
||||||
|
|
||||||
SoInfo *vdso = getStaticPointer<SoInfo>(linker, vdso_sym_name);
|
SoInfo *vdso = getStaticPointer<SoInfo>(linker, vdso_sym_name);
|
||||||
if (vdso != NULL) {
|
if (vdso != NULL) LOGD("found symbol vdso");
|
||||||
LOGD("found symbol vdso");
|
|
||||||
} else {
|
|
||||||
LOGD("symbol vdso is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
SoInfo::get_realpath_sym = reinterpret_cast<decltype(SoInfo::get_realpath_sym)>(linker.getSymbAddress("__dl__ZNK6soinfo12get_realpathEv"));
|
SoInfo::get_realpath_sym = reinterpret_cast<decltype(SoInfo::get_realpath_sym)>(linker.getSymbAddress("__dl__ZNK6soinfo12get_realpathEv"));
|
||||||
if (SoInfo::get_realpath_sym == NULL) return false;
|
if (SoInfo::get_realpath_sym == NULL) return false;
|
||||||
@@ -197,6 +217,11 @@ namespace SoList {
|
|||||||
if (SoInfo::soinfo_free == NULL) return false;
|
if (SoInfo::soinfo_free == NULL) return false;
|
||||||
LOGD("found symbol soinfo_free");
|
LOGD("found symbol soinfo_free");
|
||||||
|
|
||||||
|
g_module_load_counter = reinterpret_cast<decltype(g_module_load_counter)>(linker.getSymbAddress("__dl__ZL21g_module_load_counter"));
|
||||||
|
if (g_module_load_counter != NULL) LOGD("found symbol g_module_load_counter");
|
||||||
|
|
||||||
|
g_module_unload_counter = reinterpret_cast<decltype(g_module_unload_counter)>(linker.getSymbAddress("__dl__ZL23g_module_unload_counter"));
|
||||||
|
if (g_module_unload_counter != NULL) LOGD("found symbol g_module_unload_counter");
|
||||||
|
|
||||||
for (size_t i = 0; i < 1024 / sizeof(void *); i++) {
|
for (size_t i = 0; i < 1024 / sizeof(void *); i++) {
|
||||||
auto possible_field = (uintptr_t) solist + i * sizeof(void *);
|
auto possible_field = (uintptr_t) solist + i * sizeof(void *);
|
||||||
|
|||||||
@@ -25,5 +25,5 @@ void entry(void* addr, size_t size, const char* path) {
|
|||||||
|
|
||||||
LOGI("start plt hooking");
|
LOGI("start plt hooking");
|
||||||
hook_functions();
|
hook_functions();
|
||||||
clean_trace(path);
|
clean_trace(path, 1, 0, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -578,16 +578,21 @@ void ZygiskContext::run_modules_pre() {
|
|||||||
|
|
||||||
void ZygiskContext::run_modules_post() {
|
void ZygiskContext::run_modules_post() {
|
||||||
flags[POST_SPECIALIZE] = true;
|
flags[POST_SPECIALIZE] = true;
|
||||||
|
|
||||||
|
size_t modules_unloaded = 0;
|
||||||
for (const auto &m : modules) {
|
for (const auto &m : modules) {
|
||||||
if (flags[APP_SPECIALIZE]) {
|
if (flags[APP_SPECIALIZE]) {
|
||||||
m.postAppSpecialize(args.app);
|
m.postAppSpecialize(args.app);
|
||||||
} else if (flags[SERVER_FORK_AND_SPECIALIZE]) {
|
} else if (flags[SERVER_FORK_AND_SPECIALIZE]) {
|
||||||
m.postServerSpecialize(args.server);
|
m.postServerSpecialize(args.server);
|
||||||
}
|
}
|
||||||
m.tryUnload();
|
if (m.tryUnload()) modules_unloaded++;
|
||||||
}
|
}
|
||||||
|
|
||||||
clean_trace("jit-cache-zygisk", true);
|
if (modules.size() > 0) {
|
||||||
|
LOGD("modules unloaded: %zu/%zu", modules_unloaded, modules.size());
|
||||||
|
clean_trace("jit-cache-zygisk", modules.size(), modules_unloaded, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zygisksu changed: Load module fds */
|
/* Zygisksu changed: Load module fds */
|
||||||
@@ -746,12 +751,12 @@ static void hook_register(dev_t dev, ino_t inode, const char *symbol, void *new_
|
|||||||
#define PLT_HOOK_REGISTER(DEV, INODE, NAME) \
|
#define PLT_HOOK_REGISTER(DEV, INODE, NAME) \
|
||||||
PLT_HOOK_REGISTER_SYM(DEV, INODE, #NAME, NAME)
|
PLT_HOOK_REGISTER_SYM(DEV, INODE, #NAME, NAME)
|
||||||
|
|
||||||
void clean_trace(const char* path, bool spoof_maps) {
|
void clean_trace(const char* path, size_t load, size_t unload, bool spoof_maps) {
|
||||||
LOGD("cleaning trace for path %s", path);
|
LOGD("cleaning trace for path %s", path);
|
||||||
|
|
||||||
if (!SoList::DropSoPath(path) || !spoof_maps) {
|
if (load > 0 || unload >0) SoList::ResetCounters(load, unload);
|
||||||
return;
|
bool path_found = SoList::DropSoPath(path);
|
||||||
}
|
if (!path_found || !spoof_maps) return;
|
||||||
|
|
||||||
LOGD("spoofing virtual maps for %s", path);
|
LOGD("spoofing virtual maps for %s", path);
|
||||||
// spoofing map names is futile in Android, we do it simply
|
// spoofing map names is futile in Android, we do it simply
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include "api.hpp"
|
#include "api.hpp"
|
||||||
|
|
||||||
@@ -209,7 +210,7 @@ case 5: \
|
|||||||
int getModuleDir() const;
|
int getModuleDir() const;
|
||||||
void setOption(zygisk::Option opt);
|
void setOption(zygisk::Option opt);
|
||||||
static uint32_t getFlags();
|
static uint32_t getFlags();
|
||||||
void tryUnload() const { if (unload) dlclose(handle); }
|
bool tryUnload() const { return unload && dlclose(handle) == 0; };
|
||||||
void clearApi() { memset(&api, 0, sizeof(api)); }
|
void clearApi() { memset(&api, 0, sizeof(api)); }
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
|
|
||||||
@@ -235,4 +236,4 @@ case 5: \
|
|||||||
} mod;
|
} mod;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ extern size_t block_size;
|
|||||||
|
|
||||||
void hook_functions();
|
void hook_functions();
|
||||||
|
|
||||||
void clean_trace(const char* path, bool spoof_maps = false);
|
void clean_trace(const char* path, size_t load = 1, size_t unload = 0, bool spoof_maps = false);
|
||||||
|
|
||||||
void revert_unmount_ksu();
|
void revert_unmount_ksu();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user