From da200d3ac0204abadd5992820486321970d689b8 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 19 Feb 2018 15:51:56 +0200 Subject: refactoring, fixing and implementing messy commits yay --- src/wrapper/wrapper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/wrapper/wrapper.c (limited to 'src/wrapper/wrapper.c') diff --git a/src/wrapper/wrapper.c b/src/wrapper/wrapper.c new file mode 100644 index 0000000..5ed0943 --- /dev/null +++ b/src/wrapper/wrapper.c @@ -0,0 +1,70 @@ +#include "wrapper.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID_X86_LINKER +__asm__( + "wrapper_start: nop\n" + "wrapper_symbol: pushl $0xFAFBFCFD\n" + "wrapper_trace: movl $0xFAFBFCFD, %eax\ncall *%eax\npop %eax\n" + "wrapper_call: movl $0xFAFBFCFD, %eax\njmp *%eax\n" + "wrapper_end: nop\n" +); +# define WRAPPER_TRACE +#else +# warning "no wrapper asm for this platform, function tracing is not available" +#endif + +#ifdef WRAPPER_TRACE +extern char wrapper_start, wrapper_symbol, wrapper_trace, wrapper_call, wrapper_end; +static char* (*__cxa_demangle)(const char *mangled_name, char *output_buffer, size_t *length, int *status); + +static void +trace(const char *const symbol) +{ + if (__cxa_demangle) { + // >If output_buffer is not long enough, it is expanded using realloc + // Holy fuck gcc what the fuck? Guess we don't use stack then, thanks + int status; + char *demangled; + if ((demangled = __cxa_demangle(symbol, NULL, NULL, &status))) { + printf("trace: %s\n", demangled); + free(demangled); // so pointless... + return; + } + } + + printf("trace: %s\n", symbol); +} +#endif + +void* +wrapper_create(const char *const symbol, void *function) +{ +#ifdef WRAPPER_TRACE + if (!__cxa_demangle) + __cxa_demangle = dlsym(RTLD_DEFAULT, "__cxa_demangle"); + + const size_t sz = &wrapper_end - &wrapper_start; + unsigned char *fun = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + assert(fun != MAP_FAILED); + memcpy(fun, &wrapper_start, sz); +#ifdef ANDROID_X86_LINKER + memcpy(fun + (&wrapper_symbol - &wrapper_start) + 1, &symbol, sizeof(symbol)); + memcpy(fun + (&wrapper_trace - &wrapper_start) + 1, (uintptr_t[]){ (uintptr_t)trace }, sizeof(uintptr_t)); + memcpy(fun + (&wrapper_call - &wrapper_start) + 1, &function, sizeof(function)); +#else +# error "should not happen" +#endif + mprotect(fun, sz, PROT_READ | PROT_EXEC); + return fun; +#else + return function; +#endif +} -- cgit v1.2.3