aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-01-25 01:32:07 -0500
committercomex2015-01-25 01:32:07 -0500
commitf14efa13e2c78d7b7788f5b1125d1ba865cbe15e (patch)
tree3f12083af90729caabed99e5c32e20b11d1cd022
parentfixes (diff)
downloadsubstitute-f14efa13e2c78d7b7788f5b1125d1ba865cbe15e.tar.gz
fix substrate-compat; check in test
-rw-r--r--lib/darwin/substrate-compat.c11
-rw-r--r--test/test-hook-functions.c62
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
+}