diff options
author | comex | 2015-01-20 19:57:26 -0500 |
---|---|---|
committer | comex | 2015-01-20 19:57:26 -0500 |
commit | 018c956986f0a773c0af1da6c86fdb94737e9d5b (patch) | |
tree | ecc870cbc8832ce4359d07cf5a8a02e8e7423528 /lib/darwin/find-syms.c | |
parent | progress on injection (diff) | |
download | substitute-018c956986f0a773c0af1da6c86fdb94737e9d5b.tar.gz |
revert THAT WHOLE THING because we can't actually use it for inject
Diffstat (limited to 'lib/darwin/find-syms.c')
-rw-r--r-- | lib/darwin/find-syms.c | 108 |
1 files changed, 37 insertions, 71 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__ */ |