diff options
author | comex | 2015-02-18 02:22:36 -0500 |
---|---|---|
committer | comex | 2015-02-18 02:22:36 -0500 |
commit | 7c26a1964d2d2e54f87d9c42735f6c99b546abd4 (patch) | |
tree | f50838e492aa101a4d87e6ef01d1dc2611f32f97 /test/test-pc-patch.c | |
parent | more fixes (diff) | |
download | substitute-7c26a1964d2d2e54f87d9c42735f6c99b546abd4.tar.gz |
Fix hook-function:
- Thread stoppage is now complemented by sigaction to catch injected
threads (sigaction is not used exclusively because the rest of the
program could be trying to use sigaction itself in the meantime - this
is a real thing, ask Dolphin)
- mprotect is no longer used due to max_protection possibly getting in
the way; instead, a copy is created and mapped onto the original.
Diffstat (limited to 'test/test-pc-patch.c')
-rw-r--r-- | test/test-pc-patch.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/test/test-pc-patch.c b/test/test-pc-patch.c new file mode 100644 index 0000000..5ae3570 --- /dev/null +++ b/test/test-pc-patch.c @@ -0,0 +1,50 @@ +#include "substitute-internal.h" +#include "execmem.h" +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pthread.h> +#include <assert.h> +/* printf without taking any locks - because they might be taken at stop time */ +#define ulprintf(...) do { \ + char buf[256]; \ + int len = sprintf(buf, __VA_ARGS__); \ + write(1, buf, len); \ +} while(0) + +static void *some_thread(void *ip) { + long i = (long) ip; + while (1) { + ulprintf("Hello from %ld\n", i); + sleep(1); + } +} +static void replacement() { + ulprintf("Bye\n"); + pthread_exit(NULL); +} +static uintptr_t patch_callback(void *ctx, UNUSED uintptr_t pc) { + assert(!ctx); + return (uintptr_t) replacement; +} + +int main() { + pthread_t pts[10]; + for (long i = 0; i < 10; i++) + pthread_create(&pts[i], NULL, some_thread, (void *) i); + sleep(1); + char *foo = malloc(0x10000); + static char bar[16]; + struct execmem_foreign_write writes[] = { + {foo, bar, 5}, + {foo + 7, bar + 7, 3}, + }; + int ret = execmem_foreign_write_with_pc_patch(writes, + sizeof(writes)/sizeof(*writes), + patch_callback, + NULL); + ulprintf("==> %d\n", ret); + void *out; + for (long i = 0; i < 10; i++) + assert(!pthread_join(pts[i], &out)); +} |