diff --git a/BaseBin/systemhook/src/main.c b/BaseBin/systemhook/src/main.c index 00ca4a1bd..56944a279 100644 --- a/BaseBin/systemhook/src/main.c +++ b/BaseBin/systemhook/src/main.c @@ -73,13 +73,19 @@ int dyld_hook_routine(void **dyld, int idx, void *hook, void **orig, uint16_t pa return -1; } +// All dlopen/dlsym calls use __builtin_return_address(0) to determine what library called it +// Since we hook them, if we just call the original function on our own, the return address will always point to systemhook +// Therefore we must ensure the call to the original function is a tail call, +// which ensures that the stack and lr are restored and the compiler turns the call into a direct branch +// This is done via __attribute__((musttail)), this way __builtin_return_address(0) will point to the original calling library instead of systemhook + void* (*dyld_dlopen_orig)(void *dyld, const char* path, int mode); void* dyld_dlopen_hook(void *dyld, const char* path, int mode) { if (path && !(mode & RTLD_NOLOAD)) { jbclient_trust_library(path, __builtin_return_address(0)); } - return dyld_dlopen_orig(dyld, path, mode); + __attribute__((musttail)) return dyld_dlopen_orig(dyld, path, mode); } void* (*dyld_dlopen_from_orig)(void *dyld, const char* path, int mode, void* addressInCaller); @@ -88,7 +94,7 @@ void* dyld_dlopen_from_hook(void *dyld, const char* path, int mode, void* addres if (path && !(mode & RTLD_NOLOAD)) { jbclient_trust_library(path, addressInCaller); } - return dyld_dlopen_from_orig(dyld, path, mode, addressInCaller); + __attribute__((musttail)) return dyld_dlopen_from_orig(dyld, path, mode, addressInCaller); } void* (*dyld_dlopen_audited_orig)(void *dyld, const char* path, int mode); @@ -97,7 +103,7 @@ void* dyld_dlopen_audited_hook(void *dyld, const char* path, int mode) if (path && !(mode & RTLD_NOLOAD)) { jbclient_trust_library(path, __builtin_return_address(0)); } - return dyld_dlopen_audited_orig(dyld, path, mode); + __attribute__((musttail)) return dyld_dlopen_audited_orig(dyld, path, mode); } bool (*dyld_dlopen_preflight_orig)(void *dyld, const char *path); @@ -106,7 +112,7 @@ bool dyld_dlopen_preflight_hook(void *dyld, const char* path) if (path) { jbclient_trust_library(path, __builtin_return_address(0)); } - return dyld_dlopen_preflight_orig(dyld, path); + __attribute__((musttail)) return dyld_dlopen_preflight_orig(dyld, path); } void *(*dyld_dlsym_orig)(void *dyld, void *handle, const char *name); @@ -117,7 +123,7 @@ void *dyld_dlsym_hook(void *dyld, void *handle, const char *name) // Because we can just return a different pointer, we avoid doing instruction replacements return sandbox_apply_hook; } - return dyld_dlsym_orig(dyld, handle, name); + __attribute__((musttail)) return dyld_dlsym_orig(dyld, handle, name); } int ptrace_hook(int request, pid_t pid, caddr_t addr, int data)