mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2026-09-17 08:49:39 -04:00
almost woorking
This commit is contained in:
1 parent
bdacac412f
commit
99b8d408fb
10 files changed
+112
-204
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,21 +16,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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 <sys/mman.h>
|
||||
#include <elf.h>
|
||||
#include <android/log.h>
|
||||
#include "platform.h"
|
||||
#include "android_linker_namespace_bypass/platform.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#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;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Created by maks on 05.06.2023.
|
||||
//
|
||||
#include "nsbypass.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <android/dlext.h>
|
||||
#include <android/log.h>
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <elf.h>
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,7 @@
|
||||
#define POJAVLAUNCHER_NSBYPASS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
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
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <GL/osmesa.h>
|
||||
#include "ctxbridges/osmesa_loader.h"
|
||||
#include "driver_helper/nsbypass.h"
|
||||
|
||||
#include "android_linker_namespace_bypass/nsbypass.h"
|
||||
#ifdef GLES_TEST
|
||||
#include <GLES2/gl2.h>
|
||||
#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];
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <android/dlext.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#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;
|
||||
|
||||
File renamed without changes.
@@ -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)(
|
||||
|
||||
Reference in new issue
Block a user