static bool objc_build_refs(RCoreObjc *objc) { ut64 off; ut8 *buf = calloc (1, objc->_const->vsize); if (!buf) { return false; } (void)r_io_read_at (objc->core->io, objc->_const->vaddr, buf, objc->_const->vsize); for (off = 0; off < objc->_const->vsize; off += objc->word_size) { ut64 va = objc->_const->vaddr + off; ut64 xrefs_to = r_read_le64 (buf + off); if (!xrefs_to) { continue; } sdb_array_add_num (objc->db, addr_key (va), xrefs_to, 0); } free (buf); buf = calloc (1, objc->_selrefs->vsize); if (!buf) { return false; } r_io_read_at (objc->core->io, objc->_selrefs->vaddr, buf, objc->_selrefs->vsize); for (off = 0; off < objc->_selrefs->vsize; off += objc->word_size) { ut64 va = objc->_selrefs->vaddr + off; ut64 xrefs_to = r_read_le64 (buf + off); if (!xrefs_to) { continue; } sdb_array_add_num (objc->db, addr_key (xrefs_to), va, 0); } free (buf); return true; }
R_API RList *r_anal_xrefs_set (RAnal *anal, const char *type, ut64 from, ut64 to) { char key[32]; snprintf (key, sizeof (key), "ref.%s.0x%"PFMT64x, type, from); sdb_array_add_num (DB, key, -1, to, 0); snprintf (key, sizeof (key), "xref.%s.0x%"PFMT64x, type, to); sdb_array_add_num (DB, key, -1, from, 0); // (-1)funfor.%d=%d return NULL; }
// avr R_API int r_anal_var_access (RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) { const char *var_global; const char *xs_type_str = xs_type? "writes": "reads"; // TODO: kind is not used if (scope>0) { // local char *var_local = sdb_fmt (0, "var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, xs_type_str); return sdb_array_add_num (DB, var_local, xs_addr, 0); } // global sdb_add (DB, sdb_fmt (0,"var.0x%"PFMT64x, var_addr), "a,", 0); var_global = sdb_fmt (0, "var.0x%"PFMT64x".%s", var_addr, xs_type_str); return sdb_array_add_num (DB, var_global, xs_addr, 0); }
R_API int r_anal_xrefs_set (RAnal *anal, const RAnalRefType type, ut64 from, ut64 to) { char key[33]; if (!anal || !DB) { return false; } if (!anal->iob.is_valid_offset (anal->iob.io, to, 0)) { return false; } // unknown refs should not be stored. seems wrong if (type == R_ANAL_REF_TYPE_NULL) { return false; } XREFKEY (key, sizeof (key), "ref", type, from); sdb_array_add_num (DB, key, to, 0); XREFKEY (key, sizeof (key), "xref", type, to); sdb_array_add_num (DB, key, from, 0); return true; }
static int meta_type_add (RAnal *a, char type, ut64 addr) { char key[32]; ut32 count, last; snprintf (key, sizeof (key)-1, "meta.%c.count", type); count = (ut32)sdb_num_inc (DB, key, 1, 0); last = count/K; snprintf (key, sizeof (key)-1, "meta.%c.%d", type, last); sdb_array_add_num (DB, key, addr, 0); return count; }
static int meta_inrange_add (RAnal *a, ut64 addr, int size) { int set = 0; char key[64]; ut64 base, base2; base = META_RANGE_BASE (addr); base2 = META_RANGE_BASE (addr+size); for (; base<base2; base += META_RANGE_SIZE) { snprintf (key, sizeof (key)-1, "range.0x%"PFMT64x, base); if (sdb_array_add_num (DB, key, addr, 0)) set = 1; } return set; }
// avr R_API int r_anal_var_access (RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) { const char *xs_type_str = xs_type? "writes": "reads"; char key[128]; // TODO: kind is not used if (scope>0) { // local SETKEY ("var.0x%"PFMT64x, var_addr); //sdb_add (DB, key, var, 0); SETKEY ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, xs_type_str); } else { // global SETKEY ("var.0x%"PFMT64x, var_addr); sdb_add (DB, key, "a,", 0); SETKEY ("var.0x%"PFMT64x".%s", var_addr, xs_type_str); } return sdb_array_add_num (DB, key, xs_addr, 0); }
static int trace_hook_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) { int ret = 0; char *hexbuf = malloc ((1+len)*3); sdb_array_add_num (DB, KEY ("mem.write"), addr, 0); r_hex_bin2str (buf, len, hexbuf); sdb_set (DB, KEYAT ("mem.write.data", addr), hexbuf, 0); eprintf ("[ESIL] MEM WRITE 0x%08"PFMT64x" %s\n", addr, hexbuf); free (hexbuf); if (ocbs.hook_mem_write) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_mem_write (esil, addr, buf, len); esil->cb = cbs; } return ret; }
// TODO: Add APIs to resize meta? nope, just del and add R_API int r_meta_set_string(RAnal *a, int type, ut64 addr, const char *s) { char key[100], val[2048], *e_str; int ret; ut64 size; snprintf (key, sizeof (key)-1, "meta.%c", type); sdb_array_add_num (DB, key, addr, 0); snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr); size = sdb_array_get_num (DB, key, 0, 0); if (!size) { size = strlen (s); meta_inrange_add (a, addr, size); ret = R_TRUE; } else ret = R_FALSE; e_str = sdb_encode ((const void*)s, -1); snprintf (val, sizeof (val)-1, "%d,%s", (int)size, e_str); sdb_set (DB, key, val, 0); free ((void*)e_str); return ret; }
static int bbAdd(Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) { ut64 block_start = getCrossingBlock (db, "bbs", from, to); int add = 1; if (block_start == UT64_MAX) { // add = 1; } else if (block_start == from) { // check if size is the same, add = 0; } else { /* from = start address of new basic block to = end address of new basic block jump = destination basic block fail = fallback jump of basic block addr = previous closer basic block start address addr_end = previous closer basic block start address */ // found a possible block if (from > block_start) { // from inside // RESIZE this sdb_num_set (db, Fbb(block_start), from, 0); sdb_num_set (db, FbbTo(block_start), from, 0); sdb_array_set_num (db, FbbTo(block_start), 0, from, 0); sdb_array_set_num (db, FbbTo(block_start), 1, UT64_MAX, 0); } else { // < the current runs into a known block to = block_start; jump = block_start; fail = UT64_MAX; } } if (add) { sdb_array_add_num (db, "bbs", from, 0); sdb_num_set (db, Fbb(from), to, 0); sdb_array_set_num (db, FbbTo(from), 0, jump, 0); sdb_array_set_num (db, FbbTo(from), 1, fail, 0); sdb_num_min (db, "min", from, 0); sdb_num_max (db, "max", to, 0); } return 0; }
static int bbAdd (Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) { ut64 addr_end, addr = sdb_array_get_closer_num (db, "bbs", from); int add = 1; if (addr == UT64_MAX) { // add = 1; } else if (addr == from) { // check if size is the same, eprintf ("basic block already analyzed\n"); add = 0; } else { /* from = start address of new basic block to = end address of new basic block jump = destination basic block fail = fallback jump of basic block addr = previous closer basic block start address addr_end = previous closer basic block start address */ addr_end = sdb_num_get (db, Fbb(addr), NULL); if (addr_end) { if (from >= addr && from < addr_end) { eprintf ("OVERLAPS MUST SPLIT\n"); /* reduce current basic block to from */ eprintf ("Shrink basic block 0x%08"PFMT64x" to %d\n", addr, (int)(from-addr)); sdb_num_set (db, Fbb(addr), addr + from-addr, 0); sdb_num_set (db, FbbTo(addr), from, 0); //to = addr_end; // ??? } } } if (add) { sdb_array_add_num (db, "bbs", from, 0); sdb_num_set (db, Fbb(from), to, 0); if (jump != UT64_MAX) sdb_array_set_num (db, FbbTo(from), 0, jump, 0); if (fail != UT64_MAX) sdb_array_set_num (db, FbbTo(from), 1, fail, 0); sdb_num_min (db, "min", from, 0); sdb_num_max (db, "max", to, 0); } return 0; }
static int trace_hook_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) { char *hexbuf = malloc ((1+len)*3); int ret = 0; if (esil->cb.mem_read) { ret = esil->cb.mem_read (esil, addr, buf, len); } sdb_array_add_num (DB, KEY ("mem.read"), addr, 0); r_hex_bin2str (buf, len, hexbuf); sdb_set (DB, KEYAT ("mem.read.data", addr), hexbuf, 0); eprintf ("[ESIL] MEM READ 0x%08"PFMT64x" %s\n", addr, hexbuf); free (hexbuf); if (ocbs.hook_mem_read) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_mem_read (esil, addr, buf, len); esil->cb = cbs; } return ret; }
R_API int r_meta_add(RAnal *a, int type, ut64 from, ut64 to, const char *str) { int exists; char *e_str, key[100], val[2048]; if (from>to) return R_FALSE; if (from == to) to = from+1; if (type == 100) { if ((to-from)<3) { return R_FALSE; } } /* set entry */ e_str = sdb_encode ((const void*)str, -1); snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, from); snprintf (val, sizeof (val)-1, "%d,%s", (int)(to-from), e_str); exists = sdb_exists (DB, key); sdb_set (DB, key, val, 0); free (e_str); // XXX: This is totally inefficient, using array_add withuot // checking return value is wrong practice, also it may lead // to inconsistent DB, and pretty bad performance. We should // store this list in a different storage that doesnt have // those limits and it's O(1) instead of O(n) if (!exists) { /* set type index */ snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, from); snprintf (val, sizeof (val)-1, "%c", type); sdb_array_add (DB, key, val, 0); /* set type index */ snprintf (key, sizeof (key)-1, "meta.%c", type); sdb_array_add_num (DB, key, from, 0); } return R_TRUE; }
static int hook_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) { sdb_array_add_num (esil->stats, "mem.write", addr, 0); return 0; }
static int hook_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) { sdb_array_add_num (esil->stats, "mem.read", addr, 0); return 0; }