From 7c26a1964d2d2e54f87d9c42735f6c99b546abd4 Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 18 Feb 2015 02:22:36 -0500 Subject: 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. --- test/test-execmem.c | 11 ++++++++--- test/test-pc-patch.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ test/test-stop-threads.c | 46 -------------------------------------------- 3 files changed, 58 insertions(+), 49 deletions(-) create mode 100644 test/test-pc-patch.c delete mode 100644 test/test-stop-threads.c (limited to 'test') diff --git a/test/test-execmem.c b/test/test-execmem.c index 5ec64e9..9125d68 100644 --- a/test/test-execmem.c +++ b/test/test-execmem.c @@ -25,13 +25,18 @@ int test(size_t a) { return 1000; } +static int ewrite(void *dst, const void *src, size_t len) { + struct execmem_foreign_write w = {dst, src, len}; + return execmem_foreign_write_with_pc_patch(&w, 1, NULL, NULL); +} + int main() { printf("this should be 5: %d\n", test(0)); - printf("=> %d\n", execmem_write(test, other, OTHER_SIZE)); + printf("=> %d\n", ewrite(test, other, OTHER_SIZE)); printf(" %s\n", strerror(errno)); printf("this should be 6: %d\n", test(0)); - printf("=> %d\n", execmem_write(hcreate, other, OTHER_SIZE)); + printf("=> %d\n", ewrite(hcreate, other, OTHER_SIZE)); printf(" %s\n", strerror(errno)); - printf("modified shared cache func: %d\n", hcreate(0)); + printf("modified shared cache func should be 6: %d\n", hcreate(0)); } 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 +#include +#include +#include +#include +/* 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)); +} diff --git a/test/test-stop-threads.c b/test/test-stop-threads.c deleted file mode 100644 index d53d8cd..0000000 --- a/test/test-stop-threads.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "substitute-internal.h" -#include "stop-other-threads.h" -#include -#include -#include -#include -/* 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); - void *stop_token; - ulprintf("stopping\n"); - assert(!stop_other_threads(&stop_token)); - ulprintf("stopped\n"); - assert(!apply_pc_patch_callback(stop_token, patch_callback, NULL)); - ulprintf("resuming\n"); - assert(!resume_other_threads(stop_token)); - ulprintf("resumed\n"); - void *out; - for (long i = 0; i < 10; i++) - assert(!pthread_join(pts[i], &out)); -} -- cgit v1.2.3