You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user