diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 7c49d681dded5..102c57ca98a3f 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -108,6 +108,40 @@ static REsilMemInterface core_esil_mem_if = { .mem_write = core_esil_mem_write }; +static void core_esil_voyeur_trap_revert_reg_write (void *user, const char *name, + ut64 old, ut64 val) { + RCoreEsil *cesil = user; + if (!(cesil->cfg & R_CORE_ESIL_REVERT)) { + return; + } + if (R_UNLIKELY (!r_strbuf_length (&cesil->trap_revert))) { + r_strbuf_setf (&cesil->trap_revert, "0x%"PFMT64x",%s,:=", old, name); + return; + } + r_strbuf_appendf (&cesil->trap_revert, ",0x%"PFMT64x",%s,:=", old, name); +} + +static void core_esil_voyeur_trap_revert_mem_write (void *user, ut64 addr, + const ut8 *old, const ut8 *buf, int len) { + RCoreEsil *cesil = user; + if (!(cesil->cfg & R_CORE_ESIL_REVERT)) { + return; + } + int i; + if (R_UNLIKELY (!r_strbuf_length (&cesil->trap_revert))) { + r_strbuf_setf (&cesil->trap_revert, "0x%02x,0x%"PFMT64x",=[1]", + *old, addr); + i = 1; + } else { + i = 0; + } + for (;i < len; i++) { + //TODO: optimize this after breaking + r_strbuf_appendf (&cesil->trap_revert, ",0x%02x,0x%"PFMT64x",=[1]", + old[i], addr + i); + } +} + R_API bool r_core_esil_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io, false); core->esil.reg = r_reg_new (); @@ -124,7 +158,12 @@ R_API bool r_core_esil_init(RCore *core) { 0, 0, R_ESIL_OP_TYPE_UNKNOWN)) { goto op_fail; } + r_strbuf_init (&core->esil.trap_revert); core->esil.esil.user = core; + core->esil.tr_reg = r_esil_add_voyeur (&core->esil.esil, &core->esil, + core_esil_voyeur_trap_revert_reg_write, R_ESIL_VOYEUR_REG_WRITE); + core->esil.tr_mem = r_esil_add_voyeur (&core->esil.esil, &core->esil, + core_esil_voyeur_trap_revert_mem_write, R_ESIL_VOYEUR_MEM_WRITE); return true; op_fail: r_esil_fini (&core->esil.esil); @@ -135,7 +174,10 @@ R_API bool r_core_esil_init(RCore *core) { R_API void r_core_esil_fini(RCoreEsil *cesil) { R_RETURN_IF_FAIL (cesil); + r_esil_del_voyeur (&cesil->esil, cesil->tr_reg); + r_esil_del_voyeur (&cesil->esil, cesil->tr_mem); r_esil_fini (&cesil->esil); + r_strbuf_fini (&cesil->trap_revert); if (cesil->reg) { r_reg_free (cesil->reg); cesil->reg = NULL; diff --git a/libr/include/r_core.h b/libr/include/r_core.h index df8456e55eab4..da8a449dd3547 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -304,6 +304,12 @@ typedef struct { typedef struct r_core_esil_t { REsil esil; + union { + RStrBuf trap_revert; + ut64 old_pc; + }; + ut32 tr_reg; + ut32 tr_mem; RReg *reg; char *cmd_step; // command to run before a step is performed char *cmd_step_out; // command to run after a step is performed @@ -318,6 +324,7 @@ typedef struct r_core_esil_t { #define R_CORE_ESIL_RO 0x1 #define R_CORE_ESIL_NONULL 0x2 +#define R_CORE_ESIL_REVERT 0x4 typedef struct RCorePriv RCorePriv; diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 936816dd6a9ec..7103fbdfc24e9 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -162,7 +162,7 @@ typedef struct r_esil_register_interface_t { typedef void (*REsilVoyeurRegRead)(void *user, const char *name, ut64 val); typedef void (*REsilVoyeurRegWrite)(void *user, const char *name, ut64 old, ut64 val); typedef void (*REsilVoyeurMemRead)(void *user, ut64 addr, const ut8 *buf, int len); -typedef void (*REsilVoyeurMemWrite)(void *user, ut64 addr, const ut8 *buf, const ut8 *old, int len); +typedef void (*REsilVoyeurMemWrite)(void *user, ut64 addr, const ut8 *old, const ut8 *buf, int len); typedef struct r_esil_voyeur_t { void *user;