diff --git a/loader/src/injector/entry.cpp b/loader/src/injector/entry.cpp index 1cabc27..40a71b6 100644 --- a/loader/src/injector/entry.cpp +++ b/loader/src/injector/entry.cpp @@ -1,16 +1,17 @@ #include "daemon.h" #include "logging.h" #include "zygisk.hpp" -#include "module.hpp" using namespace std; -void *self_handle = nullptr; +void *start_addr = nullptr; +size_t block_size = 0; extern "C" [[gnu::visibility("default")]] -void entry(void* handle, const char* path) { +void entry(void* addr, size_t size, const char* path) { LOGI("Zygisk library injected, version %s", ZKSU_VERSION); - self_handle = handle; + start_addr = addr; + block_size = size; zygiskd::Init(path); if (!zygiskd::PingHeartbeat()) { @@ -22,6 +23,6 @@ void entry(void* handle, const char* path) { logging::setfd(zygiskd::RequestLogcatFd()); #endif - LOGI("Start hooking"); + LOGI("Start hooking, call %p", hook_functions); hook_functions(); } diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index a1b715c..16bb8d1 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -176,22 +176,24 @@ DCL_HOOK_FUNC(void, android_log_close) { // We cannot directly call `dlclose` to unload ourselves, otherwise when `dlclose` returns, // it will return to our code which has been unmapped, causing segmentation fault. -// Instead, we hook `pthread_attr_destroy` which will be called when VM daemon threads start. -DCL_HOOK_FUNC(int, pthread_attr_destroy, void *target) { - int res = old_pthread_attr_destroy((pthread_attr_t *)target); +// Instead, we hook `pthread_attr_setstacksize` which will be called when VM daemon threads start. +DCL_HOOK_FUNC(int, pthread_attr_setstacksize, void *target, size_t size) { + int res = old_pthread_attr_setstacksize((pthread_attr_t *)target, size); + LOGV("Call pthread_attr_setstacksize in [tid, pid]: %d, %d", gettid(), getpid()); // Only perform unloading on the main thread if (gettid() != getpid()) return res; - LOGV("pthread_attr_destroy"); + LOGV("Clean zygisk reminders"); if (should_unmap_zygisk) { unhook_functions(); if (should_unmap_zygisk) { - // Because both `pthread_attr_destroy` and `dlclose` have the same function signature, + // Because both `pthread_attr_setstacksize` and `dlclose` have the same function signature, // we can use `musttail` to let the compiler reuse our stack frame and thus - // `dlclose` will directly return to the caller of `pthread_attr_destroy`. - [[clang::musttail]] return dlclose(self_handle); + // `dlclose` will directly return to the caller of `pthread_attr_setstacksize`. + LOGV("Unmap libzygisk.so"); + [[clang::musttail]] return munmap(start_addr, block_size); } } @@ -858,7 +860,7 @@ static void hook_unloader() { } } - PLT_HOOK_REGISTER(art_dev, art_inode, pthread_attr_destroy); + PLT_HOOK_REGISTER(art_dev, art_inode, pthread_attr_setstacksize); hook_commit(); } diff --git a/loader/src/injector/zygisk.hpp b/loader/src/injector/zygisk.hpp index 5c06f8b..636367b 100644 --- a/loader/src/injector/zygisk.hpp +++ b/loader/src/injector/zygisk.hpp @@ -1,10 +1,9 @@ #pragma once -#include #include -#include -extern void *self_handle; +extern void *start_addr; +extern size_t block_size; void hook_functions(); diff --git a/loader/src/ptracer/ptracer.cpp b/loader/src/ptracer/ptracer.cpp index 9182ddd..f790f98 100644 --- a/loader/src/ptracer/ptracer.cpp +++ b/loader/src/ptracer/ptracer.cpp @@ -222,10 +222,24 @@ bool inject_on_main(int pid, const char *lib_path) { return false; } - /* call injector entry(handle, path) */ + /* record the address range of libzygisk.so */ + map = MapInfo::Scan(std::to_string(pid)); + void *start_addr = nullptr; + size_t block_size = 0; + for (auto &info : map) { + if (strstr(info.path.c_str(), "libzygisk.so")) { + void *addr = (void *)info.start; + if (start_addr == nullptr) start_addr = addr; + size_t size = info.end - info.start; + block_size += size; + LOGD("found block %s: [%p-%p] with size %zu", info.path.c_str(), addr, (void *)info.end, size); + } + } + /* call injector entry(start_addr, block_size, path) */ args.clear(); - args.push_back(remote_handle); + args.push_back((uintptr_t) start_addr); + args.push_back(block_size); str = push_string(pid, regs, zygiskd::GetTmpPath().c_str()); args.push_back((long) str);