Skip to content

Commit

Permalink
systemhook: Stop relying on implicit tail calls
Browse files Browse the repository at this point in the history
  • Loading branch information
opa334 committed Aug 18, 2024
1 parent 91bafa6 commit 5f9f061
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions BaseBin/systemhook/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand Down

0 comments on commit 5f9f061

Please sign in to comment.