diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/find-syms.c | 4 | ||||
-rw-r--r-- | lib/substitute-internal.h | 10 | ||||
-rw-r--r-- | lib/substitute.h | 11 | ||||
-rw-r--r-- | lib/substrate-compat.c | 55 |
4 files changed, 78 insertions, 2 deletions
diff --git a/lib/find-syms.c b/lib/find-syms.c index 5e58cb4..78421c5 100644 --- a/lib/find-syms.c +++ b/lib/find-syms.c @@ -115,6 +115,7 @@ static void inspect_dyld() { } /* 'dlopen_header' keeps the image alive */ +EXPORT struct substitute_image *substitute_open_image(const char *filename) { pthread_once(&dyld_inspect_once, inspect_dyld); @@ -134,17 +135,20 @@ struct substitute_image *substitute_open_image(const char *filename) { return im; } +EXPORT void substitute_close_image(struct substitute_image *im) { dlclose(im->dlhandle); /* ignore errors */ free(im); } +EXPORT int substitute_find_private_syms(struct substitute_image *im, const char **names, substitute_sym **syms, size_t count) { find_syms_raw(im->image_header, &im->slide, names, syms, count); return SUBSTITUTE_OK; } +EXPORT void *substitute_sym_to_ptr(struct substitute_image *handle, substitute_sym *sym) { return sym_to_ptr(sym, handle->slide); } diff --git a/lib/substitute-internal.h b/lib/substitute-internal.h new file mode 100644 index 0000000..cbb7462 --- /dev/null +++ b/lib/substitute-internal.h @@ -0,0 +1,10 @@ +#pragma once + +#include <stdio.h> +#define panic(...) do { \ + fprintf(stderr, __VA_ARGS__); \ + abort(); \ + __builtin_unreachable(); \ +} while(0) + +#define EXPORT __attribute__ ((visibility("default"))) diff --git a/lib/substitute.h b/lib/substitute.h index 20dc020..a7fdd31 100644 --- a/lib/substitute.h +++ b/lib/substitute.h @@ -8,7 +8,11 @@ #include <stdlib.h> #include <stdint.h> -// TODO add numbers +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO add numbers */ enum { SUBSTITUTE_OK = 0, }; @@ -42,7 +46,6 @@ struct substitute_image { * @filename the executable/library path (c.f. dyld(3) on Darwin) * @return a handle, or NULL if the image wasn't found */ - struct substitute_image *substitute_open_image(const char *filename); /* Release a handle opened with substitute_open_image. @@ -76,3 +79,7 @@ int substitute_find_private_syms(struct substitute_image *handle, void *substitute_sym_to_ptr(struct substitute_image *handle, substitute_sym *sym); #endif /* 1 */ + +#ifdef __cplusplus +} /* extern */ +#endif diff --git a/lib/substrate-compat.c b/lib/substrate-compat.c new file mode 100644 index 0000000..6bbe316 --- /dev/null +++ b/lib/substrate-compat.c @@ -0,0 +1,55 @@ +#include "substitute.h" +#include "substitute-internal.h" +#include <syslog.h> +#include <mach-o/dyld.h> + +EXPORT +void *SubGetImageByName(const char *filename) __asm__("SubGetImageByName"); +void *SubGetImageByName(const char *filename) { + return substitute_open_image(filename); +} + +EXPORT +void *SubFindSymbol(void *image, const char *name) __asm__("SubFindSymbol"); +void *SubFindSymbol(void *image, const char *name) { + if (!image) { + const char *s = "SubFindSymbol: 'any image' specified, which is incredibly slow - like, 2ms. I'm going to do it since it seems to be somewhat common, but you should be ashamed of yourself."; + syslog(LOG_WARNING, "%s", s); + fprintf(stderr, "%s\n", s); + /* and it isn't thread safe, but neither is MS */ + for(uint32_t i = 0; i < _dyld_image_count(); i++) { + const char *im_name = _dyld_get_image_name(i); + struct substitute_image *im = substitute_open_image(im_name); + if (!im) { + fprintf(stderr, "(btw, couldn't open %s?)\n", im_name); + continue; + } + void *r = SubFindSymbol(im, name); + substitute_close_image(im); + if (r) + return r; + } + return NULL; + } + + substitute_sym *sym; + if (substitute_find_private_syms(image, &name, &sym, 1) || !sym) + return NULL; + return substitute_sym_to_ptr(image, sym); +} + +/* +EXPORT +void SubHookFunction(void *symbol, void *replace, void **result) __asm__("SubHookFunction"); +void SubHookFunction(void *symbol, void *replace, void **result) { + // ... +} +*/ + +#ifdef __APPLE__ +/*void SubHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result) __asm__("SubHookMessageEx"); +void SubHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result) { + +}*/ + +#endif |