* Add support for parsing relocs to r_bin
* Add flag -R to rabin2 to list relocs * Implement reloc resolution in r_bin_elf for 32 & 64 bits
This commit is contained in:
parent
2d2131607c
commit
5567da9538
4
TODO
4
TODO
|
@ -41,10 +41,10 @@ Build system:
|
|||
|
||||
TODO nibble
|
||||
-----------
|
||||
* r_bin->relocs // RList of relocations
|
||||
* use r_anal_value everywhere in r_anal
|
||||
* make x86_x86im the default backend for x86 analysis
|
||||
* implement analysis for more instructions in x86_x86im
|
||||
* use r_anal_value everywhere in r_anal
|
||||
* r_bin->relocs // RList of relocations
|
||||
* big-ssl.c big-gmp.c ...
|
||||
* native fat bins support (push uncommited changes)
|
||||
* diff code analysis
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define ACTION_SRCLINE 0x0400
|
||||
#define ACTION_MAIN 0x0800
|
||||
#define ACTION_EXTRACT 0x1000
|
||||
#define ACTION_RELOCS 0x2000
|
||||
|
||||
static struct r_lib_t *l;
|
||||
static struct r_bin_t *bin = NULL;
|
||||
|
@ -53,6 +54,7 @@ static int rabin_show_help() {
|
|||
" -I Binary info\n"
|
||||
" -H Header fields\n"
|
||||
" -l Linked libraries\n"
|
||||
" -R Relocations\n"
|
||||
" -O [str] Write/Extract operations (str=help for help)\n"
|
||||
" -o [file] Output file for write operations (a.out by default)\n"
|
||||
" -f [format] Override file format autodetection\n"
|
||||
|
@ -144,6 +146,33 @@ static int rabin_show_libs() {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int rabin_show_relocs() {
|
||||
RList *relocs;
|
||||
RListIter *iter;
|
||||
RBinReloc *reloc;
|
||||
int i = 0;
|
||||
|
||||
ut64 baddr = gbaddr?gbaddr:r_bin_get_baddr (bin);
|
||||
|
||||
if ((relocs = r_bin_get_relocs (bin)) == NULL)
|
||||
return R_FALSE;
|
||||
|
||||
if (rad) printf ("fs relocs\n");
|
||||
else printf ("[Relocations]\n");
|
||||
|
||||
r_list_foreach (relocs, iter, reloc) {
|
||||
if (rad) {
|
||||
printf ("f reloc.%s @ 0x%08"PFMT64x"\n", reloc->name, va?baddr+reloc->rva:reloc->offset);
|
||||
} else printf ("sym=%02i address=0x%08"PFMT64x" offset=0x%08"PFMT64x" type=0x%08x %s\n",
|
||||
reloc->sym, baddr+reloc->rva, reloc->offset, reloc->type, reloc->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!rad) printf ("\n%i relocations\n", i);
|
||||
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int rabin_show_imports() {
|
||||
RList *imports;
|
||||
RListIter *iter;
|
||||
|
@ -573,7 +602,7 @@ int main(int argc, char **argv)
|
|||
r_lib_opendir (l, LIBDIR"/radare2/");
|
||||
}
|
||||
|
||||
while ((c = getopt (argc, argv, "b:Mm:n:@:VisSzIHelwO:o:f:rvLhx")) != -1) {
|
||||
while ((c = getopt (argc, argv, "b:Mm:n:@:VisSzIHelRwO:o:f:rvLhx")) != -1) {
|
||||
switch(c) {
|
||||
case 'm':
|
||||
at = r_num_math (NULL, optarg);
|
||||
|
@ -605,6 +634,9 @@ int main(int argc, char **argv)
|
|||
case 'l':
|
||||
action |= ACTION_LIBS;
|
||||
break;
|
||||
case 'R':
|
||||
action |= ACTION_RELOCS;
|
||||
break;
|
||||
case 'x':
|
||||
action |= ACTION_EXTRACT;
|
||||
break;
|
||||
|
@ -679,6 +711,8 @@ int main(int argc, char **argv)
|
|||
rabin_show_fields();
|
||||
if (action&ACTION_LIBS)
|
||||
rabin_show_libs();
|
||||
if (action&ACTION_RELOCS)
|
||||
rabin_show_relocs();
|
||||
if (action&ACTION_SRCLINE)
|
||||
rabin_show_srcline(at);
|
||||
if (action&ACTION_EXTRACT)
|
||||
|
|
|
@ -91,6 +91,8 @@ static void r_bin_init_items(RBin *bin) {
|
|||
bin->info = bin->cur->info (bin);
|
||||
if (bin->cur->libs)
|
||||
bin->libs = bin->cur->libs (bin);
|
||||
if (bin->cur->relocs)
|
||||
bin->relocs = bin->cur->relocs (bin);
|
||||
if (bin->cur->sections)
|
||||
bin->sections = bin->cur->sections (bin);
|
||||
if (bin->cur->strings)
|
||||
|
@ -112,6 +114,8 @@ static void r_bin_free_items(RBin *bin) {
|
|||
free (bin->info);
|
||||
if (bin->libs)
|
||||
r_list_free (bin->libs);
|
||||
if (bin->relocs)
|
||||
r_list_free (bin->relocs);
|
||||
if (bin->sections)
|
||||
r_list_free (bin->sections);
|
||||
if (bin->strings)
|
||||
|
@ -207,6 +211,10 @@ R_API RList* r_bin_get_libs(RBin *bin) {
|
|||
return bin->libs;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_relocs(RBin *bin) {
|
||||
return bin->relocs;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_sections(RBin *bin) {
|
||||
return bin->sections;
|
||||
}
|
||||
|
|
|
@ -486,6 +486,86 @@ char *Elf_(r_bin_elf_get_rpath)(struct Elf_(r_bin_elf_obj_t) *bin) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct r_bin_elf_reloc_t* Elf_(r_bin_elf_get_relocs)(struct Elf_(r_bin_elf_obj_t) *bin) {
|
||||
struct r_bin_elf_reloc_t *ret = NULL;
|
||||
Elf_(Shdr) *strtab_section;
|
||||
Elf_(Sym) *sym;
|
||||
Elf_(Rel) *rel;
|
||||
char *strtab;
|
||||
int i, j, nrel, tsize, len, nsym;
|
||||
|
||||
if (!bin->shdr || !bin->strtab)
|
||||
return NULL;
|
||||
for (i = 0, nsym = 0; i < bin->ehdr.e_shnum; i++)
|
||||
if (bin->shdr[i].sh_type == (bin->ehdr.e_type == ET_REL ? SHT_SYMTAB : SHT_DYNSYM)) {
|
||||
strtab_section = &bin->shdr[bin->shdr[i].sh_link];
|
||||
if ((strtab = (char *)malloc (8+strtab_section->sh_size)) == NULL) {
|
||||
perror ("malloc (syms strtab)");
|
||||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, strtab_section->sh_offset, (ut8*)strtab, strtab_section->sh_size) == -1) {
|
||||
eprintf ("Error: read (syms strtab)\n");
|
||||
return NULL;
|
||||
}
|
||||
if ((sym = (Elf_(Sym) *)malloc (1+bin->shdr[i].sh_size)) == NULL) {
|
||||
perror ("malloc (syms)");
|
||||
return NULL;
|
||||
}
|
||||
nsym = (int)(bin->shdr[i].sh_size/sizeof (Elf_(Sym)));
|
||||
if (r_buf_fread_at (bin->b, bin->shdr[i].sh_offset, (ut8*)sym,
|
||||
#if R_BIN_ELF64
|
||||
bin->endian?"I2cS2L":"i2cs2l",
|
||||
#else
|
||||
bin->endian?"3I2cS":"3i2cs",
|
||||
#endif
|
||||
nsym) == -1) {
|
||||
eprintf ("Error: read (sym)\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < bin->ehdr.e_shnum; i++) {
|
||||
if (!strcmp (&bin->strtab[bin->shdr[i].sh_name], ".rel.plt"))
|
||||
tsize = sizeof (Elf_(Rel));
|
||||
else if (!strcmp (&bin->strtab[bin->shdr[i].sh_name], ".rela.plt"))
|
||||
tsize = sizeof (Elf_(Rela));
|
||||
else continue;
|
||||
if ((rel = (Elf_(Rel) *)malloc ((int)(bin->shdr[i].sh_size / tsize) * sizeof (Elf_(Rel)))) == NULL) {
|
||||
perror ("malloc (rel)");
|
||||
return NULL;
|
||||
}
|
||||
for (j = nrel = 0; j < bin->shdr[i].sh_size; j += tsize, nrel++) {
|
||||
len = r_buf_fread_at (bin->b, bin->shdr[i].sh_offset + j, (ut8*)&rel[nrel],
|
||||
#if R_BIN_ELF64
|
||||
bin->endian?"2L":"2l",
|
||||
#else
|
||||
bin->endian?"2I":"2i",
|
||||
#endif
|
||||
1);
|
||||
if (len == -1) {
|
||||
eprintf ("Error: read (rel)\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ((ret = (struct r_bin_elf_reloc_t *)malloc (nrel * sizeof (struct r_bin_elf_reloc_t))) == NULL) {
|
||||
perror ("malloc (reloc)");
|
||||
return NULL;
|
||||
}
|
||||
for (j = 0; j < nrel; j++) {
|
||||
if (j < nsym) {
|
||||
len = __strnlen (&strtab[sym[ELF_R_SYM (rel[j].r_info)].st_name], ELF_STRING_LENGTH-1);
|
||||
memcpy (ret[j].name, &strtab[sym[ELF_R_SYM (rel[j].r_info)].st_name], len);
|
||||
} else strncpy (ret[j].name, "unknown", ELF_STRING_LENGTH);
|
||||
ret[j].sym = ELF_R_SYM (rel[j].r_info);
|
||||
ret[j].type = ELF_R_TYPE (rel[j].r_info);
|
||||
ret[j].offset = rel[j].r_offset - bin->baddr;
|
||||
ret[j].last = 0;
|
||||
}
|
||||
ret[j].last = 1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct r_bin_elf_lib_t* Elf_(r_bin_elf_get_libs)(struct Elf_(r_bin_elf_obj_t) *bin) {
|
||||
struct r_bin_elf_lib_t *ret = NULL;
|
||||
Elf_(Dyn) *dyn = NULL;
|
||||
|
@ -597,7 +677,7 @@ struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj
|
|||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, strtab_section->sh_offset, (ut8*)strtab, strtab_section->sh_size) == -1) {
|
||||
eprintf ("Error: read (magic)\n");
|
||||
eprintf ("Error: read (syms strtab)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -613,7 +693,7 @@ struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj
|
|||
bin->endian?"3I2cS":"3i2cs",
|
||||
#endif
|
||||
nsym) == -1) {
|
||||
eprintf ("Error: read (ehdr)\n");
|
||||
eprintf ("Error: read (sym)\n");
|
||||
return NULL;
|
||||
}
|
||||
for (j = k = ret_ctr = 0; j < bin->shdr[i].sh_size; j += sizeof (Elf_(Sym)), k++) {
|
||||
|
@ -725,6 +805,7 @@ struct Elf_(r_bin_elf_obj_t)* Elf_(r_bin_elf_new)(const char* file) {
|
|||
|
||||
if (!(bin = malloc (sizeof (struct Elf_(r_bin_elf_obj_t)))))
|
||||
return NULL;
|
||||
memset (bin, 0, sizeof (struct Elf_(r_bin_elf_obj_t)));
|
||||
bin->file = file;
|
||||
if (!(buf = (ut8*)r_file_slurp (file, &bin->size)))
|
||||
return Elf_(r_bin_elf_free) (bin);
|
||||
|
|
|
@ -34,6 +34,14 @@ typedef struct r_bin_elf_symbol_t {
|
|||
int last;
|
||||
} RBinElfSymbol;
|
||||
|
||||
typedef struct r_bin_elf_reloc_t {
|
||||
int sym;
|
||||
int type;
|
||||
ut64 offset;
|
||||
int last;
|
||||
char name[ELF_STRING_LENGTH];
|
||||
} RBinElfReloc;
|
||||
|
||||
typedef struct r_bin_elf_field_t {
|
||||
ut64 offset;
|
||||
char name[ELF_STRING_LENGTH];
|
||||
|
@ -79,6 +87,7 @@ char* Elf_(r_bin_elf_get_elf_class)(struct Elf_(r_bin_elf_obj_t) *bin);
|
|||
int Elf_(r_bin_elf_get_bits)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
char* Elf_(r_bin_elf_get_osabi_name)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
int Elf_(r_bin_elf_is_big_endian)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
struct r_bin_elf_reloc_t* Elf_(r_bin_elf_get_relocs)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
struct r_bin_elf_lib_t* Elf_(r_bin_elf_get_libs)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
struct r_bin_elf_section_t* Elf_(r_bin_elf_get_sections)(struct Elf_(r_bin_elf_obj_t) *bin);
|
||||
struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj_t) *bin, int type);
|
||||
|
|
|
@ -421,6 +421,7 @@ struct r_bin_java_obj_t* r_bin_java_new(const char* file) {
|
|||
|
||||
if (!(bin = malloc(sizeof(struct r_bin_java_obj_t))))
|
||||
return NULL;
|
||||
memset (bin, 0, sizeof (struct r_bin_java_obj_t));
|
||||
bin->file = file;
|
||||
if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
|
||||
return r_bin_java_free(bin);
|
||||
|
|
|
@ -745,6 +745,7 @@ struct PE_(r_bin_pe_obj_t)* PE_(r_bin_pe_new)(const char* file)
|
|||
|
||||
if (!(bin = malloc(sizeof(struct PE_(r_bin_pe_obj_t)))))
|
||||
return NULL;
|
||||
memset (bin, 0, sizeof (struct PE_(r_bin_pe_obj_t)));
|
||||
bin->file = file;
|
||||
if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
|
||||
return PE_(r_bin_pe_free)(bin);
|
||||
|
|
|
@ -46,6 +46,7 @@ struct r_bin_plugin_t r_bin_plugin_dummy = {
|
|||
.info = NULL,
|
||||
.fields = NULL,
|
||||
.libs = NULL,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -155,6 +155,31 @@ static RList* libs(RBin *bin) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static RList* relocs(RBin *bin) {
|
||||
RList *ret = NULL;
|
||||
RBinReloc *ptr = NULL;
|
||||
struct r_bin_elf_reloc_t *relocs = NULL;
|
||||
int i;
|
||||
|
||||
if (!(ret = r_list_new ()))
|
||||
return NULL;
|
||||
ret->free = free;
|
||||
if (!(relocs = Elf_(r_bin_elf_get_relocs) (bin->bin_obj)))
|
||||
return ret;
|
||||
for (i = 0; !relocs[i].last; i++) {
|
||||
if (!(ptr = R_NEW (RBinReloc)))
|
||||
break;
|
||||
strncpy (ptr->name, relocs[i].name, R_BIN_SIZEOF_STRINGS);
|
||||
ptr->rva = relocs[i].offset;
|
||||
ptr->offset = relocs[i].offset;
|
||||
ptr->type = relocs[i].type;
|
||||
ptr->sym = relocs[i].sym;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
free (relocs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RBinInfo* info(RBin *bin) {
|
||||
RBinInfo *ret = NULL;
|
||||
char *str;
|
||||
|
@ -265,6 +290,7 @@ struct r_bin_plugin_t r_bin_plugin_elf = {
|
|||
.info = &info,
|
||||
.fields = &fields,
|
||||
.libs = &libs,
|
||||
.relocs = &relocs,
|
||||
.meta = &r_bin_meta_elf,
|
||||
.write = &r_bin_write_elf,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ struct r_bin_plugin_t r_bin_plugin_elf64 = {
|
|||
.info = &info,
|
||||
.fields = &fields,
|
||||
.libs = &libs,
|
||||
.relocs = &relocs,
|
||||
.meta = &r_bin_meta_elf64,
|
||||
.write = &r_bin_write_elf64,
|
||||
};
|
||||
|
|
|
@ -65,6 +65,7 @@ struct r_bin_plugin_t r_bin_plugin_fatmach0 = {
|
|||
.info = NULL,
|
||||
.fields = NULL,
|
||||
.libs = NULL,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -154,6 +154,7 @@ struct r_bin_plugin_t r_bin_plugin_java = {
|
|||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = NULL,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -217,6 +217,7 @@ struct r_bin_plugin_t r_bin_plugin_mach0 = {
|
|||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = &libs,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -35,6 +35,7 @@ struct r_bin_plugin_t r_bin_plugin_mach064 = {
|
|||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = &libs,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -243,6 +243,7 @@ struct r_bin_plugin_t r_bin_plugin_pe = {
|
|||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = &libs,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ struct r_bin_plugin_t r_bin_plugin_pe64 = {
|
|||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = &libs,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef struct r_bin_t {
|
|||
RList* strings;
|
||||
RList* fields;
|
||||
RList* libs;
|
||||
RList* relocs;
|
||||
RBuffer *buf;
|
||||
void *user;
|
||||
struct r_bin_plugin_t *cur;
|
||||
|
@ -60,6 +61,7 @@ typedef struct r_bin_plugin_t {
|
|||
struct r_bin_info_t* (*info)(RBin *bin);
|
||||
RList* (*fields)(RBin *bin);
|
||||
RList* (*libs)(RBin *bin);
|
||||
RList* (*relocs)(RBin *bin);
|
||||
struct r_bin_meta_t *meta;
|
||||
struct r_bin_write_t *write;
|
||||
struct list_head list;
|
||||
|
@ -107,6 +109,14 @@ typedef struct r_bin_import_t {
|
|||
ut64 hint;
|
||||
} RBinImport;
|
||||
|
||||
typedef struct r_bin_reloc_t {
|
||||
char name[R_BIN_SIZEOF_STRINGS];
|
||||
ut64 rva;
|
||||
ut64 offset;
|
||||
int sym;
|
||||
int type;
|
||||
} RBinReloc;
|
||||
|
||||
typedef struct r_bin_string_t {
|
||||
char string[R_BIN_SIZEOF_STRINGS];
|
||||
ut64 rva;
|
||||
|
@ -160,6 +170,7 @@ R_API RList* r_bin_get_fields(RBin *bin);
|
|||
R_API RList* r_bin_get_imports(RBin *bin);
|
||||
R_API RBinInfo* r_bin_get_info(RBin *bin);
|
||||
R_API RList* r_bin_get_libs(RBin *bin);
|
||||
R_API RList* r_bin_get_relocs(RBin *bin);
|
||||
R_API RList* r_bin_get_sections(RBin *bin);
|
||||
R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va);
|
||||
R_API RList* r_bin_get_strings(RBin *bin);
|
||||
|
|
Loading…
Reference in New Issue