added reloc into coff

This commit is contained in:
Álvaro Felipe Melchor 2016-08-16 23:43:05 +02:00
parent 21b1befc66
commit 80026a5d5e
4 changed files with 115 additions and 47 deletions

View File

@ -4,7 +4,7 @@
#include "coff.h"
bool r_coff_supported_arch (const ut8 *buf) {
bool r_coff_supported_arch(const ut8 *buf) {
ut16 arch = *(ut16*)buf;
switch (arch) {
case COFF_FILE_MACHINE_AMD64:
@ -17,12 +17,12 @@ bool r_coff_supported_arch (const ut8 *buf) {
}
}
int r_coff_is_stripped (struct r_bin_coff_obj *obj) {
int r_coff_is_stripped(struct r_bin_coff_obj *obj) {
return !!(obj->hdr.f_flags & (COFF_FLAGS_TI_F_RELFLG | \
COFF_FLAGS_TI_F_LNNO | COFF_FLAGS_TI_F_LSYMS));
}
const char *r_coff_symbol_name (struct r_bin_coff_obj *obj, void *ptr) {
char *r_coff_symbol_name(struct r_bin_coff_obj *obj, void *ptr) {
char n[256] = {0};
int len = 0, offset = 0;
union {
@ -49,7 +49,7 @@ const char *r_coff_symbol_name (struct r_bin_coff_obj *obj, void *ptr) {
return strdup (n);
}
static int r_coff_rebase_sym (struct r_bin_coff_obj *obj, RBinAddr *addr, struct coff_symbol *sym) {
static int r_coff_rebase_sym(struct r_bin_coff_obj *obj, RBinAddr *addr, struct coff_symbol *sym) {
if (sym->n_scnum < 1 || sym->n_scnum > obj->hdr.f_nscns) {
return 0;
}

View File

@ -28,7 +28,7 @@ bool r_coff_supported_arch(const ut8 *buf); /* Reads two bytes from buf. */
struct r_bin_coff_obj* r_bin_coff_new_buf(struct r_buf_t *buf);
void r_bin_coff_free(struct r_bin_coff_obj *obj);
RBinAddr *r_coff_get_entry(struct r_bin_coff_obj *obj);
const char *r_coff_symbol_name (struct r_bin_coff_obj *obj, void *ptr);
char *r_coff_symbol_name (struct r_bin_coff_obj *obj, void *ptr);
int r_coff_is_stripped (struct r_bin_coff_obj *obj);
#endif /* COFF_H */

View File

@ -172,4 +172,11 @@ struct coff_symbol {
ut8 n_numaux; /* Auxiliary Count */
} __attribute__((packed));
struct coff_reloc {
ut32 r_vaddr; /* Reference Address */
ut32 r_symndx; /* Symbol index */
ut16 r_type; /* Type of relocation */
} __attribute__((packed));
#endif /* COFF_SPECS_H */

View File

@ -59,6 +59,51 @@ static RBinAddr *binsym(RBinFile *arch, int sym) {
return NULL;
}
static bool _fill_bin_symbol(struct r_bin_coff_obj *bin, int idx, RBinSymbol **sym) {
RBinSymbol *ptr = *sym;
char * coffname = NULL;
struct coff_symbol *s = NULL;
if (idx > bin->hdr.f_nsyms) {
return false;
}
s = &bin->symbols[idx];
coffname = r_coff_symbol_name (bin, s);
if (!coffname) {
return false;
}
ptr->name = strdup (coffname);
free (coffname);
ptr->forwarder = r_str_const ("NONE");
switch (s->n_sclass) {
case COFF_SYM_CLASS_FUNCTION:
ptr->type = r_str_const ("FUNC");
break;
case COFF_SYM_CLASS_FILE:
ptr->type = r_str_const ("FILE");
break;
case COFF_SYM_CLASS_SECTION:
ptr->type = r_str_const ("SECTION");
break;
case COFF_SYM_CLASS_EXTERNAL:
ptr->type = r_str_const ("EXTERNAL");
break;
case COFF_SYM_CLASS_STATIC:
ptr->type = r_str_const ("STATIC");
break;
default:
ptr->type = r_str_const (sdb_fmt (0, "%i", s->n_sclass));
break;
}
if (bin->symbols[idx].n_scnum < bin->hdr.f_nscns) {
ptr->paddr = bin->scn_hdrs[s->n_scnum].s_scnptr + s->n_value;
}
ptr->size = 4;
ptr->ordinal = 0;
return true;
}
static RList *entries(RBinFile *arch) {
struct r_bin_coff_obj *obj = (struct r_bin_coff_obj*)arch->o->bin_obj;
RList *ret;
@ -119,61 +164,26 @@ static RList *sections(RBinFile *arch) {
}
static RList *symbols(RBinFile *arch) {
const char *coffname;
size_t i;
int i;
RList *ret = NULL;
RBinSymbol *ptr = NULL;
struct r_bin_coff_obj *obj = (struct r_bin_coff_obj*)arch->o->bin_obj;
if (!(ret = r_list_newf (free))) {
struct r_bin_coff_obj *obj = (struct r_bin_coff_obj*)arch->o->bin_obj;
if (!(ret = r_list_new ())) {
return ret;
}
ret->free = free;
if (obj->symbols) {
for (i = 0; i < obj->hdr.f_nsyms; i++) {
if (!(ptr = R_NEW0 (RBinSymbol))) {
break;
}
coffname = r_coff_symbol_name (obj, &obj->symbols[i]);
if (!coffname) {
free (ptr);
break;
if (_fill_bin_symbol (obj, i, &ptr)) {
r_list_append (ret, ptr);
}
ptr->name = strdup (coffname);
ptr->forwarder = r_str_const ("NONE");
switch (obj->symbols[i].n_sclass) {
case COFF_SYM_CLASS_FUNCTION:
ptr->type = r_str_const ("FUNC");
break;
case COFF_SYM_CLASS_FILE:
ptr->type = r_str_const ("FILE");
break;
case COFF_SYM_CLASS_SECTION:
ptr->type = r_str_const ("SECTION");
break;
case COFF_SYM_CLASS_EXTERNAL:
ptr->type = r_str_const ("EXTERNAL");
break;
case COFF_SYM_CLASS_STATIC:
ptr->type = r_str_const ("STATIC");
break;
default:
ptr->type = r_str_const (sdb_fmt(0, "%i", obj->symbols[i].n_sclass));
break;
}
if (obj->symbols[i].n_scnum < obj->hdr.f_nscns) {
ptr->paddr = obj->scn_hdrs[obj->symbols[i].n_scnum].s_scnptr +
obj->symbols[i].n_value;
}
ptr->size = 4;
ptr->ordinal = 0;
r_list_append (ret, ptr);
i += obj->symbols[i].n_numaux;
}
}
return ret;
}
@ -186,7 +196,58 @@ static RList *libs(RBinFile *arch) {
}
static RList *relocs(RBinFile *arch) {
return NULL;
struct r_bin_coff_obj *bin = (struct r_bin_coff_obj*)arch->o->bin_obj;
RBinReloc *reloc;
struct coff_reloc *rel;
int j, i = 0;
RList *list_rel;
list_rel = r_list_new ();
if (!list_rel || !bin || !bin->scn_hdrs) {
return NULL;
}
for (i = 0; i < bin->hdr.f_nscns; i++) {
if (bin->scn_hdrs[i].s_nreloc) {
int len = 0, size = bin->scn_hdrs[i].s_nreloc * sizeof (struct coff_reloc);
if (size < 0) {
return list_rel;
}
rel = calloc (1, size + 1);
if (!rel) {
return list_rel;
}
if (bin->scn_hdrs[i].s_relptr > bin->size ||
bin->scn_hdrs[i].s_relptr + size > bin->size) {
return list_rel;
}
len = r_buf_read_at (bin->b, bin->scn_hdrs[i].s_relptr, (ut8*)rel, size);
if (len != size) {
free (rel);
return list_rel;
}
for (j = 0; j < bin->scn_hdrs[i].s_nreloc; j++) {
RBinSymbol *symbol = R_NEW0 (RBinSymbol);
if (!symbol) {
continue;
}
if (!_fill_bin_symbol (bin, rel[j].r_symndx, &symbol)) {
free (symbol);
continue;
}
reloc = R_NEW0 (RBinReloc);
if (!reloc) {
free (symbol);
continue;
}
reloc->type = rel[j].r_type; //XXX the type if different from what r2 expects
reloc->symbol = symbol;
reloc->paddr = bin->scn_hdrs[i].s_scnptr + rel[j].r_vaddr;
reloc->vaddr = reloc->paddr;
r_list_append (list_rel, reloc);
}
}
}
return list_rel;
}
static RBinInfo *info(RBinFile *arch) {