add: Android 9 support (#117)

This commit makes ReZygisk load Zygisk libraries directly, not utilizing memfd, as it doesn't exist in older versions of Android.
This commit is contained in:
Reveny
2025-03-22 23:12:24 +01:00
committed by GitHub
parent bc6cf67c7b
commit 92e2f528a9
5 changed files with 34 additions and 32 deletions

View File

@@ -6,6 +6,7 @@
#include <android/dlext.h> #include <android/dlext.h>
#include "dl.h" #include "dl.h"
#include "files.hpp"
#include "logging.h" #include "logging.h"
extern "C" [[gnu::weak]] struct android_namespace_t* extern "C" [[gnu::weak]] struct android_namespace_t*
@@ -50,11 +51,22 @@ void* DlopenMem(int fd, int flags) {
.library_fd = fd .library_fd = fd
}; };
auto* handle = android_dlopen_ext("/jit-cache-zygisk", flags, &info); /* 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) { if (handle) {
LOGV("dlopen fd %d: %p", fd, handle); LOGV("dlopen fd %d: %p", fd, handle);
} else { } else {
LOGE("dlopen fd %d: %s", fd, dlerror()); LOGE("dlopen fd %d: %s", fd, dlerror());
} }
return handle; return handle;
} }

View File

@@ -120,3 +120,18 @@ sDIR make_dir(DIR *dp) {
sFILE make_file(FILE *fp) { sFILE make_file(FILE *fp) {
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; }); return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
} }
int get_path_from_fd(int fd, char *buf, size_t size) {
if (fd < 0 || !buf || size == 0) return -1;
/* NOTE: We assume that the path is always at /data/adb/modules/xxx
which should never be longer than 128 chars. */
char proc_path[128];
snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", fd);
ssize_t len = readlink(proc_path, buf, size - 1);
if (len == -1) return -1;
buf[len] = '\0';
return 0;
}

View File

@@ -2,6 +2,7 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <unistd.h>
struct mount_info { struct mount_info {
unsigned int id; unsigned int id;
@@ -26,6 +27,8 @@ void file_readline(const char *file, const std::function<bool(std::string_view)>
std::vector<mount_info> parse_mount_info(const char *pid); std::vector<mount_info> parse_mount_info(const char *pid);
int get_path_from_fd(int fd, char *buf, size_t size);
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>; using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>; using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
sDIR make_dir(DIR *dp); sDIR make_dir(DIR *dp);

View File

@@ -591,7 +591,7 @@ void ZygiskContext::run_modules_post() {
if (modules.size() > 0) { if (modules.size() > 0) {
LOGD("modules unloaded: %zu/%zu", modules_unloaded, modules.size()); LOGD("modules unloaded: %zu/%zu", modules_unloaded, modules.size());
clean_trace("jit-cache-zygisk", modules.size(), modules_unloaded, true); clean_trace("/data/adb", modules.size(), modules_unloaded, true);
} }
} }
@@ -762,7 +762,7 @@ void clean_trace(const char* path, size_t load, size_t unload, bool spoof_maps)
// spoofing map names is futile in Android, we do it simply // spoofing map names is futile in Android, we do it simply
// to avoid Zygisk detections based on string comparison // to avoid Zygisk detections based on string comparison
for (auto &map : lsplt::MapInfo::Scan()) { for (auto &map : lsplt::MapInfo::Scan()) {
if (strstr(map.path.c_str(), path)) if (strstr(map.path.c_str(), path) && strstr(map.path.c_str(), "libzygisk") == 0)
{ {
void *addr = (void *)map.start; void *addr = (void *)map.start;
size_t size = map.end - map.start; size_t size = map.end - map.start;

View File

@@ -83,35 +83,7 @@ int create_library_fd(const char *restrict so_path) {
return -1; return -1;
} }
/* INFO: This is required as older implementations of glibc may not return so_fd;
have the memfd_create function call, causing a crash. */
int memfd = (int)syscall(SYS_memfd_create, "jit-cache-zygisk", MFD_ALLOW_SEALING);
if (memfd == -1) {
LOGE("Failed creating memfd: %s\n", strerror(errno));
return -1;
}
if (sendfile(memfd, so_fd, NULL, (size_t)so_size) == -1) {
LOGE("Failed copying so file to memfd: %s\n", strerror(errno));
close(so_fd);
close(memfd);
return -1;
}
close(so_fd);
if (fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) == -1) {
LOGE("Failed sealing memfd: %s\n", strerror(errno));
close(memfd);
return -1;
}
return memfd;
} }
/* WARNING: Dynamic memory based */ /* WARNING: Dynamic memory based */