mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-07 13:51:16 +00:00
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:
parent
65a5d2b5d5
commit
3dfadc0b30
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user