R_API void r_anal_xrefs_init (RAnal *anal) { DB = NULL; DB = sdb_new (NULL, 0); // TODO sdb_aadd (DB, "types", -1, "code"SDB_SS"data", 0); #if 0 //... r_anal_xrefs_get (anal, "code", 0); #endif }
R_API void r_anal_xrefs_init (RAnal *anal) { DB = NULL; DB = sdb_new (NULL, "xrefs", 0); // TODO sdb_array_set (DB, "types", -1, "code,data", 0); #if 0 //... r_anal_xrefs_get (anal, "code", 0); #endif }
R_API RList *r_anal_xref_get(RAnal *anal, ut64 addr) { return r_anal_xrefs_get (anal, addr); }
static bool objc_find_refs(RCore *core) { static const char *oldstr = NULL; RCoreObjc objc = {0}; const int objc2ClassSize = 0x28; const int objc2ClassInfoOffs = 0x20; const int objc2ClassMethSize = 0x18; const int objc2ClassBaseMethsOffs = 0x20; const int objc2ClassMethImpOffs = 0x10; objc.core = core; objc.word_size = (core->assembler->bits == 64)? 8: 4; RList *sections = r_bin_get_sections (core->bin); if (!sections) { return false; } RBinSection *s; RListIter *iter; r_list_foreach (sections, iter, s) { const char *name = s->name; if (strstr (name, "__objc_data")) { objc._data = s; } else if (strstr (name, "__objc_selrefs")) { objc._selrefs = s; } else if (strstr (name, "__objc_msgrefs")) { objc._msgrefs = s; } else if (strstr (name, "__objc_const")) { objc._const = s; } } if (!objc._const) { if (core->anal->verbose) { eprintf ("Could not find necessary objc_const section\n"); } return false; } if ((objc._selrefs || objc._msgrefs) && !(objc._data && objc._const)) { if (core->anal->verbose) { eprintf ("Could not find necessary Objective-C sections...\n"); } return false; } objc.db = sdb_new0 (); if (!objc_build_refs (&objc)) { return false; } oldstr = r_print_rowlog (core->print, "Parsing metadata in ObjC to find hidden xrefs"); r_print_rowlog_done (core->print, oldstr); int total = 0; ut64 off; for (off = 0; off < objc._data->vsize ; off += objc2ClassSize) { ut64 va = objc._data->vaddr + off; ut64 classRoVA = readQword (&objc, va + objc2ClassInfoOffs); if (isInvalid (classRoVA)) { continue; } ut64 classMethodsVA = readQword (&objc, classRoVA + objc2ClassBaseMethsOffs); if (isInvalid (classMethodsVA)) { continue; } int count = readDword (&objc, classMethodsVA + 4); classMethodsVA += 8; // advance to start of class methods array ut64 from = classMethodsVA; ut64 to = from + (objc2ClassMethSize * count); ut64 va2; for (va2 = from; va2 < to; va2 += objc2ClassMethSize) { bool isMsgRef = false; ut64 selRefVA = getRefPtr (&objc, va2, &isMsgRef); if (!selRefVA) { continue; } // # adjust pointer to beginning of message_ref struct to get xrefs if (isMsgRef) { selRefVA -= 8; } ut64 funcVA = readQword (&objc, va2 + objc2ClassMethImpOffs); RList *list = r_anal_xrefs_get (core->anal, selRefVA); RListIter *iter; RAnalRef *ref; r_list_foreach (list, iter, ref) { r_anal_xrefs_set (core->anal, ref->addr, funcVA, R_META_TYPE_CODE); total++; } } }