From 99b8d408fbe0bd92e4d04f5d10ba2c5ea32dcafd Mon Sep 17 00:00:00 2001 From: tomikun <60690056+alexytomi@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:21:22 +0800 Subject: [PATCH] almost woorking --- app_pojavlauncher/src/main/jni/Android.mk | 3 + .../elf_soname_patcher.c | 2 +- .../nsbypass.c | 20 ++- .../nsbypass_dlfcn.c | 99 ++++++++--- .../src/main/jni/driver_helper/nsbypass.c | 164 +----------------- .../src/main/jni/driver_helper/nsbypass.h | 6 +- app_pojavlauncher/src/main/jni/egl_bridge.c | 17 +- .../nsbypass.h | 3 +- .../platform.h | 0 .../jni/include/fasthook/nsbypass_dlfcn.h | 2 +- 10 files changed, 112 insertions(+), 204 deletions(-) rename app_pojavlauncher/src/main/jni/{ => include}/android_linker_namespace_bypass/platform.h (100%) diff --git a/app_pojavlauncher/src/main/jni/Android.mk b/app_pojavlauncher/src/main/jni/Android.mk index 2e9f9c536..4df284826 100644 --- a/app_pojavlauncher/src/main/jni/Android.mk +++ b/app_pojavlauncher/src/main/jni/Android.mk @@ -37,6 +37,7 @@ LOCAL_MODULE := pojavexec # LOCAL_CFLAGS += -DDEBUG # -DGLES_TEST LOCAL_C_INCLUDES := $(LOCAL_PATH)/include +LOCAL_SHARED_LIBRARIES := android_linker_namespace_bypass LOCAL_SRC_FILES := \ bigcoreaffinity.c \ egl_bridge.c \ @@ -76,6 +77,8 @@ include $(BUILD_SHARED_LIBRARY) #ifeq ($(TARGET_ARCH_ABI),arm64-v8a) include $(CLEAR_VARS) LOCAL_MODULE := linkerhook +LOCAL_SHARED_LIBRARIES := android_linker_namespace_bypass +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_SRC_FILES := driver_helper/hook.c LOCAL_LDFLAGS := -z global include $(BUILD_SHARED_LIBRARY) diff --git a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/elf_soname_patcher.c b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/elf_soname_patcher.c index 25169466b..d300a3a87 100644 --- a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/elf_soname_patcher.c +++ b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/elf_soname_patcher.c @@ -1,4 +1,4 @@ -#include "platform.h" +#include "android_linker_namespace_bypass/platform.h" #include "android_linker_namespace_bypass/elf_soname_patcher.h" // Used the following as reference diff --git a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass.c b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass.c index f981cd958..70930f39f 100644 --- a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass.c +++ b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass.c @@ -16,21 +16,25 @@ #include #include #include "fasthook/nsbypass_dlfcn.h" -#include "platform.h" +#include "android_linker_namespace_bypass/platform.h" #include "android_linker_namespace_bypass/elf_soname_patcher.h" #include "android_linker_namespace_bypass/nsbypass.h" // libdl_android.so and ld-android.so are aliases to linker64 impl -// libdl_android.so provides WEAK symbols and missing dlFuncs. Don't use it. +// libdl_android.so provides only the namespace funcs except __loader_android_link_namespaces_all_libs // ld-android.so is more complete, so fallback to that if dl functions can be acquired. // This means a configuration of libdl + ld-android is possible // The preferred configuration on arm64 will be libdl + linker64 +// The preferred configuration on other arches will be linker64 // We have two sources for this, linker64/linker or libdl.so via ARM64 shenanigans private_dl_funcs get_dl_functions(){ private_dl_funcs dlFuncs; - void* linkerHandle = nsbypass_dlopen(LINKER_PATH, 0); + // Expecting /apex/com.android.runtime/bin/linker64 but not 100% sure on that so just linker64 + void* linkerHandle = nsbypass_dlopen("linker64", 0); + // If that fails, do try this funny (this works, don't ask why idk either) + if (!linkerHandle) linkerHandle = dlopen("libdl.so", RTLD_LAZY); // First attempt the normal libadrenotools method (ARM64 shenanigans) #if (defined __aarch64__) // This searches libdl which has WEAK funcs. @@ -39,11 +43,11 @@ private_dl_funcs get_dl_functions(){ dlFuncs.dlclose = find_branch_label(&dlclose); dlFuncs.dlsym = find_branch_label(&dlsym); #endif - // If that fails, try looking for it in memory - if (!dlFuncs.dlopen) dlFuncs.dlopen = nsbypass_dlsym(linkerHandle, "__loader_dlopen"); - if (!dlFuncs.dlopen_ext) dlFuncs.dlopen_ext = nsbypass_dlsym(linkerHandle, "__loader_android_dlopen_ext"); - if (!dlFuncs.dlclose) dlFuncs.dlclose = nsbypass_dlsym(linkerHandle, "__loader_dlclose"); - if (!dlFuncs.dlsym) dlFuncs.dlsym = nsbypass_dlsym(linkerHandle, "__loader_dlsym"); + + if (!dlFuncs.dlopen) dlFuncs.dlopen = dlsym(linkerHandle, "__loader_dlopen"); + if (!dlFuncs.dlopen_ext) dlFuncs.dlopen_ext = dlsym(linkerHandle, "__loader_android_dlopen_ext"); + if (!dlFuncs.dlclose) dlFuncs.dlclose = dlsym(linkerHandle, "__loader_dlclose"); + if (!dlFuncs.dlsym) dlFuncs.dlsym = dlsym(linkerHandle, "__loader_dlsym"); // Don't dlclose that, it's not our property. return dlFuncs; } diff --git a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass_dlfcn.c b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass_dlfcn.c index c56a4458f..8d8f300b7 100644 --- a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass_dlfcn.c +++ b/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/nsbypass_dlfcn.c @@ -19,7 +19,9 @@ // SOFTWARE. // Copyright (c) 2026 alexytomi -// Modified to remove redundancies within nsbypass library +// Modified to remove redundancies within nsbypass library and renaming things +// Added relative file support to nsbypass_dlopen +// Redirect these functions to the real implementations on Android 6 and below // This is not actually dlfunc. It doesn't load anything. // It bypasses normal linker restrictions by searching the memory for already loaded symbols. @@ -33,10 +35,11 @@ #include #include #include -#include "platform.h" +#include "android_linker_namespace_bypass/platform.h" #include #include #include +#include #include "fasthook/nsbypass_dlfcn.h" struct ctx { @@ -50,7 +53,24 @@ struct ctx { off_t bias; }; +typedef int (*get_device_api_level_fn)(void); + +// Namespace restrictions were added in android 7, stub to the normal funcs if below that +static int is_android_6_or_lower(void) +{ + void *symbol; + get_device_api_level_fn get_api_level; + symbol = dlsym(dlopen("libc.so", RTLD_LAZY), "android_get_device_api_level"); + if (symbol == NULL) { + // android_get_device_api_level() was added in API 24. If it's not here then we are lower. + return 1; + } + get_api_level = (get_device_api_level_fn)symbol; + return get_api_level() < 24 ? 1 : 0; +} + int nsbypass_dlclose(void *handle) { + if (is_android_6_or_lower()) return dlclose(handle); if (handle) { struct ctx *ctx = (struct ctx *) handle; if (ctx->dynsym) free(ctx->dynsym); /* we're saving dynsym and dynstr */ @@ -62,9 +82,12 @@ int nsbypass_dlclose(void *handle) { return 0; } -void *nsbypass_dlopen(const char *libpath, int flags) { +void *nsbypass_dlopen(const char *libPath, int flags) { + if (is_android_6_or_lower()) return dlopen(libPath, flags); FILE *maps; - char buff[256]; + // Increase the buffer because we added searching for absolute file. + // 256 might not be enough buffer to get the whole path in. + char mapsSearchBuff[2048]; struct ctx *ctx = 0; off_t load_addr, size; int k, fd = -1, found = 0; @@ -76,34 +99,63 @@ void *nsbypass_dlopen(const char *libpath, int flags) { maps = fopen("/proc/self/maps", "r"); if (!maps) fatal("failed to open maps"); - while (!found && fgets(buff, sizeof(buff), maps)) - if (strstr(buff, "r-xp") && strstr(buff, libpath)) found = 1; + while (!found && fgets(mapsSearchBuff, sizeof(mapsSearchBuff), maps)) + if (strstr(mapsSearchBuff, "r-xp") && strstr(mapsSearchBuff, libPath)) found = 1; fclose(maps); - if (!found) fatal("%s not found in my userspace", libpath); + // If user didn't prove an absolute path we have to find the actual full path ourselves + // This is NOT the file path where the file lives in, so scan memory again. + if (libPath[0] != '/') { + // Looks through the current buffer which contains the libPath and the path + // mapsSearchBuff probably looks like + // 7a8d366000-7a8d453000 r-xp 00039000 07:60 16 /apex/com.android.runtime/bin/linker64 + char *libPathStart = strstr(mapsSearchBuff, libPath); // at ..bin/[l]inker64 + if (libPathStart != NULL) { + char *pathStart = libPathStart; + // Move backward until we find the spaces area. + while (pathStart > mapsSearchBuff && + pathStart[-1] != ' ' && + pathStart[-1] != '\t') { + --pathStart; + } + // Hopefully this is the start of the path + if (*pathStart == '/') { + libPath = pathStart; + } else { + fatal( + "An error happened while resolving the full path of %s; " + "searching stopped at %s", + libPath, + pathStart + ); + } + } + } - if (sscanf(buff, "%lx", &load_addr) != 1) - fatal("failed to read load address for %s", libpath); + if (!found) fatal("%s not found in my userspace", libPath); - LOGI("%s loaded in Android at 0x%08lx", libpath, load_addr); + if (sscanf(mapsSearchBuff, "%lx", &load_addr) != 1) + fatal("failed to read load address for %s", libPath); + + LOGI("%s loaded in Android at 0x%08lx", libPath, load_addr); /* Now, mmap the same library once again */ - fd = open(libpath, O_RDONLY); - if (fd < 0) fatal("failed to open %s", libpath); + fd = open(libPath, O_RDONLY); + if (fd < 0) fatal("failed to open %s", libPath); size = lseek(fd, 0, SEEK_END); - if (size <= 0) fatal("lseek() failed for %s", libpath); + if (size <= 0) fatal("lseek() failed for %s", libPath); elf = (ELF_EHDR *) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); close(fd); fd = -1; - if (elf == MAP_FAILED) fatal("mmap() failed for %s", libpath); + if (elf == MAP_FAILED) fatal("mmap() failed for %s", libPath); ctx = (struct ctx *) calloc(1, sizeof(struct ctx)); - if (!ctx) fatal("no memory for %s", libpath); + if (!ctx) fatal("no memory for %s", libPath); ctx->load_addr = (void *) load_addr; shoff = ((void *) elf) + elf->e_shoff; @@ -120,17 +172,17 @@ void *nsbypass_dlopen(const char *libpath, int flags) { switch (sh->sh_type) { case SHT_DYNSYM: - if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libpath); /* .dynsym */ + if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libPath); /* .dynsym */ ctx->dynsym = malloc(sh->sh_size); - if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libpath); + if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libPath); memcpy(ctx->dynsym, ((void *) elf) + sh->sh_offset, sh->sh_size); ctx->dynsym_num = (sh->sh_size / sizeof(ELF_SYM)); break; case SHT_SYMTAB: - if (ctx->symtab) fatal("%s: duplicate SYMTAB sections", libpath); /* .symtab */ + if (ctx->symtab) fatal("%s: duplicate SYMTAB sections", libPath); /* .symtab */ ctx->symtab = malloc(sh->sh_size); - if (!ctx->symtab) fatal("%s: no memory for .symtab", libpath); + if (!ctx->symtab) fatal("%s: no memory for .symtab", libPath); memcpy(ctx->symtab, ((void *) elf) + sh->sh_offset, sh->sh_size); ctx->symtab_num = (sh->sh_size / sizeof(ELF_SYM)); break; @@ -139,12 +191,12 @@ void *nsbypass_dlopen(const char *libpath, int flags) { if(!strcmp(shstr+sh->sh_name,".dynstr")) { if (ctx->dynstr) break; /* .dynstr is guaranteed to be the first STRTAB */ ctx->dynstr = malloc(sh->sh_size); - if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libpath); + if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libPath); memcpy(ctx->dynstr, ((void *) elf) + sh->sh_offset, sh->sh_size); }else if(!strcmp(shstr+sh->sh_name,".strtab")) { if (ctx->strtab) break; ctx->strtab = malloc(sh->sh_size); - if (!ctx->strtab) fatal("%s: no memory for .strtab", libpath); + if (!ctx->strtab) fatal("%s: no memory for .strtab", libPath); memcpy(ctx->strtab, ((void *) elf) + sh->sh_offset, sh->sh_size); } break; @@ -161,11 +213,11 @@ void *nsbypass_dlopen(const char *libpath, int flags) { munmap(elf, size); elf = 0; - if (!ctx->dynstr || !ctx->dynsym) fatal("dynamic sections not found in %s", libpath); + if (!ctx->dynstr || !ctx->dynsym) fatal("dynamic sections not found in %s", libPath); #undef fatal - LOGD("%s: ok, dynsym = %p, dynstr = %p symtab = %p strtab = %p", libpath, ctx->dynsym, ctx->dynstr, ctx->symtab, ctx->strtab); + LOGD("%s: ok, dynsym = %p, dynstr = %p symtab = %p strtab = %p", libPath, ctx->dynsym, ctx->dynstr, ctx->symtab, ctx->strtab); return ctx; @@ -177,6 +229,7 @@ void *nsbypass_dlopen(const char *libpath, int flags) { } void *nsbypass_dlsym(void *handle, const char *name) { + if (is_android_6_or_lower()) return dlsym(handle, name); int k; struct ctx *ctx = (struct ctx *) handle; ELF_SYM *dynsym = (ELF_SYM *) ctx->dynsym; diff --git a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c index 08bcc8ef3..4f5f7cb2d 100644 --- a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c +++ b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c @@ -1,7 +1,7 @@ // // Created by maks on 05.06.2023. // -#include "nsbypass.h" + #include #include #include @@ -16,6 +16,7 @@ #include #include #include +#include "android_linker_namespace_bypass/nsbypass.h" /* upper 6 bits of an ARM64 instruction are the instruction name */ #define OP_MS 0b11111100000000000000000000000000 @@ -32,70 +33,11 @@ #define ELF_SYM Elf64_Sym //#define ADRENO_POSSIBLE - -typedef void* (*loader_dlopen_t)(const char* filename, int flags, const void* caller_addr); - -typedef struct android_namespace_t* (*ld_android_create_namespace_t)( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct android_namespace_t* parent, const void* caller_addr); - -typedef void* (*ld_android_link_namespaces_t)(struct android_namespace_t* namespace_from, - struct android_namespace_t* namespace_to, - const char* shared_libs_sonames); - -static ld_android_create_namespace_t android_create_namespace; -static struct android_namespace_t* driver_namespace; - -struct android_namespace_t* local_android_create_namespace( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct android_namespace_t* parent) { - void* caller = __builtin_return_address(0); - return android_create_namespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent, caller); -} - -// Find the first "branch to label" function in the function provided in func_start -static void* find_branch_label(void* func_start) { - long page_size = sysconf(_SC_PAGESIZE); - // round down the pointer to get the start of the function's page - void* func_page_start = (void*)(((uintptr_t)func_start) & ~(page_size-1)); - // remap to r-x to bypass "execute only" protections on MIUI - mprotect(func_page_start, page_size, PROT_READ | PROT_EXEC); - uint32_t* bl_addr = func_start; - // search for the "branch to label" opcode - while((*bl_addr & OP_MS) != BL_OP) { - bl_addr++; // walk through memory until we find it or die - } - // offset the address to find where the "branch to label" instrunction - // points to. - return ((char*)bl_addr) + (*bl_addr & BL_IM) * 4; -} - -bool linker_ns_load(const char* lib_search_path) { - long page_size = sysconf(_SC_PAGESIZE); -#ifndef ADRENO_POSSIBLE - return false; -#else - // Makes bytehook stop being all crashy about hooky - if(driver_namespace != NULL) return true; - - loader_dlopen_t loader_dlopen = find_branch_label(&dlopen); - // reprotecting the functions removes protection from indirect jumps - mprotect(loader_dlopen, page_size, PROT_WRITE | PROT_READ | PROT_EXEC); - void* ld_android_handle = loader_dlopen("ld-android.so", RTLD_LAZY, &dlopen); - if(ld_android_handle == NULL) { - return false; - } - // load the two functions we need - android_create_namespace = dlsym(ld_android_handle, "__loader_android_create_namespace"); - ld_android_link_namespaces_t android_link_namespaces = dlsym(ld_android_handle, "__loader_android_link_namespaces"); - if(android_create_namespace == NULL || android_link_namespaces == NULL) { - dlclose(ld_android_handle); - return false; - } +bool linker_ns_load(const char* lib_search_path, struct android_namespace_t** ns) { // assemble the full path search path char full_path[strlen(SEARCH_PATH) + strlen(lib_search_path) + 2 + 1]; sprintf(full_path, "%s:%s", SEARCH_PATH, lib_search_path); - driver_namespace = local_android_create_namespace("pojav-driver", + *ns = g_linkerFuncs.create_namespace("pojav-driver", full_path, full_path, 3 /* TYPE_SHAFED | TYPE_ISOLATED */, @@ -108,102 +50,12 @@ bool linker_ns_load(const char* lib_search_path) { // a lot of android versions // FoldCraft got trolled because they copied the // old broken code verbatim and didn't even test it thoroughly - android_link_namespaces(driver_namespace, NULL, "ld-android.so"); + g_linkerFuncs.link_namespaces(*ns, NULL, "ld-android.so"); // Also establish links to use the libnativeloader(_lazy).so libraries // from the global namespace. This is a workaround for an EMUI issue where // the newly loaded libnativeloader_lazy for some unknown reason links // to itself and causes a deadlock when loading the vulkan driver. - android_link_namespaces(driver_namespace, NULL, "libnativeloader.so"); - android_link_namespaces(driver_namespace, NULL, "libnativeloader_lazy.so"); - dlclose(ld_android_handle); + g_linkerFuncs.link_namespaces(*ns, NULL, "libnativeloader.so"); + g_linkerFuncs.link_namespaces(*ns, NULL, "libnativeloader_lazy.so"); return true; -#endif -} - -void* linker_ns_dlopen(const char* name, int flag) { -#ifndef ADRENO_POSSIBLE - return NULL; -#else - android_dlextinfo dlextinfo; - dlextinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; - dlextinfo.library_namespace = driver_namespace; - return android_dlopen_ext(name, flag, &dlextinfo); -#endif -} - - -/** - * @brief Overwrites the first three characters of a soname - * @note IMPORTANT: The supplied soname patch will overwrite the first strlen(sonamePatch) chars of the soname - * @param elfPath Full path to the elf to patch - * @param targetFd FD to use for storing the patched library - * @return True on success - */ -bool patch_elf_soname(int patchfd, int realfd, uint16_t patchid) { - struct stat realstat; - if(fstat(realfd, &realstat)) return false; - if(ftruncate64(patchfd, realstat.st_size) == -1) return false; - char* target = mmap(NULL, realstat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, patchfd, 0); - if(!target) return false; - if(read(realfd, target, realstat.st_size) != realstat.st_size) { - munmap(target, realstat.st_size); - return false; - } - close(realfd); - - ELF_EHDR *ehdr = (ELF_EHDR*)target; - ELF_SHDR *shdr = (ELF_SHDR*)(target + ehdr->e_shoff); - // Iterate over section headers to find the .dynamic section - for(ELF_HALF i = 0; i < ehdr->e_shnum; i++) { - ELF_SHDR *hdr = &shdr[i]; - if(hdr->sh_type == SHT_DYNAMIC) { - char* strtab = target + shdr[hdr->sh_link].sh_offset; - ELF_DYN *dynEntries = (ELF_DYN*)(target + hdr->sh_offset); - - // Iterate over .dynamic entries to find DT_SONAME - for(ELF_XWORD k = 0; k < (hdr->sh_size / hdr->sh_entsize);k++) { - ELF_DYN* dynEntry = &dynEntries[k]; - if(dynEntry->d_tag == DT_SONAME) { - char* soname = strtab + dynEntry->d_un.d_val; - char sprb[4]; - // Partially replace the old soname with the soname patch - snprintf(sprb, 4, "%03x", patchid); - memcpy(soname, sprb, 3); - munmap(target, realstat.st_size); - return true; - } - } - } - } - return false; -} - -void* linker_ns_dlopen_unique(const char* tmpdir, const char* name, int flags) { -#ifndef ADRENO_POSSIBLE - return NULL; -#else - char pathbuf[PATH_MAX]; - static uint16_t patch_id; - int patch_fd, real_fd; - snprintf(pathbuf,PATH_MAX,"%s/%d_p.so", tmpdir, patch_id); - patch_fd = open(pathbuf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - if(patch_fd == -1) return NULL; - snprintf(pathbuf,PATH_MAX,"%s/%s", SEARCH_PATH, name); - real_fd = open(pathbuf, O_RDONLY); - if(real_fd == -1) { - close(patch_fd); - return NULL; - } - if(!patch_elf_soname(patch_fd, real_fd, patch_id)) { - close(patch_fd); - close(real_fd); - return NULL; - } - android_dlextinfo extinfo; - extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE | ANDROID_DLEXT_USE_LIBRARY_FD; - extinfo.library_fd = patch_fd; - extinfo.library_namespace = driver_namespace; - snprintf(pathbuf, PATH_MAX, "/proc/self/fd/%d", patch_fd); - return android_dlopen_ext(pathbuf, flags, &extinfo); -#endif -} +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h index fb9e1c397..905ea77e2 100644 --- a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h +++ b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h @@ -7,9 +7,7 @@ #define POJAVLAUNCHER_NSBYPASS_H #include - -bool linker_ns_load(const char* lib_search_path); -void* linker_ns_dlopen(const char* name, int flag); -void* linker_ns_dlopen_unique(const char* tmpdir, const char* name, int flag); +struct android_namespace_t; +bool linker_ns_load(const char* lib_search_path, struct android_namespace_t** ns); #endif //POJAVLAUNCHER_NSBYPASS_H diff --git a/app_pojavlauncher/src/main/jni/egl_bridge.c b/app_pojavlauncher/src/main/jni/egl_bridge.c index 60d0be09a..a6d9076a9 100644 --- a/app_pojavlauncher/src/main/jni/egl_bridge.c +++ b/app_pojavlauncher/src/main/jni/egl_bridge.c @@ -13,7 +13,7 @@ #include #include "ctxbridges/osmesa_loader.h" #include "driver_helper/nsbypass.h" - +#include "android_linker_namespace_bypass/nsbypass.h" #ifdef GLES_TEST #include #endif @@ -96,23 +96,21 @@ Java_net_kdt_pojavlaunch_utils_JREUtils_releaseBridgeWindow(ABI_COMPAT JNIEnv *e EXTERNAL_API void* pojavGetCurrentContext() { return br_get_current(); } - -//#define ADRENO_POSSIBLE -#ifdef ADRENO_POSSIBLE +static struct android_namespace_t* driver_namespace; void* load_turnip_vulkan() { if(getenv("POJAV_LOAD_TURNIP") == NULL) return NULL; const char* native_dir = getenv("POJAV_NATIVEDIR"); const char* cache_dir = getenv("TMPDIR"); - if(!linker_ns_load(native_dir)) return NULL; - void* linkerhook = linker_ns_dlopen("liblinkerhook.so", RTLD_LOCAL | RTLD_NOW); + if(driver_namespace == NULL && !linker_ns_load(native_dir, &driver_namespace)) return NULL; + void* linkerhook = linker_ns_dlopen("liblinkerhook.so", RTLD_LOCAL | RTLD_NOW, driver_namespace); if(linkerhook == NULL) return NULL; - void* turnip_driver_handle = linker_ns_dlopen("libvulkan_freedreno.so", RTLD_LOCAL | RTLD_NOW); + void* turnip_driver_handle = linker_ns_dlopen("libvulkan_freedreno.so", RTLD_LOCAL | RTLD_NOW, driver_namespace); if(turnip_driver_handle == NULL) { printf("AdrenoSupp: Failed to load Turnip!\n%s\n", dlerror()); dlclose(linkerhook); return NULL; } - void* dl_android = linker_ns_dlopen("libdl_android.so", RTLD_LOCAL | RTLD_LAZY); + void* dl_android = linker_ns_dlopen("libdl_android.so", RTLD_LOCAL | RTLD_LAZY, driver_namespace); if(dl_android == NULL) { dlclose(linkerhook); dlclose(turnip_driver_handle); @@ -127,10 +125,9 @@ void* load_turnip_vulkan() { return NULL; } linkerhook_pass_handles(turnip_driver_handle, android_dlopen_ext, android_get_exported_namespace); - void* libvulkan = linker_ns_dlopen_unique(cache_dir, "libvulkan.so", RTLD_LOCAL | RTLD_NOW); + void* libvulkan = linker_ns_dlopen_unique(cache_dir, SEARCH_PATH, "libvulkan.so", RTLD_LOCAL | RTLD_NOW, driver_namespace); return libvulkan; } -#endif static void set_vulkan_ptr(void* ptr) { char envval[64]; diff --git a/app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/nsbypass.h b/app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/nsbypass.h index a6bc1e68a..ac93753dd 100644 --- a/app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/nsbypass.h +++ b/app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/nsbypass.h @@ -5,6 +5,7 @@ #include #include #include +#include "android_linker_namespace_bypass/platform.h" #ifndef AMETHYST_NSBYPASS_H #define AMETHYST_NSBYPASS_H @@ -44,7 +45,7 @@ static void* find_branch_label(void* func_start) { // Reprotecting the functions removes (BTI) protection from indirect jumps // while technically out of scope of "find_branch_label", this is just // cleaner overall. - if (mprotect(t, page_size, PROT_WRITE | PROT_READ | PROT_EXEC) != 0) { + if (mprotect(align_ptr_to_pagesize(t), page_size, PROT_WRITE | PROT_READ | PROT_EXEC) != 0) { LOGW("Failed to remove BTI protection from private API page. This might fail.. %p", t); } return t; diff --git a/app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/platform.h b/app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/platform.h similarity index 100% rename from app_pojavlauncher/src/main/jni/android_linker_namespace_bypass/platform.h rename to app_pojavlauncher/src/main/jni/include/android_linker_namespace_bypass/platform.h diff --git a/app_pojavlauncher/src/main/jni/include/fasthook/nsbypass_dlfcn.h b/app_pojavlauncher/src/main/jni/include/fasthook/nsbypass_dlfcn.h index 31a52d4b1..5b45b09d0 100644 --- a/app_pojavlauncher/src/main/jni/include/fasthook/nsbypass_dlfcn.h +++ b/app_pojavlauncher/src/main/jni/include/fasthook/nsbypass_dlfcn.h @@ -3,7 +3,7 @@ // int nsbypass_dlclose(void *handle); -void *nsbypass_dlopen(const char *libpath, int flags); +void *nsbypass_dlopen(const char *libPath, int flags); void *nsbypass_dlsym(void *handle, const char *name); typedef int (*dlclose_function)(