mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 15:10:53 +00:00
Initial implementation of extracting class info from symbols
This commit is contained in:
parent
1cf650aceb
commit
fb47d2ce74
210
libr/bin/bin.c
210
libr/bin/bin.c
@ -84,11 +84,42 @@ static RBinFile *r_bin_file_new_from_bytes(RBin *bin, const char *file,
|
||||
const char *xtrname, ut64 offset,
|
||||
bool steal_ptr);
|
||||
|
||||
static int getoffset(RBin *bin, int type, int idx);
|
||||
static const char *getname(RBin *bin, int type, int idx);
|
||||
static int r_bin_file_object_add(RBinFile *binfile, RBinObject *o);
|
||||
static void binobj_set_baddr(RBinObject *o, ut64 baddr);
|
||||
static ut64 binobj_a2b(RBinObject *o, ut64 addr);
|
||||
static int getoffset(RBin *bin, int type, int idx) {
|
||||
RBinFile *a = r_bin_cur (bin);
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (a);
|
||||
if (plugin && plugin->get_offset) {
|
||||
return plugin->get_offset (a, type, idx);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *getname(RBin *bin, int type, int idx) {
|
||||
RBinFile *a = r_bin_cur (bin);
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (a);
|
||||
if (plugin && plugin->get_name) {
|
||||
return plugin->get_name (a, type, idx);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static int r_bin_file_object_add(RBinFile *binfile, RBinObject *o) {
|
||||
if (!o) {
|
||||
return false;
|
||||
}
|
||||
r_list_append (binfile->objs, o);
|
||||
r_bin_file_set_cur_binfile_obj (binfile->rbin, binfile, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void binobj_set_baddr(RBinObject *o, ut64 baddr) {
|
||||
if (!o || baddr == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
o->baddr_shift = baddr - o->baddr;
|
||||
}
|
||||
|
||||
static ut64 binobj_a2b(RBinObject *o, ut64 addr) {
|
||||
return addr + (o? o->baddr_shift: 0);
|
||||
}
|
||||
|
||||
static void filterStrings (RBin *bin, RList *strings) {
|
||||
RBinString *ptr;
|
||||
@ -571,6 +602,72 @@ static void r_bin_object_free(void /*RBinObject*/ *o_) {
|
||||
R_FREE (o);
|
||||
}
|
||||
|
||||
static char *swiftField(const char *dn, const char *cn) {
|
||||
char *p = strstr (dn, ".getter_");
|
||||
if (!p) {
|
||||
p = strstr (dn, ".setter_");
|
||||
if (!p) {
|
||||
p = strstr (dn, ".method_");
|
||||
}
|
||||
}
|
||||
if (p) {
|
||||
char *q = strstr (dn, cn);
|
||||
if (q && q[strlen (cn)] == '.') {
|
||||
q = strdup (q + strlen (cn) + 1);
|
||||
char *r = strchr (q, '.');
|
||||
if (r) {
|
||||
*r = 0;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API RList *r_bin_classes_from_symbols (RBinFile *bf, RBinObject *o) {
|
||||
RBinSymbol *sym;
|
||||
RListIter *iter;
|
||||
RList *symbols = o->symbols;
|
||||
RList *classes = o->classes;
|
||||
if (!classes) {
|
||||
classes = r_list_newf ((RListFree)r_bin_class_free);
|
||||
}
|
||||
r_list_foreach (symbols, iter, sym) {
|
||||
if (sym->name[0] != '_') {
|
||||
continue;
|
||||
}
|
||||
const char *cn = sym->classname;
|
||||
if (cn) {
|
||||
RBinClass *c = r_bin_class_new (bf, sym->classname, NULL, 0);
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
// swift specific
|
||||
char *dn = sym->dname;
|
||||
char *fn = swiftField (dn, cn);
|
||||
if (fn) {
|
||||
// eprintf ("FIELD %s %s\n", cn, fn);
|
||||
RBinField *f = r_bin_field_new (sym->paddr, sym->vaddr, sym->size, fn, NULL, NULL);
|
||||
r_list_append (c->fields, f);
|
||||
free (fn);
|
||||
} else {
|
||||
char *mn = strstr (dn, "..");
|
||||
if (mn) {
|
||||
// eprintf ("META %s %s\n", sym->classname, mn);
|
||||
} else {
|
||||
char *mn = strstr (dn, cn);
|
||||
if (mn && mn[strlen(cn)] == '.') {
|
||||
mn += strlen (cn) + 1;
|
||||
// eprintf ("METHOD %s %s\n", sym->classname, mn);
|
||||
r_list_append (c->methods, sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
// XXX - change this to RBinObject instead of RBinFile
|
||||
// makes no sense to pass in a binfile and set the RBinObject
|
||||
// kinda a clunky functions
|
||||
@ -676,9 +773,14 @@ R_API int r_bin_object_set_items(RBinFile *binfile, RBinObject *o) {
|
||||
if (bin->filter_rules & R_BIN_REQ_CLASSES) {
|
||||
if (cp->classes) {
|
||||
o->classes = cp->classes (binfile);
|
||||
if (bin->filter) {
|
||||
r_bin_filter_classes (o->classes);
|
||||
if (r_bin_lang_swift (binfile)) {
|
||||
o->classes = r_bin_classes_from_symbols (binfile, o);
|
||||
}
|
||||
} else {
|
||||
o->classes = r_bin_classes_from_symbols (binfile, o);
|
||||
}
|
||||
if (bin->filter) {
|
||||
r_bin_filter_classes (o->classes);
|
||||
}
|
||||
}
|
||||
if (cp->lines) {
|
||||
@ -1038,17 +1140,19 @@ static void r_bin_file_free(void /*RBinFile*/ *bf_) {
|
||||
RBinFile *a = bf_;
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (a);
|
||||
|
||||
if (!a) return;
|
||||
if (!a) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Binary format objects are connected to the
|
||||
// RBinObject, so the plugin must destroy the
|
||||
// format data first
|
||||
if (plugin && plugin->destroy)
|
||||
if (plugin && plugin->destroy) {
|
||||
plugin->destroy (a);
|
||||
|
||||
if (a->curxtr && a->curxtr->destroy && a->xtr_obj)
|
||||
}
|
||||
if (a->curxtr && a->curxtr->destroy && a->xtr_obj) {
|
||||
a->curxtr->free_xtr ((void *)(a->xtr_obj));
|
||||
|
||||
}
|
||||
r_buf_free (a->buf);
|
||||
// TODO: unset related sdb namespaces
|
||||
if (a && a->sdb_addrinfo) {
|
||||
@ -1064,15 +1168,6 @@ static void r_bin_file_free(void /*RBinFile*/ *bf_) {
|
||||
free (a);
|
||||
}
|
||||
|
||||
static int r_bin_file_object_add(RBinFile *binfile, RBinObject *o) {
|
||||
if (!o) {
|
||||
return false;
|
||||
}
|
||||
r_list_append (binfile->objs, o);
|
||||
r_bin_file_set_cur_binfile_obj (binfile->rbin, binfile, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
static RBinFile *r_bin_file_create_append(RBin *bin, const char *file,
|
||||
const ut8 *bytes, ut64 sz,
|
||||
ut64 file_sz, int rawstr, int fd,
|
||||
@ -1284,7 +1379,6 @@ static RBinFile *r_bin_file_new(RBin *bin, const char *file, const ut8 *bytes,
|
||||
if (!res && steal_ptr) { // we own the ptr, free on error
|
||||
free((void*) bytes);
|
||||
}
|
||||
|
||||
binfile->rbin = bin;
|
||||
binfile->file = strdup (file);
|
||||
binfile->rawstr = rawstr;
|
||||
@ -1477,11 +1571,11 @@ R_API int r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo) {
|
||||
if (foo->init) {
|
||||
foo->init (bin->user);
|
||||
}
|
||||
|
||||
// avoid duplicates
|
||||
r_list_foreach (bin->binxtrs, it, xtr) {
|
||||
if (!strcmp (xtr->name, foo->name))
|
||||
if (!strcmp (xtr->name, foo->name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
r_list_append (bin->binxtrs, foo);
|
||||
return true;
|
||||
@ -1639,13 +1733,6 @@ R_API ut64 r_bin_get_laddr(RBin *bin) {
|
||||
return o? o->loadaddr: UT64_MAX;
|
||||
}
|
||||
|
||||
static void binobj_set_baddr(RBinObject *o, ut64 baddr) {
|
||||
if (!o || baddr == UT64_MAX) {
|
||||
return;
|
||||
}
|
||||
o->baddr_shift = baddr - o->baddr;
|
||||
}
|
||||
|
||||
R_API void r_bin_set_baddr(RBin *bin, ut64 baddr) {
|
||||
RBinObject *o = r_bin_cur_object (bin);
|
||||
binobj_set_baddr (o, baddr);
|
||||
@ -1798,7 +1885,6 @@ R_API int r_bin_is_string(RBin *bin, ut64 va) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//callee must not free the symbol
|
||||
R_API RBinSymbol *r_bin_get_symbol_at_vaddr(RBin *bin, ut64 addr) {
|
||||
//use skiplist here
|
||||
@ -1813,7 +1899,6 @@ R_API RBinSymbol *r_bin_get_symbol_at_vaddr(RBin *bin, ut64 addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//callee must not free the symbol
|
||||
R_API RBinSymbol *r_bin_get_symbol_at_paddr(RBin *bin, ut64 addr) {
|
||||
//use skiplist here
|
||||
@ -2100,9 +2185,9 @@ R_API int r_bin_select_by_ids(RBin *bin, ut32 binfile_id, ut32 binobj_id) {
|
||||
binfile = r_bin_file_find_by_id (bin, binfile_id);
|
||||
obj = binfile? r_bin_file_object_find_by_id (binfile, binobj_id): NULL;
|
||||
}
|
||||
|
||||
if (!binfile || !obj) return false;
|
||||
|
||||
if (!binfile || !obj) {
|
||||
return false;
|
||||
}
|
||||
return obj && binfile && r_bin_file_set_cur_binfile_obj (bin, binfile, obj);
|
||||
}
|
||||
|
||||
@ -2137,8 +2222,8 @@ static void list_xtr_archs(RBin *bin, int mode) {
|
||||
bits = xtr_data->metadata->bits;
|
||||
switch (mode) {
|
||||
case 'q':
|
||||
bin->cb_printf ("%s\n", arch);
|
||||
break;
|
||||
bin->cb_printf ("%s\n", arch);
|
||||
break;
|
||||
case 'j':
|
||||
bin->cb_printf (
|
||||
"%s{\"arch\":\"%s\",\"bits\":%d,"
|
||||
@ -2279,24 +2364,6 @@ R_API void r_bin_set_user_ptr(RBin *bin, void *user) {
|
||||
bin->user = user;
|
||||
}
|
||||
|
||||
static int getoffset(RBin *bin, int type, int idx) {
|
||||
RBinFile *a = r_bin_cur (bin);
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (a);
|
||||
if (plugin && plugin->get_offset) {
|
||||
return plugin->get_offset (a, type, idx);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *getname(RBin *bin, int type, int idx) {
|
||||
RBinFile *a = r_bin_cur (bin);
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (a);
|
||||
if (plugin && plugin->get_name) {
|
||||
return plugin->get_name (a, type, idx);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API void r_bin_bind(RBin *bin, RBinBind *b) {
|
||||
if (b) {
|
||||
b->bin = bin;
|
||||
@ -2321,8 +2388,7 @@ R_API RBuffer *r_bin_create(RBin *bin, const ut8 *code, int codelen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API RBuffer *r_bin_package(RBin *bin, const char *type, const char *file,
|
||||
RList *files) {
|
||||
R_API RBuffer *r_bin_package(RBin *bin, const char *type, const char *file, RList *files) {
|
||||
if (!strcmp (type, "zip")) {
|
||||
#if 0
|
||||
int zep = 0;
|
||||
@ -2418,6 +2484,14 @@ R_API RList * /*<RBinClass>*/ r_bin_get_classes(RBin *bin) {
|
||||
return o? o->classes: NULL;
|
||||
}
|
||||
|
||||
R_API void r_bin_class_free(RBinClass *c) {
|
||||
free (c->name);
|
||||
free (c->super);
|
||||
r_list_free (c->methods);
|
||||
r_list_free (c->fields);
|
||||
free (c);
|
||||
}
|
||||
|
||||
R_API RBinClass *r_bin_class_new(RBinFile *binfile, const char *name,
|
||||
const char *super, int view) {
|
||||
RBinObject *o = binfile? binfile->o: NULL;
|
||||
@ -2534,13 +2608,6 @@ R_API ut64 r_bin_get_vaddr(RBin *bin, ut64 paddr, ut64 vaddr) {
|
||||
return r_binfile_get_vaddr (bin->cur, paddr, vaddr);
|
||||
}
|
||||
|
||||
static ut64 binobj_a2b(RBinObject *o, ut64 addr) {
|
||||
if (!o) {
|
||||
return addr;
|
||||
}
|
||||
return o->baddr_shift + addr;
|
||||
}
|
||||
|
||||
R_API ut64 r_bin_a2b(RBin *bin, ut64 addr) {
|
||||
RBinObject *o = r_bin_cur_object (bin);
|
||||
return o? o->baddr_shift + addr: addr;
|
||||
@ -2548,10 +2615,7 @@ R_API ut64 r_bin_a2b(RBin *bin, ut64 addr) {
|
||||
|
||||
R_API ut64 r_bin_get_size(RBin *bin) {
|
||||
RBinObject *o = r_bin_cur_object (bin);
|
||||
if (o) {
|
||||
return o->size;
|
||||
}
|
||||
return UT64_MAX;
|
||||
return o? o->size: UT64_MAX;
|
||||
}
|
||||
|
||||
R_API int r_bin_file_delete_all(RBin *bin) {
|
||||
@ -2635,8 +2699,7 @@ R_API int r_bin_file_set_cur_by_fd(RBin *bin, ut32 bin_fd) {
|
||||
return r_bin_file_set_cur_binfile (bin, bf);
|
||||
}
|
||||
|
||||
R_API int r_bin_file_set_cur_binfile_obj(RBin *bin, RBinFile *bf,
|
||||
RBinObject *obj) {
|
||||
R_API int r_bin_file_set_cur_binfile_obj(RBin *bin, RBinFile *bf, RBinObject *obj) {
|
||||
RBinPlugin *plugin = NULL;
|
||||
if (!bin || !bf || !obj) {
|
||||
return false;
|
||||
@ -2654,10 +2717,7 @@ R_API int r_bin_file_set_cur_binfile_obj(RBin *bin, RBinFile *bf,
|
||||
|
||||
R_API int r_bin_file_set_cur_binfile(RBin *bin, RBinFile *bf) {
|
||||
RBinObject *obj = bf? bf->o: NULL;
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
return r_bin_file_set_cur_binfile_obj (bin, bf, obj);
|
||||
return obj? r_bin_file_set_cur_binfile_obj (bin, bf, obj): false;
|
||||
}
|
||||
|
||||
R_API int r_bin_file_set_cur_by_name(RBin *bin, const char *name) {
|
||||
|
@ -89,8 +89,6 @@ static void get_method_list_t(mach0_ut p, RBinFile *arch, char *class_name, RBin
|
||||
static void get_protocol_list_t(mach0_ut p, RBinFile *arch, RBinClass *klass);
|
||||
static void get_class_ro_t(mach0_ut p, RBinFile *arch, ut32 *is_meta_class, RBinClass *klass);
|
||||
static void get_class_t(mach0_ut p, RBinFile *arch, RBinClass *klass, bool dupe);
|
||||
static void __r_bin_class_free(RBinClass *p);
|
||||
|
||||
static bool is_thumb(RBinFile *arch) {
|
||||
struct MACH0_(obj_t) *bin = (struct MACH0_(obj_t) *)arch->o->bin_obj;
|
||||
if (bin->hdr.cputype == 12) {
|
||||
@ -981,29 +979,6 @@ static void get_class_t(mach0_ut p, RBinFile *arch, RBinClass *klass, bool dupe)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void __r_bin_class_free(RBinClass *p) {
|
||||
RBinSymbol *symbol = NULL;
|
||||
RBinField *field = NULL;
|
||||
RListIter *iter = NULL;
|
||||
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
r_list_foreach (p->methods, iter, symbol) {
|
||||
free (symbol->name);
|
||||
free (symbol->classname);
|
||||
R_FREE (symbol);
|
||||
}
|
||||
r_list_foreach (p->fields, iter, field) {
|
||||
free (field->name);
|
||||
R_FREE (field);
|
||||
}
|
||||
r_list_free (p->methods);
|
||||
r_list_free (p->fields);
|
||||
r_bin_class_free (p);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static RList *parse_swift_classes(RBinFile *bf) {
|
||||
bool is_swift = false;
|
||||
@ -1086,7 +1061,7 @@ RList *MACH0_(parse_classes)(RBinFile *arch) {
|
||||
}
|
||||
// end of seaching of section with name __objc_classlist
|
||||
|
||||
if (!ret && !(ret = r_list_newf ((RListFree)__r_bin_class_free))) {
|
||||
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;
|
||||
@ -1142,6 +1117,7 @@ RList *MACH0_(parse_classes)(RBinFile *arch) {
|
||||
get_classes_error:
|
||||
r_list_free (sctns);
|
||||
r_list_free (ret);
|
||||
__r_bin_class_free (klass);
|
||||
r_bin_class_free (klass);
|
||||
//__r_bin_class_free (klass);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -211,6 +211,25 @@ static RList* symbols(RBinFile *arch) {
|
||||
break;
|
||||
}
|
||||
ptr->name = strdup ((char*)symbols[i].name);
|
||||
if (ptr->name[0] == '_' && strncmp (ptr->name, "imp.", 4)) {
|
||||
char *dn = r_bin_demangle (arch, ptr->name, ptr->name, ptr->vaddr);
|
||||
if (dn) {
|
||||
ptr->dname = dn;
|
||||
char *p = strchr (dn, '.');
|
||||
if (p) {
|
||||
if (IS_UPPER (ptr->name[0])) {
|
||||
ptr->classname = strdup (ptr->name);
|
||||
ptr->classname[p - ptr->name] = 0;
|
||||
} else if (IS_UPPER (p[1])) {
|
||||
ptr->classname = strdup (p + 1);
|
||||
p = strchr (ptr->classname, '.');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr->forwarder = r_str_const ("NONE");
|
||||
ptr->bind = r_str_const ((symbols[i].type == R_BIN_MACH0_SYMBOL_TYPE_LOCAL)?
|
||||
"LOCAL": "GLOBAL");
|
||||
|
@ -2327,7 +2327,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
}
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
r_cons_printf ("0x%08"PFMT64x" method %d %s\n",
|
||||
sym->vaddr, m, sym->name);
|
||||
sym->vaddr, m, sym->dname? sym->dname: sym->name);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
@ -382,6 +382,7 @@ typedef struct r_bin_class_t {
|
||||
typedef struct r_bin_symbol_t {
|
||||
/* heap-allocated */
|
||||
char *name;
|
||||
char *dname;
|
||||
char *classname;
|
||||
/* const-unique-strings */
|
||||
const char *forwarder;
|
||||
@ -485,8 +486,6 @@ typedef struct r_bin_bind_t {
|
||||
|
||||
#ifdef R_API
|
||||
|
||||
#define r_bin_class_free(x) { free(x->name);free(x->super);free (x); }
|
||||
|
||||
/* bin.c */
|
||||
R_API void r_bin_load_filter(RBin *bin, ut64 rules);
|
||||
R_API int r_bin_load(RBin *bin, const char *file, ut64 baseaddr, ut64 loadaddr, int xtr_idx, int fd, int rawstr);
|
||||
@ -554,6 +553,7 @@ R_API RList* /*<RBinClass>*/r_bin_get_classes(RBin *bin);
|
||||
|
||||
R_API RBinClass *r_bin_class_get (RBinFile *binfile, const char *name);
|
||||
R_API RBinClass *r_bin_class_new (RBinFile *binfile, const char *name, const char *super, int view);
|
||||
R_API void r_bin_class_free(RBinClass *c);
|
||||
R_API RBinSymbol *r_bin_class_add_method (RBinFile *binfile, const char *classname, const char *name, int nargs);
|
||||
R_API void r_bin_class_add_field (RBinFile *binfile, const char *classname, const char *name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user