From 269e5d0dfa9e634cb2eceead65fd14c17b984a5f Mon Sep 17 00:00:00 2001 From: RootHide <134120506+RootHide@users.noreply.github.com> Date: Sun, 15 Oct 2023 04:10:12 +0800 Subject: [PATCH] fix finding arch for mach-o (#265) * fix finding arch for mach-o (some fat mach-o may contain mach-o slices of both arm64e.v1 and arm64e.v2) * fix parameter and environment variable passing issues of exec* * fix PATH for execvP --- BaseBin/libjailbreak/src/macho.m | 10 ++++++---- BaseBin/systemhook/src/common.c | 9 +++++++-- BaseBin/systemhook/src/main.c | 28 ++++++++++++++++------------ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/BaseBin/libjailbreak/src/macho.m b/BaseBin/libjailbreak/src/macho.m index 06859a123..b6402b780 100644 --- a/BaseBin/libjailbreak/src/macho.m +++ b/BaseBin/libjailbreak/src/macho.m @@ -69,7 +69,7 @@ int64_t machoFindArch(FILE *machoFile, uint32_t subtypeToSearch) struct mach_header_64 mh; fseek(machoFile, archOffset, SEEK_SET); fread(&mh, sizeof(mh), 1, machoFile); - uint32_t maskedSubtype = OSSwapLittleToHostInt32(mh.cpusubtype) & ~0x80000000; + uint32_t maskedSubtype = OSSwapLittleToHostInt32(mh.cpusubtype); if (maskedSubtype == subtypeToSearch) { outArchOffset = archOffset; *stop = YES; @@ -82,11 +82,13 @@ int64_t machoFindArch(FILE *machoFile, uint32_t subtypeToSearch) int64_t machoFindBestArch(FILE *machoFile) { #if __arm64e__ - int64_t archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64E); + int64_t archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64E|0x80000000); if (archOffsetCandidate < 0) { - archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64_ALL); + archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64E); + if (archOffsetCandidate < 0) { + archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64_ALL); + } } - return archOffsetCandidate; #else int64_t archOffsetCandidate = machoFindArch(machoFile, CPU_SUBTYPE_ARM64_ALL); return archOffsetCandidate; diff --git a/BaseBin/systemhook/src/common.c b/BaseBin/systemhook/src/common.c index a1eee25c4..f63f0e5a8 100644 --- a/BaseBin/systemhook/src/common.c +++ b/BaseBin/systemhook/src/common.c @@ -253,8 +253,13 @@ int resolvePath(const char *file, const char *searchPath, int (^attemptHandler)( struct stat sb; char path_buf[PATH_MAX]; - if ((env_path = getenv("PATH")) == NULL) - env_path = _PATH_DEFPATH; + env_path = searchPath; + if (!env_path) { + env_path = getenv("PATH"); + if (!env_path) { + env_path = _PATH_DEFPATH; + } + } /* If it's an absolute or relative path name, it's easy. */ if (index(file, '/')) { diff --git a/BaseBin/systemhook/src/main.c b/BaseBin/systemhook/src/main.c index e4fbce64f..1671aad40 100644 --- a/BaseBin/systemhook/src/main.c +++ b/BaseBin/systemhook/src/main.c @@ -134,16 +134,17 @@ int execle_hook(const char *path, const char *arg0, ... /*, (char *)0, char *con // Get argument count va_list args_copy; va_copy(args_copy, args); - int arg_count = 0; + int arg_count = 1; for (char *arg = va_arg(args_copy, char *); arg != NULL; arg = va_arg(args_copy, char *)) { arg_count++; } va_end(args_copy); char *argv[arg_count+1]; + argv[0] = (char*)arg0; for (int i = 0; i < arg_count-1; i++) { char *arg = va_arg(args, char*); - argv[i] = arg; + argv[i+1] = arg; } argv[arg_count] = NULL; @@ -161,21 +162,22 @@ int execlp_hook(const char *file, const char *arg0, ... /*, (char *)0 */) // Get argument count va_list args_copy; va_copy(args_copy, args); - int arg_count = 0; + int arg_count = 1; for (char *arg = va_arg(args_copy, char*); arg != NULL; arg = va_arg(args_copy, char*)) { arg_count++; } va_end(args_copy); char **argv = malloc((arg_count+1) * sizeof(char *)); + argv[0] = (char*)arg0; for (int i = 0; i < arg_count-1; i++) { char *arg = va_arg(args, char*); - argv[i] = arg; + argv[i+1] = arg; } argv[arg_count] = NULL; int r = resolvePath(file, NULL, ^int(char *path) { - return execve_hook(path, argv, NULL); + return execve_hook(path, argv, environ); }); free(argv); @@ -191,38 +193,39 @@ int execl_hook(const char *path, const char *arg0, ... /*, (char *)0 */) // Get argument count va_list args_copy; va_copy(args_copy, args); - int arg_count = 0; + int arg_count = 1; for (char *arg = va_arg(args_copy, char*); arg != NULL; arg = va_arg(args_copy, char*)) { arg_count++; } va_end(args_copy); char *argv[arg_count+1]; + argv[0] = (char*)arg0; for (int i = 0; i < arg_count-1; i++) { char *arg = va_arg(args, char*); - argv[i] = arg; + argv[i+1] = arg; } argv[arg_count] = NULL; - return execve_hook(path, argv, NULL); + return execve_hook(path, argv, environ); } int execv_hook(const char *path, char *const argv[]) { - return execve_hook(path, argv, NULL); + return execve_hook(path, argv, environ); } int execvp_hook(const char *file, char *const argv[]) { return resolvePath(file, NULL, ^int(char *path) { - return execve_hook(path, argv, NULL); + return execve_hook(path, argv, environ); }); } int execvP_hook(const char *file, const char *search_path, char *const argv[]) { return resolvePath(file, search_path, ^int(char *path) { - return execve_hook(path, argv, NULL); + return execve_hook(path, argv, environ); }); } @@ -440,6 +443,7 @@ DYLD_INTERPOSE(execve_hook, execve) DYLD_INTERPOSE(execle_hook, execle) DYLD_INTERPOSE(execlp_hook, execlp) DYLD_INTERPOSE(execv_hook, execv) +DYLD_INTERPOSE(execl_hook, execl) DYLD_INTERPOSE(execvp_hook, execvp) DYLD_INTERPOSE(execvP_hook, execvP) DYLD_INTERPOSE(dlopen_hook, dlopen) @@ -451,4 +455,4 @@ DYLD_INTERPOSE(sandbox_init_with_parameters_hook, sandbox_init_with_parameters) DYLD_INTERPOSE(sandbox_init_with_extensions_hook, sandbox_init_with_extensions) DYLD_INTERPOSE(ptrace_hook, ptrace) DYLD_INTERPOSE(fork_hook, fork) -DYLD_INTERPOSE(vfork_hook, vfork) \ No newline at end of file +DYLD_INTERPOSE(vfork_hook, vfork)