aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-01-20 19:57:26 -0500
committercomex2015-01-20 19:57:26 -0500
commit018c956986f0a773c0af1da6c86fdb94737e9d5b (patch)
treeecc870cbc8832ce4359d07cf5a8a02e8e7423528
parentprogress on injection (diff)
downloadsubstitute-018c956986f0a773c0af1da6c86fdb94737e9d5b.tar.gz
revert THAT WHOLE THING because we can't actually use it for inject
-rw-r--r--lib/darwin/find-syms.c108
-rw-r--r--lib/darwin/find-syms.h14
2 files changed, 37 insertions, 85 deletions
diff --git a/lib/darwin/find-syms.c b/lib/darwin/find-syms.c
index f2261f0..6b07591 100644
--- a/lib/darwin/find-syms.c
+++ b/lib/darwin/find-syms.c
@@ -6,7 +6,6 @@
#include "substitute.h"
#include "substitute-internal.h"
-#include "find-syms.h"
extern const struct dyld_all_image_infos *_dyld_get_all_image_infos();
@@ -23,23 +22,13 @@ static void *sym_to_ptr(substitute_sym *sym, intptr_t slide) {
return (void *) addr;
}
-static bool find_slide(const mach_header_x *mh, intptr_t *slidep) {
- uint32_t ncmds = mh->ncmds;
- struct load_command *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 (sc->fileoff == 0) {
- *slidep = (uintptr_t) mh - sc->vmaddr;
- return true;
- }
- }
- lc = (void *) lc + lc->cmdsize;
- }
- return false;
-}
+static void find_syms_raw(const void *hdr, intptr_t *restrict slide,
+ const char **restrict names, void **restrict syms,
+ size_t nsyms) {
+ memset(syms, 0, sizeof(*syms) * nsyms);
-bool find_symtab_data(const mach_header_x *mh, struct symtab_data *data) {
+ /* 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;
@@ -50,46 +39,39 @@ bool find_symtab_data(const mach_header_x *mh, struct symtab_data *data) {
}
lc = (void *) lc + lc->cmdsize;
}
- return false; /* no symtab, no symbols */
+ 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;
- uint32_t seg_symoff = syc.symoff - sc->fileoff;
- uint32_t seg_stroff = syc.stroff - sc->fileoff;
- if (seg_symoff < sc->filesize &&
- syc.nsyms <= (sc->filesize - seg_symoff) / sizeof(substitute_sym) &&
- seg_stroff < sc->filesize &&
- syc.strsize <= sc->filesize - seg_stroff) {
- data->linkedit_vmaddr = sc->vmaddr;
- data->linkedit_symoff = seg_symoff;
- data->nsyms = syc.nsyms;
- data->linkedit_stroff = seg_stroff;
- data->strsize = syc.strsize;
- return true;
+ 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 false; /* not in any segment? */
-}
-
-void find_syms_raw(const struct symtab_data *restrict data, void *linkedit,
- const char **restrict names, substitute_sym **restrict syms,
- size_t count) {
- memset(syms, 0, count * sizeof(*syms));
- substitute_sym *symtab = linkedit + data->linkedit_symoff;
- const char *strtab = linkedit + data->linkedit_stroff;
+ 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 < data->nsyms; i++) {
+ 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 || strx >= data->strsize) ? "" : strtab + strx;
- size_t maxlen = data->strsize - strx;
- for (size_t j = 0; j < count; j++) {
- if (!strncmp(name, names[j], maxlen)) {
- syms[j] = sym;
+ const char *name = strx == 0 ? "" : strtab + strx;
+ for (size_t j = 0; j < nsyms; j++) {
+ if (!strcmp(name, names[j])) {
+ syms[j] = sym_to_ptr(sym, *slide);
break;
}
}
@@ -111,20 +93,16 @@ static void inspect_dyld() {
const void *dyld_hdr = aii->dyldImageLoadAddress;
const char *names[2] = { "__ZNK16ImageLoaderMachO8getSlideEv", "__ZNK16ImageLoaderMachO10machHeaderEv" };
- substitute_sym *syms[2];
+ void *syms[2];
intptr_t dyld_slide = -1;
- struct symtab_data symtab_data;
- if (!find_slide(dyld_hdr, &dyld_slide) ||
- !find_symtab_data(dyld_hdr, &symtab_data))
- substitute_panic("couldn't find ImageLoader methods\n");
- void *linkedit = (void *) (symtab_data.linkedit_vmaddr + dyld_slide);
- find_syms_raw(&symtab_data, linkedit, names, syms, 2);
+ 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);
+ ImageLoaderMachO_getSlide = syms[0];
+ ImageLoaderMachO_machHeader = syms[1];
}
+/* 'dlopen_header' keeps the image alive */
EXPORT
struct substitute_image *substitute_open_image(const char *filename) {
pthread_once(&dyld_inspect_once, inspect_dyld);
@@ -152,24 +130,12 @@ void substitute_close_image(struct substitute_image *im) {
}
EXPORT
-int substitute_find_private_syms(struct substitute_image *im, const char **names,
- void **syms, size_t nsyms) {
- struct symtab_data symtab_data;
- if (!find_symtab_data(im->image_header, &symtab_data))
- return SUBSTITUTE_OK;
- void *linkedit = (void *) (symtab_data.linkedit_vmaddr + im->slide);
- substitute_sym **ssyms = (void *) syms;
- find_syms_raw(&symtab_data, linkedit, names, ssyms, nsyms);
- for (size_t i = 0; i < nsyms; i++) {
- if (ssyms[i])
- syms[i] = sym_to_ptr(ssyms[i], im->slide);
- }
+int substitute_find_private_syms(struct substitute_image *im,
+ const char **restrict names,
+ void **restrict syms,
+ size_t nsyms) {
+ 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);
-}
-
#endif /* __APPLE__ */
diff --git a/lib/darwin/find-syms.h b/lib/darwin/find-syms.h
deleted file mode 100644
index c017d2a..0000000
--- a/lib/darwin/find-syms.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-#include "substitute.h"
-#include "substitute-internal.h"
-
-struct symtab_data {
- uint64_t linkedit_vmaddr;
- uint32_t linkedit_symoff, nsyms;
- uint32_t linkedit_stroff, strsize;
-};
-
-bool find_symtab_data(const mach_header_x *mh, struct symtab_data *data);
-void find_syms_raw(const struct symtab_data *restrict data, void *linkedit,
- const char **restrict names, substitute_sym **restrict syms,
- size_t count);