R_API RAnalMetaItem *r_meta_find(RAnal *a, ut64 at, int type, int where) { const char *infos, *metas; char key[100]; Sdb *s = a->sdb_meta; static RAnalMetaItem mi = {0}; // XXX: return allocated item? wtf if (where != R_META_WHERE_HERE) { eprintf ("THIS WAS NOT SUPOSED TO HAPPEN\n"); return NULL; } snprintf (key, sizeof (key), "meta.0x%" PFMT64x, at); infos = sdb_const_get (s, key, 0); if (!infos) { return NULL; } for (; *infos; infos++) { if (*infos == ',') { continue; } if (type != R_META_TYPE_ANY && type != *infos) { continue; } snprintf (key, sizeof (key), "meta.%c.0x%" PFMT64x, *infos, at); metas = sdb_const_get (s, key, 0); if (metas) { if (!r_meta_deserialize_val (&mi, *infos, at, metas)) { continue; } return &mi; } } return NULL; }
static int dbdiff (const char *a, const char *b) { int n = 0; char *k, *v; const char *v2; Sdb *A = sdb_new (NULL, a, 0); Sdb *B = sdb_new (NULL, b, 0); sdb_dump_begin (A); while (sdb_dump_dupnext (A, &k, &v)) { v2 = sdb_const_get (B, k, 0); if (!v2) { printf ("%s=\n", k); n = 1; } } sdb_dump_begin (B); while (sdb_dump_dupnext (B, &k, &v)) { if (!v || !*v) continue; v2 = sdb_const_get (A, k, 0); if (!v2 || strcmp (v, v2)) { printf ("%s=%s\n", k, v2); n = 1; } } return n; }
R_API RSyscallItem *r_syscall_get(RSyscall *s, int num, int swi) { const char *ret, *ret2, *key; if (!s || !s->db) { eprintf ("Syscall database not loaded\n"); return NULL; } swi = getswi (s, swi); if (swi < 16) { key = sdb_fmt (0, "%d.%d", swi, num); } else { key = sdb_fmt (0, "0x%02x.%d", swi, num); } ret = sdb_const_get (s->db, key, 0); if (!ret) { key = sdb_fmt (0, "0x%02x.0x%02x", swi, num); // Workaround until Syscall SDB is fixed ret = sdb_const_get (s->db, key, 0); if (!ret) { return NULL; } } ret2 = sdb_const_get (s->db, ret, 0); if (!ret2) { return NULL; } return r_syscall_item_new_from_string (ret, ret2); }
static int dbdiff (const char *a, const char *b) { int n = 0; char *v; char k[SDB_MAX_KEY] = {0}; const char *v2; Sdb *A = sdb_new (NULL, a, 0); Sdb *B = sdb_new (NULL, b, 0); sdb_dump_begin (A); while (sdb_dump_dupnext (A, k, &v, NULL)) { v2 = sdb_const_get (B, k, 0); if (!v2) { printf ("%s=\n", k); n = 1; } } sdb_dump_begin (B); while (sdb_dump_dupnext (B, k, &v, NULL)) { if (!v || !*v) { continue; } v2 = sdb_const_get (A, k, 0); if (!v2 || strcmp (v, v2)) { printf ("%s=%s\n", k, v2); n = 1; } } sdb_free (A); sdb_free (B); free (v); return n; }
R_API void r_anal_esil_trace_show(RAnalEsil *esil, int idx) { PrintfCallback p = esil->anal->printf; const char *str2; const char *str; int trace_idx = esil->trace_idx; esil->trace_idx = idx; str2 = sdb_const_get (DB, KEY ("addr"), 0); if (!str2) { return; } p ("dr pc = %s\n", str2); /* registers */ str = sdb_const_get (DB, KEY ("reg.read"), 0); if (str) { char regname[32]; const char *next, *ptr = str; if (ptr && *ptr) { do { const char *ztr = sdb_const_anext (ptr, &next); int len = next? (int)(size_t)(next-ztr)-1 : strlen (ztr); if (len <sizeof(regname)) { memcpy (regname, ztr, len); regname[len] = 0; str2 = sdb_const_get (DB, KEYREG ("reg.read", regname), 0); p ("dr %s = %s\n", regname, str2); } else { eprintf ("Invalid entry in reg.read\n"); } ptr = next; } while (next); } } /* memory */ str = sdb_const_get (DB, KEY ("mem.read"), 0); if (str) { char addr[64]; const char *next, *ptr = str; if (ptr && *ptr) { do { const char *ztr = sdb_const_anext (ptr, &next); int len = next? (int)(size_t)(next-ztr)-1 : strlen (ztr); if (len <sizeof(addr)) { memcpy (addr, ztr, len); addr[len] = 0; str2 = sdb_const_get (DB, KEYAT ("mem.read.data", r_num_get (NULL, addr)), 0); p ("wx %s @ %s\n", str2, addr); } else { eprintf ("Invalid entry in reg.read\n"); } ptr = next; } while (next); } } esil->trace_idx = trace_idx; }
int main() { const char *v; Sdb *s = sdb_new0 (); sdb_set (s, "key", "foo", 0); v = sdb_const_get(s, "key", 0); printf ("%p %p (assert != 0)\n", s, v); if (!v) return 1; sdb_drain (s, sdb_new0()); v = sdb_const_get(s, "key", 0); printf ("%p %p (assert == 0)\n", s, v); sdb_free (s); return (v==0)?0:1; }
R_API char *r_type_enum_getbitfield(Sdb *TDB, const char *name, ut64 val) { char *q, *ret = NULL; const char *res; int i; if (r_type_kind (TDB, name) != R_TYPE_ENUM) { return NULL; } bool isFirst = true; ret = r_str_appendf (ret, "0x%08"PFMT64x" : ", val); for (i = 0; i < 32; i++) { if (!(val & (1 << i))) { continue; } q = sdb_fmt ("enum.%s.0x%x", name, (1<<i)); res = sdb_const_get (TDB, q, 0); if (isFirst) { isFirst = false; } else { ret = r_str_append (ret, " | "); } if (res) { ret = r_str_append (ret, res); } else { ret = r_str_appendf (ret, "0x%x", (1<<i)); } } return ret; }
R_API char *r_meta_get_string(RAnal *a, int type, ut64 addr) { char key[100]; const char *k, *p, *p2, *p3; snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr); k = sdb_const_get (DB, key, NULL); if (!k) { return NULL; } p = strchr (k, SDB_RS); if (!p) { return NULL; } k = p + 1; p2 = strchr (k, SDB_RS); if (!p2) { return (char *)sdb_decode (k, NULL); } k = p2 + 1; if (type == R_META_TYPE_STRING) { p3 = strchr (k, SDB_RS); if (p3) { return (char *)sdb_decode (p3 + 1, NULL); } } return (char *)sdb_decode (k, NULL); }
R_API const char* r_syscall_sysreg(RSyscall *s, const char *type, ut64 num) { if (!s || !s->db) { return NULL; } const char *key = sdb_fmt (0, "%s,%"PFMT64d, type, num); return sdb_const_get (s->db, key, 0); }
SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) { const char *str = sdb_const_get (s, key, cas); const char *p = str; char *o, *n; int i, len; if (!str || !*str) return NULL; if (idx<0) { int len = sdb_alen (str); idx = -idx; if (idx>len) return NULL; idx = (len-idx); } if (idx==0) { n = strchr (str, SDB_RS); if (!n) return strdup (str); len = n-str; o = malloc (len+1); memcpy (o, str, len); o[len] = 0; return o; } for (i=0; i<idx; i++) { n = strchr (p, SDB_RS); if (!n) return NULL; p = n+1; } n = strchr (p, SDB_RS); if (!n) return strdup (p); len = n-p; o = malloc (len+1); memcpy (o, p, len); o[len] = 0; return o; }
R_API const char *r_syscall_get_i(RSyscall *s, int num, int swi) { char foo[32]; if (!s || !s->db) return NULL; swi = getswi (s->db, swi); snprintf (foo, sizeof (foo), "0x%x.%d", swi, num); return sdb_const_get (s->db, foo, 0); }
R_API RAnalMetaItem *r_meta_find(RAnal *a, ut64 at, int type, int where) { const char *infos, *metas; char key[100]; Sdb *s = a->sdb_meta; static RAnalMetaItem mi = {0}; // XXX: return allocated item? wtf if (where != R_META_WHERE_HERE) { eprintf ("THIS WAS NOT SUPOSED TO HAPPEN\n"); return NULL; } snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, at); infos = sdb_const_get (s, key, 0); if (!infos) return NULL; for (; *infos; infos++) { /* XXX wtf, must use anal.meta.deserialize() */ char *p, *q; if (*infos==',') continue; snprintf (key, sizeof (key) - 1, "meta.%c.0x%"PFMT64x, *infos, at); metas = sdb_const_get (s, key, 0); mi.size = sdb_array_get_num (s, key, 0, 0); mi.type = *infos; mi.from = at; mi.to = at + mi.size; if (type != R_META_TYPE_ANY && type != mi.type) { continue; } if (metas) { p = strchr (metas, ','); if (!p) { continue; } mi.space = atoi (p + 1); q = strchr (p + 1, ','); if (!q) { continue; } free (mi.str); mi.str = (char*)sdb_decode (q + 1, 0); return &mi; } else mi.str = NULL; } return NULL; }
static int typelist (void *p, const char *k, const char *v) { r_cons_printf ("tk %s = %s\n", k, v); #if 0 if (!strcmp (v, "func")) { const char *rv = sdb_const_get (DB, sdb_fmt (0, "func.%s.ret", k), 0); r_cons_printf ("# %s %s(", rv, k); for (i = 0; i < 16; i++) { char *av = sdb_get (DB, sdb_fmt (0, "func.%s.arg.%d", k, i), 0); if (!av) break; r_str_replace_char (av, ',', ' '); r_cons_printf ("%s%s", i? ", ": "", av); free (av); } r_cons_printf (");\n"); // signature in pf for asf r_cons_printf ("asf %s=", k); // formats for (i = 0; i < 16; i++) { const char *fmt; char *comma, *av = sdb_get (DB, sdb_fmt (0, "func.%s.arg.%d", k, i), 0); if (!av) break; comma = strchr (av, ','); if (comma) *comma = 0; fmt = sdb_const_get (DB, sdb_fmt (0, "type.%s", av), 0); r_cons_printf ("%s", fmt); if (comma) *comma = ','; free (av); } // names for (i = 0; i < 16; i++) { char *comma, *av = sdb_get (DB, sdb_fmt (0, "func.%s.arg.%d", k, i), 0); if (!av) break; comma = strchr (av, ','); if (comma) *comma++ = 0; r_cons_printf (" %s", comma); free (av); } r_cons_newline (); } #endif return 1; }
R_API RAnalHint *r_anal_hint_get(RAnal *a, ut64 addr) { char key[64]; setf (key, "hint.0x%08"PFMT64x, addr); const char *s = sdb_const_get (DB, key, 0); if (!s) { return NULL; } return r_anal_hint_from_string (a, addr, s); }
R_API int r_anal_type_set(RAnal *anal, ut64 at, const char *field, ut64 val) { Sdb *DB = anal->sdb_types; const char *kind; char var[128]; sprintf (var, "link.%08"PFMT64x, at); kind = sdb_const_get (DB, var, NULL); if (kind) { const char *p = sdb_const_get (DB, kind, NULL); if (p) { snprintf (var, sizeof (var), "%s.%s.%s", p, kind, field); int off = sdb_array_get_num (DB, var, 1, NULL); //int siz = sdb_array_get_num (DB, var, 2, NULL); eprintf ("wv 0x%08"PFMT64x" @ 0x%08"PFMT64x, val, at+off); return true; } else eprintf ("Invalid kind of type\n"); } return false; }
bool test_sdb_array_add_remove(void) { Sdb *db = sdb_new (NULL, NULL, false); sdb_array_add (db, "foo", "foo", 0); sdb_array_add (db, "foo", "bar", 0); sdb_array_add (db, "foo", "cow", 0); mu_assert_streq (sdb_const_get (db, "foo", 0), "foo,bar,cow", "Not all items found"); sdb_array_remove (db, "foo", "bar", 0); mu_assert_streq (sdb_const_get (db, "foo", 0), "foo,cow", "bar was not deleted"); sdb_array_remove (db, "foo", "nothing", 0); mu_assert_streq (sdb_const_get (db, "foo", 0), "foo,cow", "nothing should be deleted"); sdb_array_remove (db, "foo", "cow", 0); sdb_array_remove (db, "foo", "foo", 0); mu_assert_eq ((int)(size_t)sdb_const_get (db, "foo", 0), (int)(size_t)NULL, "all elements should be deleted"); sdb_free (db); mu_end; }
static int getswi(Sdb *p, int swi) { if (p && swi == -1) { // TODO: use array_get_num here const char *def = sdb_const_get (p, "_", 0); if (def && *def) { swi = r_num_get (NULL, def); } else swi = 0x80; // XXX hardcoded } return swi; }
int main(int argc, char **argv) { int i, N; if (argc>1) N = atoi (argv[1]); else N = 1000; Sdb *s = sdb_new (NULL, NULL, 0); for (i=0;i<N;i++) sdb_array_push (s, "key", "foo", 0); #if 1 if (N != sdb_alen (sdb_const_get (s, "key", 0))) { printf ("FAIL IN VERY PUSH\n"); return 1; } eprintf ("--%d\n", (int)strlen (sdb_const_get (s, "key", 0))); #endif for (i=0;i<N;i++) free (sdb_array_pop (s, "key", 0)); sdb_free (s); return 0; }
R_API char *r_meta_get_string(RAnal *a, int type, ut64 addr) { char key[100]; const char *k, *p; snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, 'C', addr); k = sdb_const_get (DB, key, NULL); if (!k) return NULL; p = strchr (k, SDB_RS); if (!p) return NULL; k = p+1; // TODO : comment append has been deprecated return (char *)sdb_decode (k, NULL); }
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size, const char *str) { char key[100], *dtr, *s, *p, *next; #if 0 char key2[100]; #endif const char *ptr; int i; if (size == UT64_MAX) { // FULL CLEANUP // XXX: this thing ignores the type if (type == R_META_TYPE_ANY) { sdb_reset (DB); } else { snprintf (key, sizeof (key)-1, "meta.%c.count", type); int last = (ut64)sdb_num_get (DB, key, NULL)/K; for (i=0; i<last; i++) { snprintf (key, sizeof (key)-1, "meta.%c.%d", type, i); dtr = sdb_get (DB, key, 0); for (p = dtr; p; p = next) { s = sdb_anext (p, &next); snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, sdb_atoi (s)); eprintf ("--> %s\n", key); sdb_unset (DB, key, 0); if (!next) break; } free (dtr); } } return false; } meta_inrange_del (a, addr, size); snprintf (key, sizeof (key)-1, type == R_META_TYPE_COMMENT ? "meta.C.0x%"PFMT64x : "meta.0x%"PFMT64x, addr); ptr = sdb_const_get (DB, key, 0); if (ptr) { sdb_unset (DB, key, 0); #if 0 // This code is wrong, but i guess it's necessary in case type is ANY for (i=0; ptr[i]; i++) { if (ptr[i] != SDB_RS) { snprintf (key2, sizeof (key2)-1, "meta.%c.0x%"PFMT64x, ptr[i], addr); printf ("UNSET (%s)\n", key2); sdb_unset (DB, key2, 0); } } #endif } sdb_unset (DB, key, 0); return false; }
static RAnalVar *get_used_var(RAnal *anal, RAnalOp *op) { char *inst_key = sdb_fmt (0, "inst.0x%"PFMT64x".vars", op->addr); const char *var_def = sdb_const_get (anal->sdb_fcns, inst_key, 0); struct VarUsedType vut; RAnalVar *res; if (sdb_fmt_tobin (var_def, SDB_VARUSED_FMT, &vut) != 4) { return NULL; } res = r_anal_var_get (anal, vut.fcn_addr, vut.type[0], vut.scope, vut.delta); sdb_fmt_free (&vut, SDB_VARUSED_FMT); return res; }
R_API RAnalHint *r_anal_hint_get(RAnal *a, ut64 addr) { char key[128]; const char *s; RAnalHint *hint; setf (key, "hint.0x%"PFMT64x, addr); s = sdb_const_get (DB, key, 0); if (!s) { return NULL; } hint = r_anal_hint_from_string (a, addr, s); return hint; }
R_API void r_anal_type_del(RAnal *anal, const char *name) { int n; char *p, str[128], str2[128]; Sdb *DB = anal->sdb_types; const char *kind = sdb_const_get (DB, name, 0); snprintf (str, sizeof (str), "%s.%s", kind, name); #define SDB_FOREACH(x,y,z) for (z = 0; (p = sdb_array_get (x, y, z, NULL)); z++) #define SDB_FOREACH_NEXT() free(p) SDB_FOREACH (DB, str, n) { snprintf (str2, sizeof (str2), "%s.%s", str, p); sdb_unset (DB, str2, 0); SDB_FOREACH_NEXT (); }
/* get array index of given value */ SDB_API int sdb_array_indexof(Sdb *s, const char *key, const char *val, ut32 cas) { const char *str = sdb_const_get (s, key, 0); const char *n, *p = str; int idx; for (idx=0; ; idx++) { if (!p) break; if (!astrcmp (p, val)) return idx; n = strchr (p, SDB_RS); if (!n) break; p = n+1; } return -1; }
// previously named del_str... pair with _add SDB_API int sdb_array_remove(Sdb *s, const char *key, const char *val, ut32 cas) { const char *str = sdb_const_get (s, key, 0); const char *n, *p = str; int idx; if (p) for (idx=0; ; idx++) { if (!astrcmp (p, val)) return sdb_array_delete (s, key, idx, cas); n = strchr (p, SDB_RS); if (!n) break; p = n+1; } return 0; }
R_API int r_anal_pin_call(RAnal *a, ut64 addr) { char buf[64]; const char *key, *name; key = sdb_itoa (addr, buf, 16); if (!key) return R_FALSE; name = sdb_const_get (DB, key, NULL); if (!name) return R_FALSE; RAnalEsilPin fcnptr = (RAnalEsilPin)sdb_ptr_get (DB, name, NULL); if (fcnptr) { fcnptr (a); return R_TRUE; } return R_FALSE; }
SDB_API ut64 sdb_array_get_num(Sdb *s, const char *key, int idx, ut32 *cas) { int i; const char *n, *str = sdb_const_get (s, key, cas); if (!str || !*str) { return 0LL; } if (idx) { for (i = 0; i < idx; i++) { n = strchr (str, SDB_RS); if (!n) return 0LL; str = n + 1; } } return sdb_atoi (str); }
SDB_API int sdb_array_remove_num(Sdb *s, const char *key, ut64 val, ut32 cas) { const char *n, *p, *str = sdb_const_get (s, key, 0); int idx = 0; ut64 num; if (!str) return 0; for (p=str; ; idx++) { num = sdb_atoi (p); if (num == val) return sdb_array_delete (s, key, idx, cas); n = strchr (p, SDB_RS); if (!n) break; p = n+1; } return 0; }
SDB_API ut64 sdb_array_get_num(Sdb *s, const char *key, int idx, ut32 *cas) { const char *str, *n, *p; int i; p = str = sdb_const_get (s, key, cas); if (!str || !*str) return 0LL; if (idx==0) return sdb_atoi (str); for (i=0; i<idx; i++) { n = strchr (p, SDB_RS); if (!n) return 0LL; p = n+1; } return sdb_atoi (p); }
R_API char *r_meta_get_string(RAnal *a, int type, ut64 addr) { char key[100]; const char *k, *p, *p2; snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, 'C', addr); k = sdb_const_get (DB, key, NULL); if (!k) return NULL; p = strchr (k, SDB_RS); if (!p) return NULL; k = p+1; p2 = strchr (k, SDB_RS); if (!p2) { return (char *)sdb_decode (k, NULL); } return (char *)sdb_decode (p2+1, NULL); }