/* radare - LGPL - Copyright 2010-2013 - nibble, pancake */ #include #include #include R_API RAnalRef *r_anal_ref_new() { RAnalRef *ref = R_NEW (RAnalRef); if (ref) { ref->addr = -1; ref->at = -1; ref->type = R_ANAL_REF_TYPE_CODE; } return ref; } R_API RList *r_anal_ref_list_new() { RList *list = r_list_new (); list->free = &r_anal_ref_free; return list; } R_API void r_anal_ref_free(void *ref) { free (ref); } R_API int r_anal_ref_add(RAnal *anal, ut64 addr, ut64 at, int type) { RAnalRef *ref = NULL, *refi; RListIter *iter; int append = 0; r_list_foreach (anal->refs, iter, refi) if (at == refi->at) { ref = refi; break; } if (ref == NULL) { if (!(ref = r_anal_ref_new ())) return R_FALSE; append = 1; } ref->addr = addr; ref->at = at; ref->type = type; if (append) r_list_append (anal->refs, ref); return R_TRUE; } R_API int r_anal_ref_del(RAnal *anal, ut64 at) { RAnalRef *refi; RListIter *iter, *iter_tmp; if (at == 0) { r_list_free (anal->refs); if (!(anal->refs = r_anal_ref_list_new ())) return R_FALSE; } else { r_list_foreach_safe (anal->refs, iter, iter_tmp, refi) { if (at == refi->at) r_list_delete (anal->refs, iter); } } return R_TRUE; } // XXX: MAJOR SLOWDOWN PLZ FIX R_API RList *r_anal_xref_get(RAnal *anal, ut64 addr) { RAnalFunction *fcni; RAnalRef *refi, *ref, *refr; RListIter *iter, *iter2, *iter3; RList *ret; return r_anal_xrefs_get (anal, addr); return NULL; // fuck yeah optimization! #if 0 for (list = sdb_list_begin (DB); list; list = sdb_list_next (list)) { char *str = astring(); eprintf ("--> %s\n", str); } char *list = sdb_list_begin(DB) while (list) { list = sdb_list_next (list); } $ sdb xrefs ()types=code,data ()data.0x1200=0x1000,0x1030,0x1090 ()code.0x3020=0x2010,0x2042 int clen, dlen; const char **coderefs, **datarefs; coderefs = r_anal_xrefs_get (anal, "code", &clen); datarefs = r_anal_xrefs_get (anal, "data", &dlen); if (!coderefs && !datarefs) return NULL; xrefs[0x80480] = { type: "data", from: " RAnalFudr_anal_fcn_get_at (anal, addr); #endif if (!(ret = r_anal_ref_list_new ())) return NULL; // XXX: this is just a hack that makes analysis/disasm much slower but // work as expected. We need to redesign the whole analysis engine :) // - find real reverse xrefs by deep walk // - addr = our target destination r_list_foreach (anal->fcns, iter, fcni) { r_list_foreach (fcni->refs, iter2, refi) { if (refi->addr == addr) { int gonext = 0; r_list_foreach (ret, iter3, refr) { if (refr->addr == refi->at) // same sauce, so we can skip gonext = 1; } if (gonext) continue; // wtf copying xrefs for new lists .. tahts insanely slow if (!(ref = r_anal_ref_new ())) { r_list_destroy (ret); return NULL; } // NOTE: swapped hacky valuez ref->addr = refi->at; ref->at = refi->addr; ref->type = refi->type; r_list_append (ret, ref); } } } if (r_list_length (ret)>0) return ret; r_list_foreach (anal->fcns, iter, fcni) { if (addr >= fcni->addr && addr < fcni->addr+fcni->size) { r_list_foreach (fcni->xrefs, iter2, refi) { if (refi->at == addr) { if (!(ref = r_anal_ref_new ())) { r_list_destroy (ret); return NULL; } ref->addr = refi->addr; ref->at = refi->at; ref->type= refi->type; r_list_append (ret, ref); } } break; // may break on corner cases } } r_list_foreach (anal->refs, iter2, refi) if (refi->addr == addr) { if (!(ref = r_anal_ref_new ())) { r_list_destroy (ret); return NULL; } ref->addr = refi->at; ref->at = refi->addr; ref->type= refi->type; r_list_append (ret, ref); } return ret; }