Fixed several issues on PE/ELF/MACH0

- relocs, entry0 vaddr and baddr
- fix tiny.elf crash (null deref on *bin ptr)
This commit is contained in:
pancake 2014-06-27 01:20:54 +02:00
parent 65a5d2b5d5
commit 3dfadc0b30
6 changed files with 76 additions and 50 deletions

View File

@ -180,7 +180,7 @@ static Elf_(Shdr)* Elf_(r_bin_elf_get_section_by_name)(struct Elf_(r_bin_elf_obj
int i;
ut32 cur_strtab_len;
if (!bin->shdr || !bin->strtab)
if (!bin || !bin->shdr || !bin->strtab)
return NULL;
for (i = 0; i < bin->ehdr.e_shnum; i++) {
if(!UT32_SUB(&cur_strtab_len, bin->shstrtab_section->sh_size, bin->shdr[i].sh_name))
@ -265,14 +265,13 @@ static ut64 Elf_(get_import_addr)(struct Elf_(r_bin_elf_obj_t) *bin, int sym) {
break;
}
}
free(rel);
free (rel);
return plt_sym_addr;
}
int Elf_(r_bin_elf_has_nx)(struct Elf_(r_bin_elf_obj_t) *bin) {
int i;
if (bin->phdr)
if (bin && bin->phdr)
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_GNU_STACK)
return (!(bin->phdr[i].p_flags & 1))? 1: 0;
@ -281,7 +280,7 @@ int Elf_(r_bin_elf_has_nx)(struct Elf_(r_bin_elf_obj_t) *bin) {
int Elf_(r_bin_elf_has_relro)(struct Elf_(r_bin_elf_obj_t) *bin) {
int i;
if (bin->phdr)
if (bin && bin->phdr)
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_GNU_RELRO)
return 1;
@ -290,32 +289,29 @@ int Elf_(r_bin_elf_has_relro)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 Elf_(r_bin_elf_get_baddr)(struct Elf_(r_bin_elf_obj_t) *bin) {
int i;
if (!bin->phdr)
return 0;
/* hopefully.. the first PT_LOAD is base */
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_LOAD)
return (ut64)bin->phdr[i].p_vaddr;
if (bin && bin->phdr)
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_LOAD)
return (ut64)bin->phdr[i].p_vaddr;
return 0;
}
ut64 Elf_(r_bin_elf_get_boffset)(struct Elf_(r_bin_elf_obj_t) *bin) {
int i;
if (!bin->phdr)
return 0;
/* hopefully.. the first PT_LOAD is base */
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_LOAD)
return (ut64) bin->phdr[i].p_offset;
if (bin && bin->phdr)
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_LOAD)
return (ut64) bin->phdr[i].p_offset;
return 0;
}
ut64 Elf_(r_bin_elf_get_init_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
ut8 buf[512];
if (!bin)
return 0LL;
if (r_buf_read_at (bin->b, entry+16, buf, sizeof (buf)) == -1) {
eprintf ("Warning: read (init_offset)\n");
return 0;
@ -330,6 +326,7 @@ ut64 Elf_(r_bin_elf_get_init_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 Elf_(r_bin_elf_get_fini_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
ut8 buf[512];
if (!bin) return 0LL;
if (r_buf_read_at (bin->b, entry+11, buf, sizeof (buf)) == -1) {
eprintf ("Warning: read (get_fini)\n");
@ -337,13 +334,17 @@ ut64 Elf_(r_bin_elf_get_fini_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
}
if (*buf == 0x68) { // push // x86/32 only
memmove (buf, buf+1, 4);
return (ut64)((int)(buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24)))-bin->baddr;
return (ut64)((int)(buf[0]+(buf[1]<<8)+
(buf[2]<<16)+(buf[3]<<24)))-bin->baddr;
}
return 0;
}
ut64 Elf_(r_bin_elf_get_entry_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 entry = (ut64) bin->ehdr.e_entry;
ut64 entry;
if (!bin)
return 0LL;
entry = (ut64) bin->ehdr.e_entry;
if (entry == 0LL) {
entry = Elf_(r_bin_elf_get_section_offset)(bin, ".init.text");
if (entry != UT64_MAX) return entry;
@ -360,6 +361,8 @@ ut64 Elf_(r_bin_elf_get_entry_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 Elf_(r_bin_elf_get_main_offset)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
ut8 buf[512];
if (!bin)
return 0LL;
if (r_buf_read_at (bin->b, entry, buf, sizeof (buf)) == -1) {
eprintf ("Warning: read (main)\n");
@ -543,7 +546,10 @@ char* Elf_(r_bin_elf_get_machine_name)(struct Elf_(r_bin_elf_obj_t) *bin) {
}
char* Elf_(r_bin_elf_get_file_type)(struct Elf_(r_bin_elf_obj_t) *bin) {
ut32 e_type = (ut32)bin->ehdr.e_type; // cast to avoid warn in iphone-gcc, must be ut16
ut32 e_type;
if (!bin)
return NULL;
e_type = (ut32)bin->ehdr.e_type; // cast to avoid warn in iphone-gcc, must be ut16
switch (e_type) {
case ET_NONE: return strdup ("NONE (None)");
case ET_REL: return strdup ("REL (Relocatable file)");
@ -640,7 +646,7 @@ char *Elf_(r_bin_elf_get_rpath)(struct Elf_(r_bin_elf_obj_t) *bin) {
char *ret = NULL;
int ndyn, i, j, len;
if (!bin->phdr)
if (!bin || !bin->phdr)
return NULL;
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_DYNAMIC) {
@ -834,7 +840,7 @@ struct r_bin_elf_lib_t* Elf_(r_bin_elf_get_libs)(struct Elf_(r_bin_elf_obj_t) *b
ut64 stroff = 0;
int ndyn, i, j, k, len;
if (!bin->phdr)
if (!bin || !bin->phdr)
return NULL;
for (i = 0; i < bin->ehdr.e_phnum; i++)
if (bin->phdr[i].p_type == PT_DYNAMIC) {
@ -942,7 +948,7 @@ struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj
Elf_(Sym) *sym;
char *strtab;
if (!bin->shdr || bin->ehdr.e_shnum == 0 || bin->ehdr.e_shnum == 0xffff)
if (!bin || !bin->shdr || bin->ehdr.e_shnum == 0 || bin->ehdr.e_shnum == 0xffff)
return NULL;
if (bin->ehdr.e_type == ET_REL) {
// XXX: we must obey shndx here
@ -1106,7 +1112,8 @@ if (
struct r_bin_elf_field_t* Elf_(r_bin_elf_get_fields)(struct Elf_(r_bin_elf_obj_t) *bin) {
struct r_bin_elf_field_t *ret = NULL;
int i = 0, j;
if (!bin)
return NULL;
if ((ret = malloc ((bin->ehdr.e_phnum+3 + 1) *
sizeof (struct r_bin_elf_field_t))) == NULL)
return NULL;

View File

@ -936,12 +936,14 @@ struct r_bin_mach0_addr_t* MACH0_(r_bin_mach0_get_entrypoint)(struct MACH0_(r_bi
return NULL;
if (!(entry = malloc (sizeof (struct r_bin_mach0_addr_t))))
return NULL;
// hack to bypass this test
bin->entry = NULL;
if (bin->entry) {
entry->offset = MACH0_(r_bin_mach0_addr_to_offset)(bin, bin->entry);
entry->addr = bin->entry;
return entry;
}
entry->addr = 0LL;
//entry->addr = 0LL;
if (!bin->entry || (entry->offset==0)) {
// XXX: section name doesnt matters at all.. just check for exec flags
for (i = 0; i < bin->nsects; i++) {

View File

@ -28,8 +28,9 @@ static void setimpord (ELFOBJ* eobj, ut32 ord, RBinImport *ptr) {
static Sdb* get_sdb (RBinObject *o) {
if (!o) return NULL;
struct Elf_(r_bin_elf_obj_t) *bin = (struct Elf_(r_bin_elf_obj_t) *) o->bin_obj;
if (bin->kv) return bin->kv;
struct Elf_(r_bin_elf_obj_t) *bin = \
(struct Elf_(r_bin_elf_obj_t) *) o->bin_obj;
if (bin && bin->kv) return bin->kv;
return NULL;
}
@ -40,7 +41,8 @@ static void * load_bytes(const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
tbuf = r_buf_new();
r_buf_set_bytes (tbuf, buf, sz);
res = Elf_(r_bin_elf_new_buf) (tbuf);
sdb_ns_set (sdb, "info", res->kv);
if (res)
sdb_ns_set (sdb, "info", res->kv);
r_buf_free (tbuf);
return res;
}
@ -49,7 +51,8 @@ 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 R_FALSE;
arch->o->bin_obj = load_bytes (bytes, sz, arch->o->loadaddr, arch->sdb);
arch->o->bin_obj = load_bytes (bytes, sz,
arch->o->loadaddr, arch->sdb);
if (!(arch->o->bin_obj))
return R_FALSE;
return R_TRUE;

View File

@ -8,6 +8,7 @@
static int check(RBinFile *arch);
static int check_bytes(const ut8 *buf, ut64 length);
static RBinInfo* info(RBinFile *arch);
static Sdb* get_sdb (RBinObject *o) {
if (!o) return NULL;
@ -52,7 +53,18 @@ static int destroy(RBinFile *arch) {
}
static ut64 baddr(RBinFile *arch) {
return MACH0_(r_bin_mach0_get_baddr) (arch->o->bin_obj);
RBinInfo *bi = info (arch);
if (strstr (bi->type, "Exe")) {
int is_arm = !strcmp (bi->arch, "arm");
free (bi);
// WARNING: THIS IS VERY HACKY
if (bi->bits==32)
return 0x1000;
//return MACH0_(r_bin_mach0_get_baddr) (arch->o->bin_obj);
return is_arm? 0x1000: 0x100000000;
}
free (bi);
return 0LL;
}
static RList* entries(RBinFile *arch) {
@ -68,7 +80,7 @@ static RList* entries(RBinFile *arch) {
return ret;
if ((ptr = R_NEW0 (RBinAddr))) {
ptr->paddr = entry->offset + obj->boffset;
ptr->vaddr = entry->addr;
ptr->vaddr = entry->addr; //
r_list_append (ret, ptr);
}
free (entry);

View File

@ -195,7 +195,7 @@ static RList* imports(RBinFile *arch) {
rel->additive = 0;
rel->import = ptr;
rel->addend = 0;
rel->vaddr = imports[i].vaddr;
rel->vaddr = imports[i].vaddr + baddr (arch);
rel->paddr = imports[i].paddr;
r_list_append (relocs, rel);
}

View File

@ -442,10 +442,11 @@ static int bin_entry (RCore *r, int mode, ut64 baddr, int va) {
r_cons_printf ("[");
r_list_foreach (entries, iter, entry) {
ut64 paddr = entry->paddr;
ut64 vaddr = r_bin_get_vaddr (r->bin, baddr, paddr, entry->vaddr);
ut64 vaddr = r_bin_get_vaddr (r->bin, baddr,
paddr, entry->vaddr);
r_cons_printf ("%s%"PFMT64d,
iter->p?",":"",
va?vaddr: paddr);
iter->p? ",":"",
va? vaddr: paddr);
}
r_cons_printf ("]");
} else
@ -474,13 +475,16 @@ static int bin_entry (RCore *r, int mode, ut64 baddr, int va) {
r_list_foreach (entries, iter, entry) {
ut64 paddr = entry->paddr;
ut64 vaddr = r_bin_get_vaddr (r->bin, baddr, paddr, entry->vaddr);
ut64 vaddr = r_bin_get_vaddr (r->bin, baddr,
paddr, entry->vaddr);
if (mode) {
r_cons_printf ("f entry%i @ 0x%08"PFMT64x"\n",
i, va?vaddr: paddr);
r_cons_printf ("s entry%i\n", i);
} else r_cons_printf ("addr=0x%08"PFMT64x" off=0x%08"PFMT64x" baddr=0x%08"PFMT64x"\n",
vaddr, paddr, baddr);
} else r_cons_printf ("addr=0x%08"PFMT64x
" off=0x%08"PFMT64x
" baddr=0x%08"PFMT64x"\n",
va?vaddr:paddr, paddr, baddr);
i++;
}
if (!mode) r_cons_printf ("\n%i entrypoints\n", i);
@ -526,17 +530,15 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) {
r_cons_printf ("[");
r_list_foreach (relocs, iter, reloc) {
if (reloc->import)
r_cons_printf ("%s{\"name\":\"%s\",", iter->p?",":"", reloc->import->name);
else
r_cons_printf ("%s{\"name\":null,", iter->p?",":"");
r_cons_printf ("%s{\"name\":\"%s\",",
iter->p?",":"", reloc->import->name);
else r_cons_printf ("%s{\"name\":null,",
iter->p?",":"");
r_cons_printf ("\"type\":\"%s\","
"\"paddr\":%"PFMT64d","
//"\"addend\":%"PFMT64d","
"\"physical\":%"PFMT64d"}",
bin_reloc_type_name (reloc),
baddr+reloc->vaddr,
//reloc->addend,
reloc->paddr);
reloc->vaddr, reloc->paddr);
}
r_cons_printf ("]");
} else
@ -548,7 +550,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) {
"reloc.%s", reloc->import->name);
r_name_filter (str, 0);
//r_str_replace_char (str, '$', '_');
r_flag_set (r->flags, str, va?baddr+reloc->vaddr:reloc->paddr,
r_flag_set (r->flags, str, va?reloc->vaddr:reloc->paddr,
bin_reloc_size (reloc), 0);
} else {
// TODO(eddyb) implement constant relocs.
@ -558,7 +560,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) {
if ((mode & R_CORE_BIN_SIMPLE)) {
r_list_foreach (relocs, iter, reloc) {
r_cons_printf ("0x%08"PFMT64x" %s\n",
va?baddr+reloc->vaddr:reloc->paddr, reloc->import ? reloc->import->name : "");
va?reloc->vaddr:reloc->paddr, reloc->import ? reloc->import->name : "");
}
} else {
if (mode) {
@ -568,7 +570,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) {
char *str = strdup (reloc->import->name);
r_str_replace_char (str, '$', '_');
r_cons_printf ("f reloc.%s @ 0x%08"PFMT64x"\n", str,
va?baddr+reloc->vaddr:reloc->paddr);
va?reloc->vaddr:reloc->paddr);
free (str);
} else {
// TODO(eddyb) implement constant relocs.
@ -579,7 +581,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) {
r_cons_printf ("[Relocations]\n");
r_list_foreach (relocs, iter, reloc) {
r_cons_printf ("addr=0x%08"PFMT64x" off=0x%08"PFMT64x" type=%s",
baddr+reloc->vaddr, reloc->paddr, bin_reloc_type_name (reloc));
reloc->vaddr, reloc->paddr, bin_reloc_type_name (reloc));
if (reloc->import && reloc->import->name[0])
r_cons_printf (" %s", reloc->import->name);
if (reloc->addend) {