static int stack_clean (RCore *core, ut64 addr, RAnalFunction *fcn) { int offset, ret; char *tmp, *str, *sig; RAnalOp *op = r_core_anal_op (core, addr); if (!op) { return 0; } str = strdup (r_strbuf_get (&op->esil)); if (!str) { return 0; } tmp = strchr (str, ','); if (!tmp) { free (str); return 0; } *tmp++ = 0; offset = r_num_math (core->num, str); const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP); sig = sdb_fmt (-1, "%s,+=", sp); ret = 0; if (!strncmp (tmp, sig, strlen (sig))) { const char *esil = sdb_fmt (-1, "%d,%s,-=", offset, sp); r_anal_esil_parse (core->anal->esil, esil); r_anal_esil_dumpstack (core->anal->esil); r_anal_esil_stack_free (core->anal->esil); r_core_esil_step (core, UT64_MAX, NULL); ret = op->size; } r_anal_op_free (op); free (str); return ret; }
int emu_step (emu *e, ut8 *buf) { int ret; ut64 addr = r_reg_getv (e->reg, r_reg_get_name (e->reg, R_REG_NAME_PC)); //Check Breakboints here: new return stat for that if (e->plugin->read) { if (e->plugin->min_read_sz) e->plugin->read (e, addr, buf, e->plugin->min_read_sz); else e->plugin->read (e, addr, buf, sizeof(int)); } else { if (e->plugin->min_read_sz) emu_read (e, addr, buf, e->plugin->min_read_sz); else emu_read (e, addr, buf, sizeof(int)); } if (e->plugin->deps & EMU_PLUGIN_DEP_ASM) { //only disassemble if it is necessary r_asm_set_pc (e->a, addr); if (e->plugin->min_read_sz) r_asm_disassemble (e->a, e->op, buf, e->plugin->min_read_sz); else r_asm_disassemble (e->a, e->op, buf, sizeof(int)); } if (e->plugin->deps & EMU_PLUGIN_DEP_ANAL) { //only analize if it is necessary if (e->plugin->min_read_sz) r_anal_op (e->anal, e->anop, addr, buf, e->plugin->min_read_sz); else r_anal_op (e->anal, e->anop, addr, buf, sizeof(int)); } ret = e->plugin->step (e, buf); if (e->plugin->deps & EMU_PLUGIN_DEP_ANAL) r_anal_op_fini (e->anop); return ret; }
R_API void r_anal_type_match(RCore *core, RAnalFunction *fcn) { bool esil_var[STATES_SIZE] = {false}; if (!core ) { return; } if (!r_anal_emul_init (core, esil_var) || !fcn ) { r_anal_emul_restore (core, esil_var); return; } const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); ut64 addr = fcn->addr; r_reg_setv (core->dbg->reg, pc, fcn->addr); r_debug_reg_sync (core->dbg, -1, true); r_cons_break (NULL, NULL); while (!r_cons_is_breaked ()) { RAnalOp *op = r_core_anal_op (core, addr); int loop_count = sdb_num_get ( core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), 0); if (loop_count > LOOP_MAX) { eprintf ("Unfortunately your evilly engineered %s function trapped my most innocent `aftm` in an infinite loop.\n", fcn->name); eprintf ("I kept trace log for you to review and find out how bad things were going to happen by yourself.\n"); eprintf ("You can view this log by `ate`. Meanwhile, I will train on how to behave with such behaviour without bothering you.\n"); return; } sdb_num_set (core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), loop_count + 1, 0); if (!op || op->type == R_ANAL_OP_TYPE_RET) { r_anal_emul_restore (core, esil_var); return; } if (op->type == R_ANAL_OP_TYPE_CALL) { RAnalFunction *fcn_call = r_anal_get_fcn_in (core->anal, op->jump, -1); //eprintf ("in the middle of %s\n", fcn_call->name); if (fcn_call) { type_match (core, addr, fcn_call->name); } else { eprintf ("Cannot find function at 0x%08"PFMT64x"\n", op->jump); } addr += op->size; r_anal_op_free (op); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); addr += stack_clean (core, addr, fcn); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); continue; } else { r_core_esil_step (core, UT64_MAX, NULL); r_anal_op_free (op); } r_core_cmd0 (core, ".ar*"); addr = r_reg_getv (core->anal->reg, pc); } r_cons_break_end (); r_anal_emul_restore (core, esil_var); }
static bool r_anal_emul_init(RCore *core, bool *state) { state[ROMEM] = r_config_get_i (core->config, "esil.romem"); r_config_set (core->config, "esil.romem", "true"); state[ASM_TRACE] = r_config_get_i (core->config, "asm.trace"); r_config_set (core->config, "asm.trace", "true"); state[ANAL_TRACE] = r_config_get_i (core->config, "anal.trace"); r_config_set (core->config, "anal.trace", "true"); state[DBG_TRACE] = r_config_get_i (core->config, "dbg.trace"); r_config_set (core->config, "dbg.trace", "true"); state[NONULL] = r_config_get_i (core->config, "esil.nonull"); r_config_set (core->config, "esil.nonull", "true"); const char *bp = r_reg_get_name (core->anal->reg, R_REG_NAME_BP); const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP); if ((bp && !r_reg_getv (core->anal->reg, bp)) || (sp && !r_reg_getv (core->anal->reg, sp))) { eprintf ("Stack isn't initiatized.\n"); eprintf ("Try running aei and aeim commands before aftm for default stack initialization\n"); return false; } return (core->anal->esil != NULL); }
static void prepend_current_pc (RDebug *dbg, RList *list) { RDebugFrame *frame; const char *pcname; if (list) { pcname = r_reg_get_name (dbg->reg, R_REG_NAME_PC); if (pcname) { ut64 addr = r_reg_getv (dbg->reg, pcname); frame = R_NEW0 (RDebugFrame); frame->addr = addr; frame->size = 0; r_list_prepend (list, frame); } } }
R_API void r_core_print_func_args(RCore *core) { RListIter *iter; bool color = r_config_get_i (core->config, "scr.color"); if (!core->anal) { return; } if (!core->anal->reg) { return; } const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); ut64 cur_addr = r_reg_getv (core->anal->reg, pc); RAnalOp *op = r_core_anal_op (core, cur_addr, R_ANAL_OP_MASK_BASIC); if (!op) { return; } if (op->type == R_ANAL_OP_TYPE_CALL) { RAnalFunction *fcn; RAnalFuncArg *arg; int i; int nargs = 0; bool onstack = false; const char *fcn_name = NULL; ut64 pcv = op->jump; if (pcv == UT64_MAX) { pcv = op->ptr; } fcn = r_anal_get_fcn_at (core->anal, pcv, 0); if (fcn) { fcn_name = fcn->name; } else { if (core->flags) { RFlagItem *item = r_flag_get_i (core->flags, pcv); if (item) { fcn_name = item->name; } } } RList *list = r_core_get_func_args (core, fcn_name); if (!r_list_empty (list)) { int argcnt = 0; r_list_foreach (list, iter, arg) { if (arg->cc_source && !strncmp (arg->cc_source, "stack", 5)) { onstack = true; } print_arg_str (argcnt, arg->name, color); print_format_values (core, arg->fmt, onstack, arg->src, color); argcnt++; } } else {
static int r_debug_gdb_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) { check_connection (dbg); if (!reg_buf) { // we cannot write registers before we once read them return -1; } int buflen = 0; int bits = dbg->anal->bits; const char *pcname = r_reg_get_name (dbg->anal->reg, R_REG_NAME_PC); RRegItem *reg = r_reg_get (dbg->anal->reg, pcname, 0); if (reg) { if (dbg->anal->bits != reg->size) bits = reg->size; } free (r_reg_get_bytes (dbg->reg, type, &buflen)); // some implementations of the gdb protocol are acting weird. // so winedbg is not able to write registers through the <G> packet // and also it does not return the whole gdb register profile after // calling <g> // so this workaround resizes the small register profile buffer // to the whole set and fills the rest with 0 if (buf_size < buflen) { ut8* new_buf = realloc (reg_buf, buflen * sizeof (ut8)); if (!new_buf) { return -1; } reg_buf = new_buf; memset (new_buf + buf_size, 0, buflen - buf_size); } RRegItem* current = NULL; for (;;) { current = r_reg_next_diff (dbg->reg, type, reg_buf, buflen, current, bits); if (!current) break; ut64 val = r_reg_get_value (dbg->reg, current); int bytes = bits / 8; gdbr_write_reg (desc, current->name, (char*)&val, bytes); } return true; }
R_API int r_anal_esil_to_reil_setup(RAnalEsil *esil, RAnal *anal, int romem, int stats) { if (!esil) return false; esil->debug = 1; esil->anal = anal; esil->trap = 0; esil->trap_code = 0; /* Set up a callback for hook_command */ esil->cb.hook_command = setup_reil_ins; esil->Reil = R_NEW0(RAnalReil); if (!esil->Reil) { return false; } esil->Reil->reilNextTemp = 0; esil->Reil->addr = -1; esil->Reil->seq_num = 0; esil->Reil->skip = 0; // Store the pc const char *name = r_reg_get_name (esil->anal->reg, r_reg_get_name_idx ("PC")); strncpy (esil->Reil->pc, name, sizeof(esil->Reil->pc) - 1); r_anal_esil_mem_ro(esil, romem); r_anal_esil_set_op(esil, "=", reil_eq); r_anal_esil_set_op(esil, "+", reil_add); r_anal_esil_set_op(esil, "+=", reil_addeq); r_anal_esil_set_op(esil, "-", reil_sub); r_anal_esil_set_op(esil, "-=", reil_subeq); r_anal_esil_set_op(esil, "*", reil_mul); r_anal_esil_set_op(esil, "*=", reil_muleq); r_anal_esil_set_op(esil, "/", reil_div); r_anal_esil_set_op(esil, "/=", reil_diveq); r_anal_esil_set_op(esil, "^", reil_xor); r_anal_esil_set_op(esil, "^=", reil_xoreq); r_anal_esil_set_op(esil, "|", reil_or); r_anal_esil_set_op(esil, "|=", reil_oreq); r_anal_esil_set_op(esil, "&", reil_and); r_anal_esil_set_op(esil, "&=", reil_andeq); r_anal_esil_set_op(esil, "<<", reil_lsl); r_anal_esil_set_op(esil, "<<=", reil_lsleq); r_anal_esil_set_op(esil, ">>", reil_lsr); r_anal_esil_set_op(esil, ">>=", reil_lsreq); r_anal_esil_set_op(esil, "++=", reil_inceq); r_anal_esil_set_op(esil, "++", reil_inc); r_anal_esil_set_op(esil, "--=", reil_deceq); r_anal_esil_set_op(esil, "--", reil_dec); r_anal_esil_set_op(esil, "!", reil_neg); r_anal_esil_set_op(esil, "!=", reil_negeq); r_anal_esil_set_op(esil, "==", reil_cmp); r_anal_esil_set_op(esil, "<", reil_smaller); r_anal_esil_set_op(esil, ">", reil_larger); r_anal_esil_set_op(esil, "<=", reil_smaller_equal); r_anal_esil_set_op(esil, ">=", reil_larger_equal); r_anal_esil_set_op(esil, "[]", reil_peek); r_anal_esil_set_op(esil, "=[]", reil_poke); r_anal_esil_set_op(esil, "|=[]", reil_mem_oreq); r_anal_esil_set_op(esil, "^=[]", reil_mem_xoreq); r_anal_esil_set_op(esil, "&=[]", reil_mem_andeq); r_anal_esil_set_op(esil, "+=[]", reil_mem_addeq); r_anal_esil_set_op(esil, "-=[]", reil_mem_subeq); r_anal_esil_set_op(esil, "*=[]", reil_mem_muleq); r_anal_esil_set_op(esil, "++=[]", reil_mem_inceq); r_anal_esil_set_op(esil, "--=[]", reil_mem_deceq); r_anal_esil_set_op(esil, "=[1]", reil_poke1); r_anal_esil_set_op(esil, "=[2]", reil_poke2); r_anal_esil_set_op(esil, "=[4]", reil_poke4); r_anal_esil_set_op(esil, "=[8]", reil_poke8); r_anal_esil_set_op(esil, "[1]", reil_peek1); r_anal_esil_set_op(esil, "[2]", reil_peek2); r_anal_esil_set_op(esil, "[4]", reil_peek4); r_anal_esil_set_op(esil, "[8]", reil_peek8); r_anal_esil_set_op(esil, "|=[1]", reil_mem_oreq1); r_anal_esil_set_op(esil, "|=[2]", reil_mem_oreq2); r_anal_esil_set_op(esil, "|=[4]", reil_mem_oreq4); r_anal_esil_set_op(esil, "|=[8]", reil_mem_oreq8); r_anal_esil_set_op(esil, "^=[1]", reil_mem_xoreq1); r_anal_esil_set_op(esil, "^=[2]", reil_mem_xoreq2); r_anal_esil_set_op(esil, "^=[4]", reil_mem_xoreq4); r_anal_esil_set_op(esil, "^=[8]", reil_mem_xoreq8); r_anal_esil_set_op(esil, "&=[1]", reil_mem_andeq1); r_anal_esil_set_op(esil, "&=[2]", reil_mem_andeq2); r_anal_esil_set_op(esil, "&=[4]", reil_mem_andeq4); r_anal_esil_set_op(esil, "&=[8]", reil_mem_andeq8); r_anal_esil_set_op(esil, "+=[1]", reil_mem_addeq1); r_anal_esil_set_op(esil, "+=[2]", reil_mem_addeq2); r_anal_esil_set_op(esil, "+=[4]", reil_mem_addeq4); r_anal_esil_set_op(esil, "+=[8]", reil_mem_addeq8); r_anal_esil_set_op(esil, "-=[1]", reil_mem_subeq1); r_anal_esil_set_op(esil, "-=[2]", reil_mem_subeq2); r_anal_esil_set_op(esil, "-=[4]", reil_mem_subeq4); r_anal_esil_set_op(esil, "-=[8]", reil_mem_subeq8); r_anal_esil_set_op(esil, "*=[1]", reil_mem_muleq1); r_anal_esil_set_op(esil, "*=[2]", reil_mem_muleq2); r_anal_esil_set_op(esil, "*=[4]", reil_mem_muleq4); r_anal_esil_set_op(esil, "*=[8]", reil_mem_muleq8); r_anal_esil_set_op(esil, "++=[1]", reil_mem_inceq1); r_anal_esil_set_op(esil, "++=[2]", reil_mem_inceq2); r_anal_esil_set_op(esil, "++=[4]", reil_mem_inceq4); r_anal_esil_set_op(esil, "++=[8]", reil_mem_inceq8); r_anal_esil_set_op(esil, "--=[1]", reil_mem_deceq1); r_anal_esil_set_op(esil, "--=[2]", reil_mem_deceq2); r_anal_esil_set_op(esil, "--=[4]", reil_mem_deceq4); r_anal_esil_set_op(esil, "--=[8]", reil_mem_deceq8); r_anal_esil_set_op(esil, "?{", reil_if); r_anal_esil_set_op(esil, "}", reil_if_end); return true; }
// XXX: RVM must be inside RAnal ???? imho no. rsyscall must provide ret reg info //XXX: may overflow. this is vulnerable. needs fix R_API char *r_anal_cc_to_string (RAnal *anal, RAnalCC* cc) { RSyscallItem *si; RAnalFunction *fcn; char str[1024], buf[64]; int i, eax = 0; // eax = arg0 int str_len = 0; int buf_len = 0; str[0] = 0; switch (cc->type) { case R_ANAL_CC_TYPE_FASTCALL: // INT { RRegItem *item; const char *a0 = r_reg_get_name (anal->reg, R_REG_NAME_A0); // A0 or RET ?? item = r_reg_get (anal->reg, a0, R_REG_TYPE_GPR); if (!item) { //eprintf ("cannot get reg a0\n"); return R_FALSE; } eax = (int)r_reg_get_value (anal->reg, item); si = r_syscall_get (anal->syscall, eax, (int)cc->jump); if (si) { //DEBUG r_cons_printf (" ; sc[0x%x][%d]=%s(", (int)analop.value, eax, si->name); snprintf (str, sizeof (str), "%s (", si->name); for (i=0; i<si->args; i++) { const char *reg = r_syscall_reg (anal->syscall, i+1, si->args); if (!reg) break; // no registers? item = r_reg_get (anal->reg, reg, R_REG_TYPE_GPR); if (item) { snprintf (buf, sizeof (buf), "0x%"PFMT64x, r_reg_get_value (anal->reg, item)); strcat (str, buf); // XXX: do not use strcat } //else eprintf ("Unknown reg '%s'\n", reg); if (i<si->args-1) strcat (str, ","); // XXX: do not use strcat } strcat (str, ")"); } else { int n = (int)cc->jump; //if (n == 3) return NULL; // XXX: hack for x86 snprintf (str, sizeof (str), "syscall[0x%x][%d]=?", n, eax); } } break; case R_ANAL_CC_TYPE_STDCALL: // CALL fcn = r_anal_fcn_find (anal, cc->jump, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_IMP); if (fcn && fcn->name) snprintf (str, sizeof (str), "%s(", fcn->name); else if (cc->jump != -1LL) snprintf (str, sizeof (str), "0x%08"PFMT64x"(", cc->jump); else strncpy (str, "unk(", sizeof (str)-1); str_len = strlen (str); if (fcn) cc->nargs = (fcn->nargs>cc->nargs?fcn->nargs:cc->nargs); if (cc->nargs>8) { //eprintf ("too many arguments for stdcall. chop to 8\n"); cc->nargs = 8; } // TODO: optimize string concat for (i=0; i<cc->nargs; i++) { if (cc->args[cc->nargs-i] != -1LL) snprintf (buf, sizeof (buf), "0x%"PFMT64x, cc->args[cc->nargs-i]); else strncpy (buf, "unk", sizeof (buf)-1); buf_len = strlen (buf); if ((buf_len+str_len+5)>=sizeof (str)) { strcat (str, "..."); break; } strcat (str, buf); str_len += buf_len; if (i<cc->nargs-1) strcat (str, ", "); } strcat (str, ")"); break; } return strdup (str); }
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); }
R_API bool r_reg_set_value_by_role(RReg *reg, RRegisterId role, ut64 val) { // TODO use mapping from RRegisterId to RRegItem (via RRegSet) RRegItem *r = r_reg_get (reg, r_reg_get_name (reg, role), -1); return r_reg_set_value (reg, r, val); }
R_API ut64 r_reg_get_value_by_role(RReg *reg, RRegisterId role) { // TODO use mapping from RRegisterId to RRegItem (via RRegSet) return r_reg_get_value (reg, r_reg_get (reg, r_reg_get_name (reg, role), -1)); }
int main() { int i; int foo[128]; const char *type; struct r_reg_t *reg; for (i=0;i<128;i++) foo[i] = i; reg = r_reg_new (); r_reg_set_profile (reg, "./test.regs"); r_reg_read_regs (reg, (const ut8 *)foo, sizeof(foo)); { ut64 a; RRegItem *item; item = r_reg_get (reg, "eflags", R_REG_TYPE_GPR); r_reg_set_value (reg, item, 0x00000346); //0xffffffffffff); a = r_reg_get_value (reg, item); eprintf ("A32 = 0x%x\n", (int)a); if ((int)a != -1) { eprintf ("1 FAIL\n"); } print_eflags_bits (reg); item = r_reg_get (reg, "zf", R_REG_TYPE_GPR); a = r_reg_get_value (reg, item); eprintf ("A = %d\n", (int)a); if (a != 1) { eprintf ("2 FAIL\n"); } item = r_reg_get (reg, "zf", R_REG_TYPE_GPR); r_reg_set_value (reg, item, 1); a = r_reg_get_value (reg, item); eprintf ("A = %d\n", (int)a); if (a != 1) { eprintf ("3 FAIL\n"); } r_reg_set_value (reg, item, 0); a = r_reg_get_value (reg, item); eprintf ("A = %d\n", (int)a); if (a != 0) { eprintf ("4 FAIL\n"); } } show_regs (reg, 1); //32); exit (0); show_regs (reg, 32); /* --- */ r_reg_set_profile(reg, "../p/x86-linux.regs"); printf ("Program counter is named: %s\n", r_reg_get_name (reg, R_REG_NAME_PC)); show_regs (reg, 32); r_reg_set_value(reg, r_reg_get(reg, "eax", -1), 0x414141); r_reg_set_value(reg, r_reg_get(reg, "ecx", -1), 666); show_regs(reg, 32); r_reg_set_value(reg, r_reg_get(reg, "al", -1), 0x22); show_regs(reg, 33); r_reg_set_value (reg, r_reg_get (reg, "zero", -1), 0); show_regs (reg, 1); r_reg_set_value (reg, r_reg_get (reg, "zero", -1), 1); show_regs (reg, 1); for (i=0; (type=r_reg_get_type (i));i++) printf (" - %s\n", type); r_reg_arena_push (reg); r_reg_arena_pop (reg); r_reg_arena_push (reg); r_reg_arena_push (reg); r_reg_arena_push (reg); r_reg_arena_pop (reg); r_reg_arena_pop (reg); r_reg_arena_push (reg); r_reg_arena_pop (reg); r_reg_arena_pop (reg); /* r_reg_arena_pop(reg); r_reg_arena_pop(reg); r_reg_arena_pop(reg); r_reg_arena_pop(reg); */ return 0; }
static RList *backtrace_fuzzy(RDebug *dbg, ut64 at) { ut8 *stack, *ptr; int wordsize = dbg->bits; // XXX, dbg->bits is wordsize not bits ut64 sp; RIOBind *bio = &dbg->iob; int i, stacksize; ut64 *p64, addr = 0LL; ut32 *p32; ut16 *p16; ut64 cursp, oldsp; RList *list; stacksize = 1024*512; // 512KB .. should get the size from the regions if possible stack = malloc (stacksize); if (at == UT64_MAX) { RRegItem *ri; RReg *reg = dbg->reg; const char *spname = r_reg_get_name (reg, R_REG_NAME_SP); if (!spname) { eprintf ("Cannot find stack pointer register\n"); free (stack); return NULL; } ri = r_reg_get (reg, spname, R_REG_TYPE_GPR); if (!ri) { eprintf ("Cannot find stack pointer register\n"); free (stack); return NULL; } sp = r_reg_get_value (reg, ri); } else { sp = at; } list = r_list_new (); list->free = free; cursp = oldsp = sp; (void)bio->read_at (bio->io, sp, stack, stacksize); ptr = stack; for (i=0; i<dbg->btdepth; i++) { p64 = (ut64*)ptr; p32 = (ut32*)ptr; p16 = (ut16*)ptr; switch (wordsize) { case 8: addr = *p64; break; case 4: addr = *p32; break; case 2: addr = *p16; break; default: eprintf ("Invalid word size with asm.bits\n"); r_list_free (list); return NULL; } if (iscallret (dbg, addr)) { RDebugFrame *frame = R_NEW0 (RDebugFrame); frame->addr = addr; frame->size = cursp - oldsp; frame->sp = cursp; frame->bp = oldsp; //addr + (i * wordsize); // -4 || -8 // eprintf ("--------------> 0x%llx (%d)\n", addr, frame->size); r_list_append (list, frame); oldsp = cursp; } ptr += wordsize; cursp += wordsize; } return list; }