From 52885faf8b1f8c0598a8b6b802c9cfb7aed27aad Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Sat, 5 Apr 2025 15:36:39 -0300 Subject: [PATCH] remove: `dl.cpp` file and replace with "dlopen" This commit replaces DlopenMem for dlopen, removing the need for "dl.cpp" file. --- loader/src/common/daemon.cpp | 5 +-- loader/src/common/dl.cpp | 77 ------------------------------------ loader/src/include/daemon.h | 5 ++- loader/src/include/dl.h | 7 ---- loader/src/injector/hook.cpp | 50 +++++++++++++---------- zygiskd/src/zygiskd.c | 22 +++++++++-- 6 files changed, 52 insertions(+), 114 deletions(-) delete mode 100644 loader/src/common/dl.cpp delete mode 100644 loader/src/include/dl.h diff --git a/loader/src/common/daemon.cpp b/loader/src/common/daemon.cpp index bd558ca..44c7660 100644 --- a/loader/src/common/daemon.cpp +++ b/loader/src/common/daemon.cpp @@ -7,7 +7,6 @@ #include #include "daemon.h" -#include "dl.h" #include "socket_utils.h" namespace zygiskd { @@ -93,9 +92,9 @@ namespace zygiskd { socket_utils::write_u8(fd, (uint8_t) SocketAction::ReadModules); size_t len = socket_utils::read_usize(fd); for (size_t i = 0; i < len; i++) { + std::string lib_path = socket_utils::read_string(fd); std::string name = socket_utils::read_string(fd); - int module_fd = socket_utils::recv_fd(fd); - modules.emplace_back(name, module_fd); + modules.emplace_back(lib_path, name); } close(fd); diff --git a/loader/src/common/dl.cpp b/loader/src/common/dl.cpp deleted file mode 100644 index 352b8f9..0000000 --- a/loader/src/common/dl.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "dl.h" -#include "files.hpp" -#include "logging.h" - -extern "C" [[gnu::weak]] struct android_namespace_t* -//NOLINTNEXTLINE -__loader_android_create_namespace([[maybe_unused]] const char* name, - [[maybe_unused]] const char* ld_library_path, - [[maybe_unused]] const char* default_library_path, - [[maybe_unused]] uint64_t type, - [[maybe_unused]] const char* permitted_when_isolated_path, - [[maybe_unused]] android_namespace_t* parent, - [[maybe_unused]] const void* caller_addr); - -void* DlopenExt(const char* path, int flags) { - auto info = android_dlextinfo{}; - auto* dir = dirname(path); - auto* ns = &__loader_android_create_namespace == nullptr ? nullptr : - __loader_android_create_namespace(path, dir, nullptr, - 2, /* ANDROID_NAMESPACE_TYPE_SHARED */ - nullptr, nullptr, - reinterpret_cast(&DlopenExt)); - if (ns) { - info.flags = ANDROID_DLEXT_USE_NAMESPACE; - info.library_namespace = ns; - - LOGD("Open %s with namespace %p", path, ns); - } else { - LOGD("Cannot create namespace for %s", path); - } - - auto* handle = android_dlopen_ext(path, flags, &info); - if (handle) { - LOGD("dlopen %s: %p", path, handle); - } else { - LOGE("dlopen %s: %s", path, dlerror()); - } - return handle; -} - -void* DlopenMem(int fd, int flags) { - auto info = android_dlextinfo { - .flags = ANDROID_DLEXT_USE_LIBRARY_FD, - .reserved_addr = NULL, - .reserved_size = 0, - .relro_fd = 0, - .library_fd = fd, - .library_fd_offset = 0, - .library_namespace = NULL - }; - - /* INFO: We need to find the path of the fd since passing "" to android_dlopen_ext - will not work and passing the original "jit-cache-zygisk" will cause a detection again. */ - char path[PATH_MAX]; - if (get_path_from_fd(fd, path, sizeof(path)) != 0) { - LOGE("Failed to get path for fd: %d", fd); - return NULL; - } - - LOGD("Path for fd %d: %s", fd, path); - - auto *handle = android_dlopen_ext(path, flags, &info); - if (handle) { - LOGV("dlopen fd %d: %p", fd, handle); - } else { - LOGE("dlopen fd %d: %s", fd, dlerror()); - } - - return handle; -} diff --git a/loader/src/include/daemon.h b/loader/src/include/daemon.h index dad3c18..9bc3617 100644 --- a/loader/src/include/daemon.h +++ b/loader/src/include/daemon.h @@ -70,10 +70,11 @@ enum mount_namespace_state { namespace zygiskd { struct ModuleInfo { + std::string path; + /* TODO: Perhaps we can also remove this and just send paths? */ std::string name; - UniqueFd memfd; - inline explicit ModuleInfo(std::string name, int memfd) : name(name), memfd(memfd) {} + inline explicit ModuleInfo(std::string path, std::string name) : path(path), name(name) {} }; enum class SocketAction { diff --git a/loader/src/include/dl.h b/loader/src/include/dl.h deleted file mode 100644 index 25dd6c6..0000000 --- a/loader/src/include/dl.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -void *DlopenExt(const char *path, int flags); - -void *DlopenMem(int memfd, int flags); diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index 5b77ba3..c3282c1 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -15,7 +15,6 @@ #include #include -#include "dl.h" #include "daemon.h" #include "zygisk.hpp" #include "module.hpp" @@ -573,24 +572,35 @@ void ZygiskContext::fork_post() { /* Zygisksu changed: Load module fds */ void ZygiskContext::run_modules_pre() { - auto ms = zygiskd::ReadModules(); - auto size = ms.size(); - for (size_t i = 0; i < size; i++) { - auto& m = ms[i]; - if (void* handle = DlopenMem(m.memfd, RTLD_NOW); - void* entry = handle ? dlsym(handle, "zygisk_module_entry") : nullptr) { - modules.emplace_back(i, handle, entry); - } + auto ms = zygiskd::ReadModules(); + auto size = ms.size(); + for (size_t i = 0; i < size; i++) { + auto &m = ms[i]; + + void *handle = dlopen(m.path.c_str(), RTLD_NOW); + if (!handle) { + LOGE("Failed to load module [%s]: %s", m.path.c_str(), dlerror()); + + continue; } - for (auto &m : modules) { - m.onLoad(env); - if (flags[APP_SPECIALIZE]) { - m.preAppSpecialize(args.app); - } else if (flags[SERVER_FORK_AND_SPECIALIZE]) { - m.preServerSpecialize(args.server); - } + void *entry = dlsym(handle, "zygisk_module_entry"); + if (!entry) { + LOGE("Failed to find entry point in module [%s]: %s", m.path.c_str(), dlerror()); + + dlclose(handle); + + continue; } + + modules.emplace_back(i, handle, entry); + } + + for (auto &m : modules) { + m.onLoad(env); + if (flags[APP_SPECIALIZE]) m.preAppSpecialize(args.app); + else if (flags[SERVER_FORK_AND_SPECIALIZE]) m.preServerSpecialize(args.server); + } } void ZygiskContext::run_modules_post() { @@ -598,11 +608,9 @@ void ZygiskContext::run_modules_post() { 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); - } + if (flags[APP_SPECIALIZE]) m.postAppSpecialize(args.app); + else if (flags[SERVER_FORK_AND_SPECIALIZE]) m.postServerSpecialize(args.server); + if (m.tryUnload()) modules_unloaded++; } diff --git a/zygiskd/src/zygiskd.c b/zygiskd/src/zygiskd.c index 429c143..44fa9fc 100644 --- a/zygiskd/src/zygiskd.c +++ b/zygiskd/src/zygiskd.c @@ -537,14 +537,28 @@ void zygiskd_start(char *restrict argv[]) { ssize_t ret = write_size_t(client_fd, clen); ASSURE_SIZE_WRITE_BREAK("ReadModules", "len", ret, sizeof(clen)); + enum Architecture arch = get_arch(); + + char arch_str[32]; + switch (arch) { + case ARM64: { strcpy(arch_str, "arm64-v8a"); break; } + case X86_64: { strcpy(arch_str, "x86_64"); break; } + case ARM32: { strcpy(arch_str, "armeabi-v7a"); break; } + case X86: { strcpy(arch_str, "x86"); break; } + } + for (size_t i = 0; i < clen; i++) { - if (write_string(client_fd, context.modules[i].name) == -1) { - LOGE("Failed writing module name.\n"); + char lib_path[PATH_MAX]; + snprintf(lib_path, PATH_MAX, "/data/adb/modules/%s/zygisk/%s.so", context.modules[i].name, arch_str); + + if (write_string(client_fd, lib_path) == -1) { + LOGE("Failed writing module path.\n"); break; } - if (write_fd(client_fd, context.modules[i].lib_fd) == -1) { - LOGE("Failed writing module fd.\n"); + + if (write_string(client_fd, context.modules[i].name) == -1) { + LOGE("Failed writing module name.\n"); break; }