aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/find-syms.c172
-rw-r--r--lib/interpose.c64
-rw-r--r--lib/substitute-internal.h6
3 files changed, 121 insertions, 121 deletions
diff --git a/lib/find-syms.c b/lib/find-syms.c
index 84df9b4..44adf78 100644
--- a/lib/find-syms.c
+++ b/lib/find-syms.c
@@ -15,65 +15,65 @@ static uintptr_t (*ImageLoaderMachO_getSlide)(void *);
static const struct mach_header *(*ImageLoaderMachO_machHeader)(void *);
static void *sym_to_ptr(substitute_sym *sym, intptr_t slide) {
- uintptr_t addr = sym->n_value;
- addr += slide;
- if (sym->n_desc & N_ARM_THUMB_DEF)
- addr |= 1;
- return (void *) addr;
+ uintptr_t addr = sym->n_value;
+ addr += slide;
+ if (sym->n_desc & N_ARM_THUMB_DEF)
+ addr |= 1;
+ return (void *) addr;
}
static void find_syms_raw(const void *hdr, intptr_t *slide, const char **names, substitute_sym **syms, size_t count) {
- memset(syms, 0, sizeof(*syms) * count);
-
- /* note: no verification at all */
- const mach_header_x *mh = hdr;
- uint32_t ncmds = mh->ncmds;
- struct load_command *lc = (void *) (mh + 1);
- struct symtab_command syc;
- for (uint32_t i = 0; i < ncmds; i++) {
- if (lc->cmd == LC_SYMTAB) {
- syc = *(struct symtab_command *) lc;
- goto ok;
- }
- lc = (void *) lc + lc->cmdsize;
- }
- return; /* no symtab, no symbols */
+ memset(syms, 0, sizeof(*syms) * count);
+
+ /* note: no verification at all */
+ const mach_header_x *mh = hdr;
+ uint32_t ncmds = mh->ncmds;
+ struct load_command *lc = (void *) (mh + 1);
+ struct symtab_command syc;
+ for (uint32_t i = 0; i < ncmds; i++) {
+ if (lc->cmd == LC_SYMTAB) {
+ syc = *(struct symtab_command *) lc;
+ goto ok;
+ }
+ lc = (void *) lc + lc->cmdsize;
+ }
+ return; /* no symtab, no symbols */
ok: ;
- substitute_sym *symtab = NULL;
- const char *strtab = NULL;
- lc = (void *) (mh + 1);
- for (uint32_t i = 0; i < ncmds; i++) {
- if (lc->cmd == LC_SEGMENT_X) {
- segment_command_x *sc = (void *) lc;
- if (syc.symoff - sc->fileoff < sc->filesize)
- symtab = (void *) sc->vmaddr + syc.symoff - sc->fileoff;
- if (syc.stroff - sc->fileoff < sc->filesize)
- strtab = (void *) sc->vmaddr + syc.stroff - sc->fileoff;
- if (*slide == -1 && sc->fileoff == 0) {
- // used only for dyld
- *slide = (uintptr_t) hdr - sc->vmaddr;
- }
- if (symtab && strtab)
- goto ok2;
- }
- lc = (void *) lc + lc->cmdsize;
- }
- return; /* uh... weird */
+ substitute_sym *symtab = NULL;
+ const char *strtab = NULL;
+ lc = (void *) (mh + 1);
+ for (uint32_t i = 0; i < ncmds; i++) {
+ if (lc->cmd == LC_SEGMENT_X) {
+ segment_command_x *sc = (void *) lc;
+ if (syc.symoff - sc->fileoff < sc->filesize)
+ symtab = (void *) sc->vmaddr + syc.symoff - sc->fileoff;
+ if (syc.stroff - sc->fileoff < sc->filesize)
+ strtab = (void *) sc->vmaddr + syc.stroff - sc->fileoff;
+ if (*slide == -1 && sc->fileoff == 0) {
+ // used only for dyld
+ *slide = (uintptr_t) hdr - sc->vmaddr;
+ }
+ if (symtab && strtab)
+ goto ok2;
+ }
+ lc = (void *) lc + lc->cmdsize;
+ }
+ return; /* uh... weird */
ok2: ;
- symtab = (void *) symtab + *slide;
- strtab = (void *) strtab + *slide;
- /* This could be optimized for efficiency with a large number of names... */
- for (uint32_t i = 0; i < syc.nsyms; i++) {
- substitute_sym *sym = &symtab[i];
- uint32_t strx = sym->n_un.n_strx;
- const char *name = strx == 0 ? "" : strtab + strx;
- for (size_t j = 0; j < count; j++) {
- if (!strcmp(name, names[j])) {
- syms[j] = sym;
- break;
- }
- }
- }
+ symtab = (void *) symtab + *slide;
+ strtab = (void *) strtab + *slide;
+ /* This could be optimized for efficiency with a large number of names... */
+ for (uint32_t i = 0; i < syc.nsyms; i++) {
+ substitute_sym *sym = &symtab[i];
+ uint32_t strx = sym->n_un.n_strx;
+ const char *name = strx == 0 ? "" : strtab + strx;
+ for (size_t j = 0; j < count; j++) {
+ if (!strcmp(name, names[j])) {
+ syms[j] = sym;
+ break;
+ }
+ }
+ }
}
/* This is a mess because the usual _dyld_image_count loop is not thread safe.
@@ -87,56 +87,56 @@ ok2: ;
*/
static void inspect_dyld() {
- const struct dyld_all_image_infos *aii = _dyld_get_all_image_infos();
- const void *dyld_hdr = aii->dyldImageLoadAddress;
-
- const char *names[2] = { "__ZNK16ImageLoaderMachO8getSlideEv", "__ZNK16ImageLoaderMachO10machHeaderEv" };
- substitute_sym *syms[2];
- intptr_t dyld_slide = -1;
- find_syms_raw(dyld_hdr, &dyld_slide, names, syms, 2);
- if (!syms[0] || !syms[1])
- substitute_panic("couldn't find ImageLoader methods\n");
- ImageLoaderMachO_getSlide = sym_to_ptr(syms[0], dyld_slide);
- ImageLoaderMachO_machHeader = sym_to_ptr(syms[1], dyld_slide);
+ const struct dyld_all_image_infos *aii = _dyld_get_all_image_infos();
+ const void *dyld_hdr = aii->dyldImageLoadAddress;
+
+ const char *names[2] = { "__ZNK16ImageLoaderMachO8getSlideEv", "__ZNK16ImageLoaderMachO10machHeaderEv" };
+ substitute_sym *syms[2];
+ intptr_t dyld_slide = -1;
+ find_syms_raw(dyld_hdr, &dyld_slide, names, syms, 2);
+ if (!syms[0] || !syms[1])
+ substitute_panic("couldn't find ImageLoader methods\n");
+ ImageLoaderMachO_getSlide = sym_to_ptr(syms[0], dyld_slide);
+ ImageLoaderMachO_machHeader = sym_to_ptr(syms[1], dyld_slide);
}
/* 'dlopen_header' keeps the image alive */
EXPORT
struct substitute_image *substitute_open_image(const char *filename) {
- pthread_once(&dyld_inspect_once, inspect_dyld);
-
- void *dlhandle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
- if (!dlhandle)
- return NULL;
-
- const void *image_header = ImageLoaderMachO_machHeader(dlhandle);
- intptr_t slide = ImageLoaderMachO_getSlide(dlhandle);
-
- struct substitute_image *im = malloc(sizeof(*im));
- if (!im)
- return NULL;
- im->slide = slide;
- im->dlhandle = dlhandle;
- im->image_header = image_header;
- return im;
+ pthread_once(&dyld_inspect_once, inspect_dyld);
+
+ void *dlhandle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
+ if (!dlhandle)
+ return NULL;
+
+ const void *image_header = ImageLoaderMachO_machHeader(dlhandle);
+ intptr_t slide = ImageLoaderMachO_getSlide(dlhandle);
+
+ struct substitute_image *im = malloc(sizeof(*im));
+ if (!im)
+ return NULL;
+ im->slide = slide;
+ im->dlhandle = dlhandle;
+ im->image_header = image_header;
+ return im;
}
EXPORT
void substitute_close_image(struct substitute_image *im) {
- dlclose(im->dlhandle); /* ignore errors */
- free(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 nsyms) {
- find_syms_raw(im->image_header, &im->slide, names, syms, nsyms);
- return SUBSTITUTE_OK;
+ find_syms_raw(im->image_header, &im->slide, names, syms, nsyms);
+ return SUBSTITUTE_OK;
}
EXPORT
void *substitute_sym_to_ptr(struct substitute_image *handle, substitute_sym *sym) {
- return sym_to_ptr(sym, handle->slide);
+ return sym_to_ptr(sym, handle->slide);
}
#endif /* __APPLE__ */
diff --git a/lib/interpose.c b/lib/interpose.c
index cb2b870..9718813 100644
--- a/lib/interpose.c
+++ b/lib/interpose.c
@@ -17,8 +17,8 @@ struct interpose_state {
int nsegments;
segment_command_x *segments[MAX_SEGMENTS];
uintptr_t slide;
- const struct substitute_import_hook *hooks;
- size_t nhooks;
+ const struct substitute_import_hook *hooks;
+ size_t nhooks;
};
static uintptr_t read_leb128(void **ptr, void *end, bool is_signed) {
@@ -108,30 +108,30 @@ static int try_bind_section(void *bind, size_t size, const struct interpose_stat
goto bind;
bind:
if (segment && sym) {
- const struct substitute_import_hook *h;
- size_t i;
- for (i = 0; i < st->nhooks; i++) {
- h = &st->hooks[i];
- // TODO abs/pcrel32? used on arm?
- if (!strcmp(sym, h->name)) {
- if (type != BIND_TYPE_POINTER)
- return SUBSTITUTE_ERR_UNKNOWN_RELOCATION_TYPE;
- break;
- }
- }
- if (i != st->nhooks) {
- while (count--) {
- uintptr_t new = (uintptr_t) h->replacement + addend;
- uintptr_t *p = (void *) (segment + offset);
- uintptr_t old = __atomic_exchange_n(p, new, __ATOMIC_RELAXED);
- if (h->old_ptr)
- *(void **) h->old_ptr = (void *) (old - addend);
- offset += stride;
- }
- break;
- }
- }
- offset += count * stride;
+ const struct substitute_import_hook *h;
+ size_t i;
+ for (i = 0; i < st->nhooks; i++) {
+ h = &st->hooks[i];
+ // TODO abs/pcrel32? used on arm?
+ if (!strcmp(sym, h->name)) {
+ if (type != BIND_TYPE_POINTER)
+ return SUBSTITUTE_ERR_UNKNOWN_RELOCATION_TYPE;
+ break;
+ }
+ }
+ if (i != st->nhooks) {
+ while (count--) {
+ uintptr_t new = (uintptr_t) h->replacement + addend;
+ uintptr_t *p = (void *) (segment + offset);
+ uintptr_t old = __atomic_exchange_n(p, new, __ATOMIC_RELAXED);
+ if (h->old_ptr)
+ *(void **) h->old_ptr = (void *) (old - addend);
+ offset += stride;
+ }
+ break;
+ }
+ }
+ offset += count * stride;
break;
}
}
@@ -154,10 +154,10 @@ int substitute_interpose_imports(const struct substitute_image *image,
struct interpose_state st;
st.slide = image->slide;
st.nsegments = 0;
- st.hooks = hooks;
- st.nhooks = nhooks;
+ st.hooks = hooks;
+ st.nhooks = nhooks;
- const mach_header_x *mh = image->image_header;
+ const mach_header_x *mh = image->image_header;
const struct load_command *lc = (void *) (mh + 1);
for (uint32_t i = 0; i < mh->ncmds; i++) {
if (lc->cmd == LC_SEGMENT_X) {
@@ -172,17 +172,17 @@ int substitute_interpose_imports(const struct substitute_image *image,
for (uint32_t i = 0; i < mh->ncmds; i++) {
if (lc->cmd == LC_DYLD_INFO || lc->cmd == LC_DYLD_INFO_ONLY) {
struct dyld_info_command *dc = (void *) lc;
- int ret;
+ int ret;
if ((ret = try_bind_section(off_to_addr(&st, dc->bind_off), dc->bind_size, &st, false)) ||
(ret = try_bind_section(off_to_addr(&st, dc->weak_bind_off), dc->weak_bind_size, &st, false)) ||
(ret = try_bind_section(off_to_addr(&st, dc->lazy_bind_off), dc->lazy_bind_size, &st, true)))
- return ret;
+ return ret;
break;
}
lc = (void *) lc + lc->cmdsize;
}
- return SUBSTITUTE_OK;
+ return SUBSTITUTE_OK;
}
#endif /* __APPLE__ */
diff --git a/lib/substitute-internal.h b/lib/substitute-internal.h
index fb64714..2550d2a 100644
--- a/lib/substitute-internal.h
+++ b/lib/substitute-internal.h
@@ -2,9 +2,9 @@
#include <stdio.h>
#define substitute_panic(...) do { \
- fprintf(stderr, __VA_ARGS__); \
- abort(); \
- __builtin_unreachable(); \
+ fprintf(stderr, __VA_ARGS__); \
+ abort(); \
+ __builtin_unreachable(); \
} while(0)
#define EXPORT __attribute__ ((visibility("default")))