Feat: patch dylib for game dlopen calls

Now that game can directly load macOS's JNA native library,
libjnidispatch is removed.
This commit is contained in:
khanhduytran0 committed 2024-06-09 21:53:15 +07:00
1 parent 77fa8b1c99
commit ec04885ce5
7 files changed
+89 -2

No files matched your search

+1
View File
@@ -99,6 +99,7 @@ target_link_libraries(PojavAccountJNI)
# PojavLauncher
add_executable(PojavLauncher
dyld_bypass_validation.m
dyld_patch_platform.m
main.m
main_hook.m
JavaLauncher.m
-1
View File
@@ -178,7 +178,6 @@ int launchJVM(NSString *username, id launchTarget, int width, int height, int mi
margv[++margc] = "-Xms128M";
margv[++margc] = [NSString stringWithFormat:@"-Xmx%dM", allocmem].UTF8String;
margv[++margc] = [NSString stringWithFormat:@"-Djava.library.path=%@/Frameworks", NSBundle.mainBundle.bundlePath].UTF8String;
margv[++margc] = [NSString stringWithFormat:@"-Djna.boot.library.path=%@/Frameworks", NSBundle.mainBundle.bundlePath].UTF8String;
margv[++margc] = [NSString stringWithFormat:@"-Duser.dir=%@", gameDir].UTF8String;
margv[++margc] = [NSString stringWithFormat:@"-Duser.home=%s", getenv("POJAV_HOME")].UTF8String;
margv[++margc] = [NSString stringWithFormat:@"-Duser.timezone=%@", NSTimeZone.localTimeZone.name].UTF8String;
+70
View File
@@ -0,0 +1,70 @@
#import <Foundation/Foundation.h>
#include <libgen.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <sys/mman.h>
#include <sys/stat.h>
extern int dyld_get_active_platform();
static BOOL PLPatchMachOPlatformForSlice(const char *path, struct mach_header_64 *header) {
uint8_t *imageHeaderPtr = (uint8_t*)header + sizeof(struct mach_header_64);
struct load_command *command = (struct load_command *)imageHeaderPtr;
for(int i = 0; i < header->ncmds; i++) {
if (command->cmd == LC_BUILD_VERSION) {
struct build_version_command *buildver = (struct build_version_command *)command;
int activePlatform = dyld_get_active_platform();
if (buildver->platform == activePlatform) return NO; // it is already set, stop
buildver->platform = activePlatform; // set to current platform
} else if (command->cmd == LC_LOAD_DYLIB) {
struct dylib_command *dylib = (struct dylib_command *)command;
char *dylibName = (void *)dylib + dylib->dylib.name.offset;
char *verPtr = strstr(dylibName, "/Versions/");
if (verPtr) {
// Remove "/Versions/X"
int lastComponentLen = strlen(dylibName) - (verPtr - dylibName) - 11;
memmove(verPtr, verPtr + 11, lastComponentLen);
verPtr[lastComponentLen] = '\0';
}
}
command = (struct load_command *)((void *)command + command->cmdsize);
}
return YES;
}
BOOL PLPatchMachOPlatformForFile(const char *path) {
int fd = open(path, O_RDWR, (mode_t)0600);
if (fd == -1) return NO;
struct stat s;
fstat(fd, &s);
void *map = mmap(NULL, s.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (!map) {
close(fd);
return NO;
}
BOOL patched = NO;
uint32_t magic = *(uint32_t *)map;
if (magic == FAT_CIGAM) {
// Find compatible slice
struct fat_header *header = (struct fat_header *)map;
struct fat_arch *arch = (struct fat_arch *)(map + sizeof(struct fat_header));
for (int i = 0; i < OSSwapInt32(header->nfat_arch); i++) {
if (OSSwapInt32(arch->cputype) == CPU_TYPE_ARM64) {
NSLog(@"[PojavLauncher] Patching %s", path);
patched |= PLPatchMachOPlatformForSlice(path, (struct mach_header_64 *)(map + OSSwapInt32(arch->offset)));
}
arch = (struct fat_arch *)((void *)arch + sizeof(struct fat_arch));
}
} else if (magic == MH_MAGIC_64 && ((struct mach_header_64 *)map)->cputype == CPU_TYPE_ARM64) {
patched = PLPatchMachOPlatformForSlice(path, (struct mach_header_64 *)map);
}
if (patched) msync(map, s.st_size, MS_SYNC);
munmap(map, s.st_size);
close(fd);
return patched;
}
+16
View File
@@ -8,6 +8,7 @@
void (*orig_abort)();
void (*orig_exit)(int code);
void* (*orig_dlopen)(const char* path, int mode);
int (*orig_open)(const char *path, int oflag, ...);
void handle_fatal_exit(int code) {
@@ -54,13 +55,27 @@ void hooked_exit(int code) {
}
handle_fatal_exit(code);
/*
if (runtimeJavaVMPtr != NULL) {
(*runtimeJavaVMPtr)->DestroyJavaVM(runtimeJavaVMPtr);
}
*/
orig_exit(code);
}
void* hooked_dlopen(const char* path, int mode) {
const char *home = getenv("POJAV_HOME");
// Only proceed to check if dylib is in the home dir
// Path input from jvm is absolute path(?)
if (!path || strncmp(path, home, strlen(home))) {
return orig_dlopen(path, mode);
}
PLPatchMachOPlatformForFile(path);
return orig_dlopen(path, mode);
}
int hooked_open(const char *path, int oflag, ...) {
va_list args;
va_start(args, oflag);
@@ -78,6 +93,7 @@ void init_hookFunctions() {
{"abort", hooked_abort, (void *)&orig_abort},
{"__assert_rtn", hooked___assert_rtn, NULL},
{"exit", hooked_exit, (void *)&orig_exit},
{"dlopen", hooked_dlopen, (void *)&orig_dlopen},
{"open", hooked_open, (void *)&orig_open}
};
rebind_symbols(rebindings, sizeof(rebindings)/sizeof(struct rebinding));
Binary file not shown.
+2
View File
@@ -63,6 +63,8 @@ void init_hookFunctions();
void init_hookUIKitConstructor();
void init_setupMultiDir();
BOOL PLPatchMachOPlatformForFile(const char *path);
UIWindow* currentWindow();
UIWindow* currentWindowInScene(BOOL external);
UIViewController* currentVC();
-1
View File
@@ -96,7 +96,6 @@ PojavLauncher is amazing, and surprisingly stable, and it wouldn't be this way w
- [LWJGLX](https://github.com/PojavLauncherTeam/lwjglx) (LWJGL2 API compatibility layer for LWJGL3): unknown license.
- [DBNumberedSlider](https://github.com/khanhduytran0/DBNumberedSlider): [Apache 2.0 License](https://github.com/immago/DBNumberedSlider/blob/master/LICENSE)
- [fishhook](https://github.com/khanhduytran0/fishhook): [BSD-3 License](https://github.com/facebook/fishhook/blob/main/LICENSE).
- [Java Native Access](https://github.com/java-native-access/jna): [Apache 2.0 License](https://github.com/java-native-access/jna/blob/master/LICENSE).
- [shaderc](https://github.com/khanhduytran0/shaderc) (used by Vulkan rendering mods): [Apache 2.0 License](https://github.com/google/shaderc/blob/main/LICENSE).
- [NRFileManager](https://github.com/mozilla-mobile/firefox-ios/tree/b2f89ac40835c5988a1a3eb642982544e00f0f90/ThirdParty/NRFileManager): [MPL-2.0 License](https://www.mozilla.org/en-US/MPL/2.0)
- [AltKit](https://github.com/rileytestut/AltKit)