// 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; int space_idx = a->meta_spaces.space_idx; meta_type_add (a, type, addr); 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 = true; } else { ret = false; } if (a->log) { char *msg = r_str_newf (":C%c %s @ 0x%"PFMT64x, type, s, addr); a->log (a, msg); free (msg); } e_str = sdb_encode ((const void*)s, -1); snprintf (val, sizeof (val)-1, "%d,%d,%s", (int)size, space_idx, e_str); sdb_set (DB, key, val, 0); free ((void*)e_str); return ret; }
static ut64 getRefPtr(RCoreObjc *objc, ut64 classMethodsVA, bool *res) { ut64 namePtr = readQword (objc, classMethodsVA); int i, cnt = 0; ut64 res_at = 0LL; const char *k = addr_key (namePtr); *res = false; for (i = 0; ; i++) { ut64 at = sdb_array_get_num (objc->db, k, i, NULL); if (!at) { break; } if (inBetween (objc->_selrefs, at)) { *res = false; res_at = at; } else if (inBetween (objc->_msgrefs, at)) { *res = true; res_at = at; } else if (inBetween (objc->_const, at)) { cnt++; } } if (cnt > 1) { return 0LL; } return res_at; }
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; }
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; }
// 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; }
R_API int r_syscall_get_num(RSyscall *s, const char *str) { if (!s || !s->db) { return -1; } return (int)sdb_array_get_num (s->db, str, 1, NULL); }
R_API int r_syscall_get_swi(RSyscall *s) { return (int)sdb_array_get_num (s->db, "_", 0, NULL); }
static void type_match(RCore *core, ut64 addr, char *name) { Sdb *trace = core->anal->esil->db_trace; RAnal *anal = core->anal; RAnalVar *v; char *fcn_name; if (r_anal_type_func_exist (anal, name)) { fcn_name = strdup (name); } else if (!(fcn_name = r_anal_type_func_guess (anal, name))) { eprintf ("can't find function prototype for %s\n", name); return; } const char* cc = r_anal_type_func_cc (anal, fcn_name); if (!cc || !r_anal_cc_exist (anal, cc)) { eprintf ("can't find %s calling convention %s\n", fcn_name, cc); return; } int i, j, max = r_anal_type_func_args_count (anal, fcn_name); int size = 0, idx = sdb_num_get (trace, "idx", 0); const char *sp_name = r_reg_get_name (anal->reg, R_REG_NAME_SP); const char *bp_name = r_reg_get_name (anal->reg, R_REG_NAME_BP); ut64 sp = r_reg_getv (anal->reg, sp_name); ut64 bp = r_reg_getv (anal->reg, bp_name); for (i = 0; i < max; i++) { char *type = r_anal_type_func_args_type (anal, fcn_name, i); const char *name =r_anal_type_func_args_name (anal, fcn_name, i); const char *place = r_anal_cc_arg (anal, cc, i + 1); if (!strcmp (place, "stack")) { // type_match_stack (); for (j = idx; j >= 0; j--) { ut64 write_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.mem.write", j), 0); if (write_addr == sp + size) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v = r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } size += r_anal_type_get_size (anal, type) / 8; } else if (!strcmp (place , "stack_rev")) { // type_match_stack_rev (); free (type); int k; for ( k = max -1; k >=i; k--) { type = r_anal_type_func_args_type (anal, fcn_name, k); name =r_anal_type_func_args_name (anal, fcn_name, k); place = r_anal_cc_arg (anal, cc, k + 1); if (strcmp (place ,"stack_rev")) { break; } for (j = idx; j >= 0; j--) { ut64 write_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.mem.write", j), 0); if (write_addr == sp + size) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } size += r_anal_type_get_size (anal, type) / 8; } break; } else { // type_match_reg (); for (j = idx; j >= 0; j--) { if (sdb_array_contains (trace, sdb_fmt (-1, "%d.reg.write", j), place, 0)) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } } free (type); } free (fcn_name); }