diff options
Diffstat (limited to '')
-rw-r--r-- | lib/darwin/substrate-compat.c | 11 | ||||
-rw-r--r-- | test/test-hook-functions.c | 62 |
2 files changed, 70 insertions, 3 deletions
diff --git a/lib/darwin/substrate-compat.c b/lib/darwin/substrate-compat.c index 345d53f..54bdd2e 100644 --- a/lib/darwin/substrate-compat.c +++ b/lib/darwin/substrate-compat.c @@ -38,13 +38,18 @@ void *SubFindSymbol(void *image, const char *name) { return ptr; } -/* +#ifdef TARGET_DIS_SUPPORTED EXPORT void SubHookFunction(void *symbol, void *replace, void **result) __asm__("SubHookFunction"); void SubHookFunction(void *symbol, void *replace, void **result) { - // ... + struct substitute_function_hook hook = {symbol, replace, result}; + int ret = substitute_hook_functions(&hook, 1, 0); + if (ret) { + panic("SubHookFunction: substitute_hook_functions returned %s\n", + substitute_strerror(ret)); + } } -*/ +#endif EXPORT void SubHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result) diff --git a/test/test-hook-functions.c b/test/test-hook-functions.c new file mode 100644 index 0000000..2f23ae4 --- /dev/null +++ b/test/test-hook-functions.c @@ -0,0 +1,62 @@ +#include "substitute.h" +#include "substitute-internal.h" +#include <stdio.h> +#include <search.h> +#include <unistd.h> +#include <errno.h> +static pid_t (*old_getpid)(); +static pid_t hook_getpid() { + return old_getpid() * 2; +} + +static int hook_hcreate(size_t nel) { + return (int) nel; +} + +static size_t (*old_fwrite)(const void *restrict, size_t, size_t, FILE *restrict); +static size_t hook_fwrite(const void *restrict ptr, size_t size, size_t nitems, + FILE *restrict stream) { + size_t ret = old_fwrite(ptr, size, nitems, stream); + old_fwrite("*hic*\n", 1, 6, stream); + return ret; +} + +__attribute__((noinline)) +void break_before() { + __asm__ volatile(""); +} + +__attribute__((noinline)) +void break_after() { + __asm__ volatile(""); +} + +static const struct substitute_function_hook hooks[] = { + {getpid, hook_getpid, &old_getpid}, + {hcreate, hook_hcreate, NULL}, + {fwrite, hook_fwrite, &old_fwrite} +}; +int main() { +#ifdef TARGET_DIS_SUPPORTED + for (size_t i = 0; i < sizeof(hooks)/sizeof(*hooks); i++) { + uintptr_t p = (uintptr_t) hooks[i].function; + uint32_t *insns = (void *) (p & ~1); + printf("<%zd: ptr=%p insns=0x%08x, 0x%08x, 0x%08x\n", + i, hooks[i].function, + insns[0], insns[1], insns[2]); + + } + printf("getpid() => %d\n", getpid()); + break_before(); + int ret = substitute_hook_functions(hooks, sizeof(hooks)/sizeof(*hooks), 0); + break_after(); + int e = errno; + printf("ret = %d\n", ret); + printf("errno = %d\n", e); + printf("getpid() => %d\n", getpid()); + printf("hcreate() => %d\n", hcreate(42)); +#else + (void) hooks; + printf("can't test this here\n"); +#endif +} |