R_API void r_anal_esil_trace (RAnalEsil *esil, RAnalOp *op) { const char *expr = r_strbuf_get (&op->esil); int esil_verbose = esil->verbose; if (ocbs_set) { eprintf ("cannot call recursively\n"); } ocbs = esil->cb; ocbs_set = true; if (!DB) { DB = sdb_new0 (); } sdb_num_set (DB, "idx", esil->trace_idx, 0); sdb_num_set (DB, KEY ("addr"), op->addr, 0); // sdb_set (DB, KEY ("opcode"), op->mnemonic, 0); // sdb_set (DB, KEY ("addr"), expr, 0); //eprintf ("[ESIL] ADDR 0x%08"PFMT64x"\n", op->addr); //eprintf ("[ESIL] OPCODE %s\n", op->mnemonic); //eprintf ("[ESIL] EXPR = %s\n", expr); /* set hooks */ esil->verbose = 0; esil->cb.hook_reg_read = trace_hook_reg_read; esil->cb.hook_reg_write = trace_hook_reg_write; esil->cb.hook_mem_read = trace_hook_mem_read; esil->cb.hook_mem_write = trace_hook_mem_write; /* evaluate esil expression */ r_anal_esil_parse (esil, expr); r_anal_esil_stack_free (esil); /* restore hooks */ esil->cb = ocbs; ocbs_set = false; esil->verbose = esil_verbose; esil->trace_idx ++; }
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; }
R_API int r_debug_esil_stepi (RDebug *d) { RAnalOp op; ut8 obuf[64]; int ret = 1; dbg = d; if (!ESIL) { ESIL = r_anal_esil_new (R_TRUE); // TODO setup something? } r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE); opc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]); dbg->iob.read_at (dbg->iob.io, opc, obuf, sizeof (obuf)); //dbg->iob.read_at (dbg->iob.io, npc, buf, sizeof (buf)); //dbg->anal->reg = dbg->reg; // hack ESIL->cb.hook_mem_read = &esilbreak_mem_read; ESIL->cb.hook_mem_write = &esilbreak_mem_write; ESIL->cb.hook_reg_read = &esilbreak_reg_read; ESIL->cb.hook_reg_write = &esilbreak_reg_write; if (prestep) { // required when a exxpression is like <= == .. // otherwise it will stop at the next instruction if (r_debug_step (dbg, 1)<1) { eprintf ("Step failed\n"); return 0; } r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE); // npc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]); } if (r_anal_op (dbg->anal, &op, opc, obuf, sizeof (obuf))) { if (esilbreak_check_pc (dbg, opc)) { eprintf ("STOP AT 0x%08"PFMT64x"\n", opc); ret = 0; } else { r_anal_esil_set_pc (ESIL, opc); eprintf ("0x%08"PFMT64x" %s\n", opc, R_STRBUF_SAFEGET (&op.esil)); (void)r_anal_esil_parse (ESIL, R_STRBUF_SAFEGET (&op.esil)); //r_anal_esil_dumpstack (ESIL); r_anal_esil_stack_free (ESIL); ret = 1; } } if (!prestep) { if (ret && !has_match) { if (r_debug_step (dbg, 1)<1) { eprintf ("Step failed\n"); return 0; } r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE); // npc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]); } } return ret; }