Fix regression in fatmach0

$ r2 -a arm -b 64 mfan
Not enough data for SClassRoT
Not enough data for SClassRoT

mach0_classes.c handle the buffer of the mach instead of the whole
fatmach file. Thus we should revert physical addresses by obj->boffset on
sections.
This commit is contained in:
Álvaro Felipe Melchor 2016-12-02 17:46:48 +01:00
parent 35eb178c8b
commit fc6000a8be
4 changed files with 52 additions and 44 deletions

View File

@ -1026,7 +1026,9 @@ static RBinFile *r_bin_file_create_append(RBin *bin, const char *file, const ut8
static RBinFile *r_bin_file_xtr_load_bytes(RBin *bin, RBinXtrPlugin *xtr, const char *filename, const ut8 *bytes, ut64 sz, ut64 file_sz, ut64 baseaddr, ut64 loadaddr, int idx, int fd, int rawstr) {
RBinFile *bf = bin? r_bin_file_find_by_name (bin, filename): NULL;
if (!bf) {
if (!bin) return NULL;
if (!bin) {
return NULL;
}
bf = r_bin_file_create_append (bin, filename, bytes, sz, file_sz, rawstr, fd, xtr->name);
if (!bf) {
return bf;
@ -1047,7 +1049,7 @@ static RBinFile *r_bin_file_xtr_load_bytes(RBin *bin, RBinXtrPlugin *xtr, const
}
}
} else if (xtr && xtr->extract_from_bytes) {
if (idx == 0) idx = 1;
if (!idx) idx = 1;
RBinXtrData *xtr_data = xtr->extract_from_bytes (bin, bytes, sz, idx);
if (xtr_data) {
if (!r_bin_file_object_new_from_xtr_data (bin, bf, baseaddr, loadaddr, xtr_data)) {
@ -1256,7 +1258,9 @@ static int r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf, ut64 bas
ut64 offset = data? data->offset: 0;
ut64 sz = data ? data->size : 0;
if (!data || !bf) return false;
if (!data || !bf) {
return false;
}
// for right now the bytes used will just be the offest into the binfile buffer
// if the extraction requires some sort of transformation then this will need to be fixed

View File

@ -1264,7 +1264,7 @@ struct section_t* MACH0_(get_sections)(struct MACH0_(obj_t)* bin) {
sections[i].size = (ut64)bin->sects[i].size;
sections[i].align = bin->sects[i].align;
sections[i].flags = bin->sects[i].flags;
r_str_ncpy (sectname, bin->sects[i].sectname, sizeof (sectname)-1);
r_str_ncpy (sectname, bin->sects[i].sectname, sizeof (sectname) - 1);
// hack to support multiple sections with same name
snprintf (segname, sizeof (segname), "%d", i); // wtf
for (j = 0; j < bin->nsegs; j++) {
@ -2225,8 +2225,9 @@ ut64 MACH0_(get_main)(struct MACH0_(obj_t)* bin) {
}
free (symbols);
if (!addr && bin->main_cmd.cmd == LC_MAIN)
if (!addr && bin->main_cmd.cmd == LC_MAIN) {
addr = bin->entry + bin->baddr;
}
if (!addr) {
ut8 b[128];
@ -2235,11 +2236,12 @@ ut64 MACH0_(get_main)(struct MACH0_(obj_t)* bin) {
if (entry > bin->size || entry + sizeof (b) > bin->size)
return 0;
i = r_buf_read_at (bin->b, entry, b, sizeof (b));
if (i < 1)
if (i < 1) {
return 0;
for (i=0; i<64; i++) {
}
for (i = 0; i < 64; i++) {
if (b[i] == 0xe8 && !b[i+3] && !b[i+4]) {
int delta = b[i+1] | (b[i+2]<<8) | (b[i+3]<<16) | (b[i+4]<<24);
int delta = b[i+1] | (b[i+2] << 8) | (b[i+3] << 16) | (b[i+4] << 24);
return bin->entry + i + 5 + delta;
}

View File

@ -110,6 +110,7 @@ static mach0_ut get_pointer(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *arch
static RList *sctns = NULL;
RListIter *iter = NULL;
RBinSection *s = NULL;
RBinObject *obj = arch ? arch->o : NULL;
if (!sctns) {
sctns = r_bin_plugin_mach.sections (arch);
@ -129,11 +130,7 @@ static mach0_ut get_pointer(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *arch
if (left) {
*left = s->vsize - (addr - s->vaddr);
}
r = (s->paddr + (addr - s->vaddr));
#if 0
r_list_free (sctns);
sctns = NULL;
#endif
r = (s->paddr - obj->boffset + (addr - s->vaddr));
return r;
}
}
@ -145,11 +142,6 @@ static mach0_ut get_pointer(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *arch
*left = 0;
}
#if 0
r_list_free (sctns);
sctns = NULL;
#endif
return 0;
}
@ -1062,19 +1054,20 @@ RList *MACH0_(parse_classes)(RBinFile *arch) {
RBinClass *klass = NULL;
RListIter *iter = NULL;
RBinSection *s = NULL;
RBinObject *obj = arch ? arch->o : NULL;
ut32 i = 0, size = 0;
RList *sctns = NULL;
bool is_found = false;
mach0_ut p = 0;
ut32 left = 0;
int len;
int len, paddr;
bool bigendian;
ut8 pp[sizeof (mach0_ut)] = {0};
if (!arch || !arch->o || !arch->o->bin_obj || !arch->o->info) {
if (!arch || !obj || !obj->bin_obj || !obj->info) {
return NULL;
}
bigendian = arch->o->info->big_endian;
bigendian = obj->info->big_endian;
/* check if it's Swift */
//ret = parse_swift_classes (arch);
@ -1100,15 +1093,13 @@ RList *MACH0_(parse_classes)(RBinFile *arch) {
}
// end of seaching of section with name __objc_classlist
if (!ret && !(ret = r_list_new ())) {
if (!ret && !(ret = r_list_newf ((RListFree)__r_bin_class_free))) {
// retain just for debug
// eprintf ("RList<RBinClass> allocation error\n");
goto get_classes_error;
}
ret->free = (RListFree)__r_bin_class_free;
// start of getting information about each class in file
paddr = s->paddr - obj->boffset;
for (i = 0; i < s->size; i += sizeof (mach0_ut)) {
if (!(klass = R_NEW0 (RBinClass))) {
// retain just for debug
@ -1134,14 +1125,13 @@ RList *MACH0_(parse_classes)(RBinFile *arch) {
break;
}
size = sizeof (mach0_ut);
if (s->paddr > arch->size || s->paddr + size > arch->size) {
if (paddr > arch->size || paddr + size > arch->size) {
goto get_classes_error;
}
if (s->paddr + size < s->paddr) {
if (paddr + size < paddr) {
goto get_classes_error;
}
len = r_buf_read_at (arch->buf, s->paddr + i, pp, sizeof (mach0_ut));
len = r_buf_read_at (arch->buf, paddr + i, pp, sizeof (mach0_ut));
if (len != sizeof (mach0_ut)) {
goto get_classes_error;
}

View File

@ -54,7 +54,9 @@ static int load(RBinFile *arch) {
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
ut64 sz = arch ? r_buf_size (arch->buf): 0;
if (!arch || !arch->o) return false;
if (!arch || !arch->o) {
return false;
}
res = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb);
if (!arch->o || !res) {
@ -75,8 +77,9 @@ static int destroy(RBinFile *arch) {
static ut64 baddr(RBinFile *arch) {
struct MACH0_(obj_t) *bin;
if (!arch || !arch->o || !arch->o->bin_obj)
if (!arch || !arch->o || !arch->o->bin_obj) {
return 0LL;
}
bin = arch->o->bin_obj;
return MACH0_(get_baddr)(bin);
}
@ -120,14 +123,16 @@ static RList* sections(RBinFile *arch) {
RBinObject *obj = arch ? arch->o : NULL;
int i;
if (!obj || !obj->bin_obj || !(ret = r_list_new ()))
if (!obj || !obj->bin_obj || !(ret = r_list_newf ((RListFree)free))) {
return NULL;
ret->free = free;
if (!(sections = MACH0_(get_sections) (obj->bin_obj)))
}
if (!(sections = MACH0_(get_sections) (obj->bin_obj))) {
return ret;
}
for (i = 0; !sections[i].last; i++) {
if (!(ptr = R_NEW0 (RBinSection)))
if (!(ptr = R_NEW0 (RBinSection))) {
break;
}
strncpy (ptr->name, (char*)sections[i].name, R_BIN_SIZEOF_STRINGS);
if (strstr (ptr->name, "la_symbol_ptr")) {
#ifndef R_BIN_MACH064
@ -147,8 +152,9 @@ static RList* sections(RBinFile *arch) {
ptr->paddr = sections[i].offset + obj->boffset;
ptr->vaddr = sections[i].addr;
ptr->add = true;
if (ptr->vaddr == 0)
if (!ptr->vaddr) {
ptr->vaddr = ptr->paddr;
}
ptr->srwx = sections[i].srwx | R_BIN_SCN_MAP;
r_list_append (ret, ptr);
}
@ -212,11 +218,13 @@ static RList* symbols(RBinFile *arch) {
ut64 value = 0, address = 0;
const ut8* temp = bin->func_start;
const ut8* temp_end = bin->func_start + bin->func_size;
while (temp+3 < temp_end && *temp) {
while (temp + 3 < temp_end && *temp) {
temp = r_uleb128_decode (temp, NULL, &value);
address += value;
ptr = R_NEW0 (RBinSymbol);
if (!ptr) break;
if (!ptr) {
break;
}
ptr->vaddr = bin->baddr + address;
ptr->paddr = address;
ptr->size = 0;
@ -247,15 +255,17 @@ static RList* imports(RBinFile *arch) {
int i;
RBinObject *obj = arch ? arch->o : NULL;
if (!obj || !bin || !obj->bin_obj || !(ret = r_list_newf (free)))
if (!obj || !bin || !obj->bin_obj || !(ret = r_list_newf (free))) {
return NULL;
if (!(imports = MACH0_(get_imports) (arch->o->bin_obj)))
}
if (!(imports = MACH0_(get_imports) (arch->o->bin_obj))) {
return ret;
}
bin->has_canary = false;
for (i = 0; !imports[i].last; i++) {
if (!(ptr = R_NEW0 (RBinImport)))
if (!(ptr = R_NEW0 (RBinImport))) {
break;
}
name = imports[i].name;
type = "FUNC";
@ -268,14 +278,16 @@ static RList* imports(RBinFile *arch) {
}
// Remove the extra underscore that every import seems to have in Mach-O.
if (*name == '_')
if (*name == '_') {
name++;
}
ptr->name = strdup (name);
ptr->bind = r_str_const ("NONE");
ptr->type = r_str_const (type);
ptr->ordinal = imports[i].ord;
if (bin->imports_by_ord && ptr->ordinal < bin->imports_by_ord_size)
if (bin->imports_by_ord && ptr->ordinal < bin->imports_by_ord_size) {
bin->imports_by_ord[ptr->ordinal] = ptr;
}
if (!strcmp (name, "__stack_chk_fail") ) {
bin->has_canary = true;
}