Permalink
Browse files

findanywhere

  • Loading branch information...
1 parent 121f784 commit 9731118cb835d82107cd2150baa1252dd9705a7d @comex committed Jul 15, 2011
Showing with 64 additions and 26 deletions.
  1. +15 −11 find.c
  2. +5 −1 find.h
  3. +7 −3 mach-o/binary.c
  4. +1 −0 mach-o/binary.h
  5. +29 −10 mach-o/link.c
  6. +7 −1 mach-o/link.h
View
26 find.c
@@ -284,19 +284,23 @@ addr_t find_bl(range_t *range) {
return baseaddr + diff;
}
-addr_t b_find_anywhere(const struct binary *binary, const char *to_find, int align, int options) {
- for(uint32_t i = 0; i < binary->nsegments; i++) {
- range_t range = binary->segments[i].vm_range;
- addr_t result = find_data(range, to_find, align, options & ~MUST_FIND);
- if(result) return result;
- }
- if(options & MUST_FIND) {
- die("didn't find [%s] anywhere", to_find);
- } else {
- return 0;
- }
+#define unparen(args...) args
+#define find_anywhere_func(name, args1, args2) \
+addr_t b_find_##name##_anywhere(const struct binary *binary, unparen args1, int options) { \
+ uint32_t end = binary->nsegments - 1; \
+ for(uint32_t i = 0; i <= end; i++) { \
+ range_t range = binary->segments[i].vm_range; \
+ addr_t result = find_##name(range, unparen args2, i == end ? options : options & ~MUST_FIND); \
+ if(result) return result; \
+ } \
+ return 0; /* won't reach */ \
}
+find_anywhere_func(data, (const char *to_find, int align), (to_find, align))
+find_anywhere_func(string, (const char *string, int align), (string, align))
+find_anywhere_func(bytes, (const char *bytes, size_t len, int align), (bytes, len, align))
+find_anywhere_func(int32, (uint32_t number), (number))
+
struct pattern {
int16_t buf[128];
ssize_t pattern_size, offset;
View
6 find.h
@@ -18,7 +18,11 @@ uint32_t resolve_ldr(const struct binary *binary, addr_t addr);
addr_t find_bl(range_t *range);
-addr_t b_find_anywhere(const struct binary *binary, const char *to_find, int align, int options);
+#define b_find_anywhere b_find_data_anywhere
+addr_t b_find_data_anywhere(const struct binary *binary, const char *to_find, int align, int options);
+addr_t b_find_string_anywhere(const struct binary *binary, const char *string, int align, int options);
+addr_t b_find_bytes_anywhere(const struct binary *binary, const char *bytes, size_t len, int align, int options);
+addr_t b_find_int32_anywhere(const struct binary *binary, uint32_t number, int options);
struct findmany *findmany_init(range_t range);
void findmany_add(addr_t *result, struct findmany *fm, const char *to_find);
View
@@ -110,11 +110,16 @@ static void do_symbols(struct binary *binary) {
}
void b_prange_load_macho(struct binary *binary, prange_t pr, size_t offset, const char *name) {
+ b_prange_load_macho_nosyms(binary, pr, offset, name);
+ do_symbols(binary);
+ binary->_sym = sym;
+ binary->_copy_syms = copy_syms;
+}
+
+void b_prange_load_macho_nosyms(struct binary *binary, prange_t pr, size_t offset, const char *name) {
#define _arg name
binary->valid = true;
binary->mach = calloc(sizeof(*binary->mach), 1);
- binary->_sym = sym;
- binary->_copy_syms = copy_syms;
binary->valid_range = pr;
binary->header_offset = offset;
@@ -166,7 +171,6 @@ void b_prange_load_macho(struct binary *binary, prange_t pr, size_t offset, cons
binary->actual_cpusubtype = binary->mach->hdr->cpusubtype;
do_load_commands(binary);
- do_symbols(binary);
#undef _arg
}
View
@@ -30,6 +30,7 @@ __attribute__((const)) range_t b_macho_sectrange(const struct binary *binary, co
void b_macho_store(struct binary *binary, const char *path);
void b_prange_load_macho(struct binary *binary, prange_t range, size_t offset, const char *name);
+void b_prange_load_macho_nosyms(struct binary *binary, prange_t range, size_t offset, const char *name);
uint32_t b_allocate_from_macho_fd(int fd);
void b_inject_into_macho_fd(const struct binary *binary, int fd, addr_t (*find_hack_func)(const struct binary *binary));
View
@@ -21,22 +21,37 @@ static uint32_t b_lookup_nlist(const struct binary *load, const struct binary *t
return sym;
}
-static void relocate_area(const struct binary *load, const struct binary *target, lookupsym_t lookup_sym, uint32_t slide, uint32_t reloff, uint32_t nreloc) {
+static void relocate_area(const struct binary *load, const struct binary *target, enum reloc_mode mode, lookupsym_t lookup_sym, uint32_t slide, uint32_t reloff, uint32_t nreloc) {
struct relocation_info *things = rangeconv_off((range_t) {load, reloff, nreloc * sizeof(struct relocation_info)}, MUST_FIND).start;
for(uint32_t i = 0; i < nreloc; i++) {
- //assert(!things[i].r_pcrel);
assert(things[i].r_length == 2);
- uint32_t *p = rangeconv((range_t) {load, things[i].r_address, 4}, MUST_FIND).start;
+ uint32_t address = things[i].r_address;
+ if(address == 0) continue;
+ uint32_t *p = rangeconv((range_t) {load, address, 4}, MUST_FIND).start;
+
uint32_t value;
if(things[i].r_extern) {
+ if(mode == RELOC_LOCAL_ONLY) continue;
value = b_lookup_nlist(load, target, lookup_sym, things[i].r_symbolnum);
} else {
+ if(mode == RELOC_EXTERN_ONLY) continue;
// *shrug*
value = slide;
}
+
+ things[i].r_address = 0;
+
+ if(mode == RELOC_EXTERN_ONLY && things[i].r_type != ARM_RELOC_VANILLA) {
+ die("non-VANILLA relocation but we are relocating without knowing the slide; use __attribute__((long_call)) to get rid of these");
+ }
switch(things[i].r_type) {
case ARM_RELOC_VANILLA:
- *p += value;
+ //printf("%x, %x += %x\n", address, *p, value);
+ if(rangeconv((range_t) {load, *p, 0}, 0).start) {
+ // when dyld_stub_binding_helper (which would just crash, btw) is present, entries in the indirect section point to it; usually this increments to point to the right dyld_stub_binding_helper, then that's clobbered by the indirect code. when we do prelinking, the indirect code runs first, so we add this check (easier than actually checking that it's not in the indirect section) to make sure we're not relocating nonsense.
+ *p += value;
+ }
+ //else printf("skipping %x\n", *p);
break;
case ARM_RELOC_BR24: {
if(!things[i].r_pcrel) die("weird relocation");
@@ -68,7 +83,7 @@ static void relocate_area(const struct binary *load, const struct binary *target
}
}
-void b_relocate(struct binary *load, const struct binary *target, lookupsym_t lookup_sym, uint32_t slide) {
+void b_relocate(struct binary *load, const struct binary *target, enum reloc_mode mode, lookupsym_t lookup_sym, uint32_t slide) {
CMD_ITERATE(load->mach->hdr, cmd) {
switch(cmd->cmd) {
case LC_SYMTAB:
@@ -84,8 +99,8 @@ void b_relocate(struct binary *load, const struct binary *target, lookupsym_t lo
assert(load->mach->symtab);
assert(load->mach->dysymtab);
- relocate_area(load, target, lookup_sym, slide, load->mach->dysymtab->locreloff, load->mach->dysymtab->nlocrel);
- relocate_area(load, target, lookup_sym, slide, load->mach->dysymtab->extreloff, load->mach->dysymtab->nextrel);
+ if(mode != RELOC_EXTERN_ONLY) relocate_area(load, target, mode, lookup_sym, slide, load->mach->dysymtab->locreloff, load->mach->dysymtab->nlocrel);
+ if(mode != RELOC_LOCAL_ONLY) relocate_area(load, target, mode, lookup_sym, slide, load->mach->dysymtab->extreloff, load->mach->dysymtab->nextrel);
CMD_ITERATE(load->mach->hdr, cmd) {
if(cmd->cmd == LC_SEGMENT) {
@@ -106,13 +121,17 @@ void b_relocate(struct binary *load, const struct binary *target, lookupsym_t lo
uint32_t sym = indirect[i];
switch(sym) {
case INDIRECT_SYMBOL_LOCAL:
+ if(mode == RELOC_EXTERN_ONLY) continue;
things[i] += slide;
break;
case INDIRECT_SYMBOL_ABS:
break;
default:
+ if(mode == RELOC_LOCAL_ONLY) continue;
+ //printf("setting indirect symbol %x\n", sect->addr + 4*i);
things[i] = b_lookup_nlist(load, target, lookup_sym, sym);
}
+ indirect[i] = INDIRECT_SYMBOL_ABS;
}
break;
}
@@ -130,10 +149,10 @@ void b_relocate(struct binary *load, const struct binary *target, lookupsym_t lo
die("unrecognized section type %02x", type);
}
- relocate_area(load, target, lookup_sym, slide, sect->reloff, sect->nreloc);
- sect->addr += slide;
+ relocate_area(load, target, mode, lookup_sym, slide, sect->reloff, sect->nreloc);
+ if(mode != RELOC_EXTERN_ONLY) sect->addr += slide;
}
- seg->vmaddr += slide;
+ if(mode != RELOC_EXTERN_ONLY) seg->vmaddr += slide;
}
}
}
View
@@ -3,8 +3,14 @@
typedef uint32_t (*lookupsym_t)(const struct binary *binary, const char *sym);
+enum reloc_mode {
+ RELOC_DEFAULT,
+ RELOC_LOCAL_ONLY,
+ RELOC_EXTERN_ONLY
+};
+
__BEGIN_DECLS
-void b_relocate(struct binary *load, const struct binary *target, lookupsym_t lookup_sym, uint32_t slide);
+void b_relocate(struct binary *load, const struct binary *target, enum reloc_mode mode, lookupsym_t lookup_sym, uint32_t slide);
__END_DECLS

0 comments on commit 9731118

Please sign in to comment.