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); }
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; }
int main (int argc, char **argv) { r_anal_esil_set_pc (core->anal->esil, fcn ? fcn->addr : core->offset); switch (*input) { case '\0': // "aft" { seek = core->offset; r_anal_esil_set_pc (core->anal->esil, fcn ? fcn->addr : core->offset); r_core_anal_type_match (core, fcn); r_core_seek (core, seek, true); break; } case '?': default: r_core_cmd_help (core, help_msg_aft); break; } return 0; }