diff --git a/loader/src/include/solist.hpp b/loader/src/include/solist.hpp index 51a4f2e6..ecd378ad 100644 --- a/loader/src/include/solist.hpp +++ b/loader/src/include/solist.hpp @@ -98,6 +98,9 @@ namespace SoList { static SoInfo *somain = NULL; static SoInfo **sonext = NULL; + static uint64_t *g_module_load_counter = NULL; + static uint64_t *g_module_unload_counter = NULL; + static bool Initialize(); template @@ -127,6 +130,27 @@ namespace SoList { return path_found; } + static void ResetCounters(size_t reset_number) { + 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 >= reset_number) { + *g_module_load_counter = loaded_modules - reset_number; + LOGD("reset g_module_load_counter to %zu", (size_t) *g_module_load_counter); + } + if (unloaded_modules >= reset_number) { + *g_module_unload_counter = unloaded_modules - reset_number; + LOGD("reset g_module_unload_counter to %zu", (size_t) *g_module_unload_counter); + } + } + static bool Initialize() { SandHook::ElfImg linker("/linker"); if (!ProtectedDataGuard::setup(linker)) return false; @@ -179,11 +203,7 @@ namespace SoList { LOGD("found symbol sonext"); SoInfo *vdso = getStaticPointer(linker, vdso_sym_name); - if (vdso != NULL) { - LOGD("found symbol vdso"); - } else { - LOGD("symbol vdso is missing"); - } + if (vdso != NULL) LOGD("found symbol vdso"); SoInfo::get_realpath_sym = reinterpret_cast(linker.getSymbAddress("__dl__ZNK6soinfo12get_realpathEv")); if (SoInfo::get_realpath_sym == NULL) return false; @@ -197,6 +217,11 @@ namespace SoList { if (SoInfo::soinfo_free == NULL) return false; LOGD("found symbol soinfo_free"); + g_module_load_counter = reinterpret_cast(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(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++) { auto possible_field = (uintptr_t) solist + i * sizeof(void *); diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index ef0ad6aa..5963d51a 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -578,16 +578,21 @@ void ZygiskContext::run_modules_pre() { void ZygiskContext::run_modules_post() { flags[POST_SPECIALIZE] = true; + + size_t modules_unloaded = 0; for (const auto &m : modules) { if (flags[APP_SPECIALIZE]) { m.postAppSpecialize(args.app); } else if (flags[SERVER_FORK_AND_SPECIALIZE]) { 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_unloaded, true); + } } /* 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) \ 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 reset_number, bool spoof_maps) { LOGD("cleaning trace for path %s", path); - if (!SoList::DropSoPath(path) || !spoof_maps) { - return; - } + if (reset_number > 0) SoList::ResetCounters(reset_number); + bool path_found = SoList::DropSoPath(path); + if (!path_found || !spoof_maps) return; LOGD("spoofing virtual maps for %s", path); // spoofing map names is futile in Android, we do it simply diff --git a/loader/src/injector/module.hpp b/loader/src/injector/module.hpp index dfbde578..24111fc5 100644 --- a/loader/src/injector/module.hpp +++ b/loader/src/injector/module.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "api.hpp" @@ -209,7 +210,7 @@ case 5: \ int getModuleDir() const; void setOption(zygisk::Option opt); 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)); } int getId() const { return id; } @@ -235,4 +236,4 @@ case 5: \ } mod; }; -} // namespace \ No newline at end of file +} // namespace diff --git a/loader/src/injector/zygisk.hpp b/loader/src/injector/zygisk.hpp index 744755e9..5d48109b 100644 --- a/loader/src/injector/zygisk.hpp +++ b/loader/src/injector/zygisk.hpp @@ -7,7 +7,7 @@ extern size_t block_size; void hook_functions(); -void clean_trace(const char* path, bool spoof_maps = false); +void clean_trace(const char* path, size_t reset_number = 1, bool spoof_maps = false); void revert_unmount_ksu();