remove: dl.cpp file and replace with "dlopen"

This commit replaces DlopenMem for dlopen, removing the need for "dl.cpp" file.
This commit is contained in:
ThePedroo
2025-04-05 15:36:39 -03:00
parent 886e2f8396
commit 52885faf8b
6 changed files with 52 additions and 114 deletions

View File

@@ -7,7 +7,6 @@
#include <fcntl.h>
#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);

View File

@@ -1,77 +0,0 @@
#include <cstdio>
#include <dlfcn.h>
#include <libgen.h>
#include <climits>
#include <cstring>
#include <android/dlext.h>
#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<void*>(&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;
}

View File

@@ -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 {

View File

@@ -1,7 +0,0 @@
#pragma once
#include <dlfcn.h>
void *DlopenExt(const char *path, int flags);
void *DlopenMem(int memfd, int flags);

View File

@@ -15,7 +15,6 @@
#include <sys/mman.h>
#include <unistd.h>
#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++;
}

View File

@@ -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;
}