From 7c37161c2d2362e8d7d2593acaefc7ef63744ae7 Mon Sep 17 00:00:00 2001 From: condret Date: Fri, 4 Apr 2025 03:44:05 +0200 Subject: [PATCH 01/61] Move code from esil_trace refactor to type_trace --- libr/core/anal_tp.c | 508 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 508 insertions(+) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 6824987e8154f..dde890b2af6b3 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -4,6 +4,514 @@ #include #define LOOP_MAX 10 +typedef struct type_trace_change_reg_t { + int idx; + ut32 cc; + char *name; + ut64 data; + ut64 odata; +} TypeTraceRegChange; + +typedef struct type_trace_change_mem_t { + int idx; + ut32 cc; + ut64 addr; + ut8 data; + ut8 odata; +} TypeTraceMemChange; + +typedef struct { + const char *name; + ut64 value; + // TODO: size +} TypeTraceRegAccess; + +typedef struct { + char *data; + ut64 addr; + // TODO: size +} TypeTraceMemoryAccess; + +typedef struct { + union { + TypeTraceRegAccess reg; + TypeTraceMemoryAccess mem; + }; + bool is_write; + bool is_reg; +} TypeTraceAccess; + +typedef struct { + ut64 addr; + ut32 start; + ut32 end; // 1 past the end of the op for this index +} TypeTraceOp; + +static inline void tt_fini_access(TypeTraceAccess *access) { + if (access->is_reg) { + return; + } + free (access->mem.data); +} + +R_VEC_TYPE(VecTraceOp, TypeTraceOp); +R_VEC_TYPE_WITH_FINI(VecAccess, TypeTraceAccess, tt_fini_access); + +typedef struct { + VecTraceOp ops; + VecAccess accesses; + HtUU *loop_counts; +} TypeTraceDB; + +typedef struct type_trace_t { + TypeTraceDB db; + int idx; + ut32 cc; + int end_idx; + int cur_idx; + RReg *reg; + HtUP *registers; + HtUP *memory; + RRegArena *arena[R_REG_TYPE_LAST]; + ut64 stack_addr; + ut64 stack_size; + ut8 *stack_data; +} TypeTrace; + +#define CMP_REG_CHANGE(x, y) ((x) - ((TypeTraceRegChange *)y)->idx) +#define CMP_MEM_CHANGE(x, y) ((x) - ((TypeTraceMemChange *)y)->idx) + +static void update_trace_db_op(TypeTraceDB *db) { + const ut32 trace_op_len = VecTraceOp_length (&db->ops); + if (!trace_op_len) { + return; + } + TypeTraceOp *last = VecTraceOp_at (&db->ops, trace_op_len - 1); + if (!last) { + return; + } + const ut32 vec_idx = VecAccess_length (&db->accesses); + if (!vec_idx) { + R_LOG_ERROR ("Invalid access database"); + return; + } + last->end = vec_idx; // - 1; +} + +static void type_trace_voyeur_reg_read (void *user, const char *name, ut64 val) { + R_RETURN_IF_FAIL (user && name); + char *name_dup = strdup (name); + if (!name_dup) { + R_LOG_ERROR ("Failed to allocate(strdup) memory for storing access"); + return; + } + TypeTraceDB *db = user; + TypeTraceAccess *access = VecAccess_emplace_back (&db->accesses); + if (!access) { + free (name_dup); + R_LOG_ERROR ("Failed to allocate memory for storing access"); + return; + } + access->reg.name = name_dup; + access->reg.value = val; + access->is_reg = true; + access->is_write = false; + update_trace_db_op (db); +} + +static void add_reg_change(TypeTrace *trace, RRegItem *ri, ut64 data, ut64 odata) { + R_RETURN_IF_FAIL (trace && ri); + ut64 addr = ri->offset | (ri->arena << 16); + RVector *vreg = ht_up_find (trace->registers, addr, NULL); + if (R_UNLIKELY (!vreg)) { + vreg = r_vector_new (sizeof (TypeTraceRegChange), NULL, NULL); + if (R_UNLIKELY (!vreg)) { + R_LOG_ERROR ("creating a register vector"); + return; + } + ht_up_insert (trace->registers, addr, vreg); + } + TypeTraceRegChange reg = {trace->cur_idx, trace->cc++, + strdup (ri->name), data, odata}; + r_vector_push (vreg, ®); +} + +static void type_trace_voyeur_reg_write (void *user, const char *name, ut64 old, ut64 val) { + R_RETURN_IF_FAIL (user && name); + TypeTrace *trace = user; + RRegItem *ri = r_reg_get (trace->reg, name, -1); + if (!ri) { + return; + } + char *name_dup = strdup (name); + if (!name_dup) { + R_LOG_ERROR ("Failed to allocate(strdup) memory for storing access"); + goto fail_name_dup; + } + TypeTraceAccess *access = VecAccess_emplace_back (&trace->db.accesses); + if (!access) { + R_LOG_ERROR ("Failed to allocate memory for storing access"); + goto fail_emplace_back; + } + access->is_reg = true; + access->reg.name = name_dup; + access->reg.value = val; + access->is_write = true; + + add_reg_change (trace, ri, val, old); + update_trace_db_op (&trace->db); + r_unref (ri); + return; +fail_emplace_back: + free (name_dup); +fail_name_dup: + r_unref (ri); +} + +static void type_trace_voyeur_mem_read (void *user, ut64 addr, const ut8 *buf, int len) { + R_RETURN_IF_FAIL (user && buf && (len > 0)); + char *hexbuf = r_hex_bin2strdup (buf, len); //why? + if (!hexbuf) { + R_LOG_ERROR ("Failed to allocate(r_hex_bin2strdup) memory for storing access"); + return; + } + TypeTraceDB *db = user; + TypeTraceAccess *access = VecAccess_emplace_back (&db->accesses); + if (!access) { + free (hexbuf); + R_LOG_ERROR ("Failed to allocate memory for storing access"); + return; + } + access->is_reg = false; + access->mem.data = hexbuf; + access->mem.addr = addr; + access->is_write = false; + update_trace_db_op (db); +} + +static void type_trace_voyeur_mem_write (void *user, ut64 addr, const ut8 *old, const ut8 *buf, int len) { + R_RETURN_IF_FAIL (user && buf && (len > 0)); + char *hexbuf = r_hex_bin2strdup (buf, len); //why? + if (!hexbuf) { + R_LOG_ERROR ("Failed to allocate(r_hex_bin2strdup) memory for storing access"); + return; + } + TypeTrace *trace = user; + TypeTraceAccess *access = RVecAccess_emplace_back (&trace->db.accesses); + if (!access) { + free (hexbuf); + R_LOG_ERROR ("Failed to allocate memory for storing access"); + return; + } + access->is_reg = false; + access->mem.data = hexbuf; + access->mem.addr = addr; + access->is_write = true; + ut32 i; + for (i = 0; i < len; i++) { + //adding each byte one by one is utterly stupid, typical gsoc crap + //ideally this would use a tree structure, that splits nodes when necessary + RVector *vmem = ht_up_find (trace->memory, addr, NULL); + if (!vmem) { + vmem = r_vector_new (sizeof (TypeTraceMemChange), NULL, NULL); + if (!vmem) { + R_LOG_ERROR ("creating a memory vector"); + break; + } + ht_up_insert (trace->memory, addr, vmem); + } + TypeTraceMemChange mem = {trace->idx, trace->cc++, addr, buf[i], old[i]}; + r_vector_push (vmem, &mem); + } + update_trace_db_op (&trace->db); +} + +static void htup_vector_free(HtUPKv *kv) { + if (kv) { + r_vector_free (kv->value); + } +} + +static void trace_db_init(TraceDB *db) { + VecTraceOp_init (&db->ops); + VecAccess_init (&db->accesses); + db->loop_counts = ht_uu_new0 (); +} + +static bool type_trace_init(TypeTrace *trace, REsil *esil, RReg *reg, + ut64 stack_addr, ut64 stack_size) { + R_RETURN_VAL_IF_FAIL (trace && esil && reg && stack_size, false); + *trace = (const TypeTrace){0}; + trace_db_init (&trace->db); + trace->registers = ht_up_new (NULL, htup_vector_free, NULL); + if (!trace->registers) { + goto fail_registers_ht; + } + trace->memory = ht_up_new (NULL, htup_vector_free, NULL); + if (!trace->memory) { + goto fail_memory_ht; + } + trace->stack_data = malloc (stack_size); + if (!trace->stack_data) { + goto fail_malloc; + } + if (!r_esil_mem_read_silent (esil, stack_addr, trace->stack_data, stack_size)) { + goto fail_read; + } + ut32 i; + for (i = 0; i < R_REG_TYPE_LAST; i++) { + RRegArena *a = reg->regset[i].arena; + RRegArena *b = r_reg_arena_new (a->size); + if (!b) { + goto fail_regs_copy; + } + if (b->bytes && a->bytes && b->size > 0) { + memcpy (b->bytes, a->bytes, b->size); + } + trace->arena[i] = b; + } + trace->reg = reg; + trace->stack_addr = stack_addr; + trace->stack_size = stack_size; + return true; +fail_regs_copy: + while (i) { + i--; + r_reg_arena_free (trace->arena[i]); + } +fail_read: + R_FREE (trace->stack_data); +fail_malloc: + ht_up_free (trace->memory); + trace->memory = NULL; +fail_memory_ht: + ht_up_free (trace->registers); + trace->registers = NULL; +fail_registers_ht: + return false; +} + +static void type_trace_fini(TypeTrace *trace) { + R_RETURN_IF_FAIL (trace); + VecTraceOp_fini (&trace->db.ops); + VecAccess_fini (&trace->db.accesses); + ht_uu_free (trace->db.loop_counts); + ht_up_free (trace->registers); + ht_up_free (trace->memory); + free (trace->stack_data); + ut32 i; + for (i = 0; i < R_REG_TYPE_LAST; i++) { + r_reg_arena_free (trace->arena[i]); + } + trace[0] = (const TypeTrace){0}; +} + +static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { + R_RETURN_IF_FAIL (trace && esil && op); + const char *expr = r_strbuf_get (&op->esil); + if (R_UNLIKELY (!expr || !strlen (expr))) { + R_LOG_WARN ("expr is empty or null"); + return; + } + trace->cc = 0; + ut32 voy[4]; + voy[R_ESIL_VOYEUR_REG_READ] = r_esil_add_voyeur (esil, &trace->db, + type_trace_voyeur_reg_read, R_ESIL_VOYEUR_REG_READ); + if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_READ] == R_ESIL_VOYEUR_ERR)) { + return; + } + voy[R_ESIL_VOYEUR_REG_WRITE] = r_esil_add_voyeur (esil, trace, + type_trace_voyeur_reg_write, R_ESIL_VOYEUR_REG_WRITE); + if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_WRITE] == R_ESIL_VOYEUR_ERR)) { + goto fail_regw_voy; + } + voy[R_ESIL_VOYEUR_MEM_READ] = r_esil_add_voyeur (esil, &trace->db, + type_trace_voyeur_mem_read, R_ESIL_VOYEUR_MEM_READ); + if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_READ] == R_ESIL_VOYEUR_ERR)) { + goto fail_memr_voy; + } + voy[R_ESIL_VOYEUR_MEM_WRITE] = r_esil_add_voyeur (esil, trace, + type_trace_voyeur_mem_write, R_ESIL_VOYEUR_MEM_WRITE); + if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_WRITE] == R_ESIL_VOYEUR_ERR)) { + goto fail_memw_voy; + } + + RRegItem *ri = r_reg_get (esil->anal->reg, "PC", -1); + if (ri) { + const bool suc = r_esil_reg_write (esil, ri->name, op->addr); + r_unref (ri); + if (!suc) { + goto fail_set_pc; + } + } + + RAnalEsilTraceOp *to = VecTraceOp_emplace_back (&trace->db.ops); + if (R_LIKELY (to)) { + ut32 vec_idx = VecAccess_length (&trace->db.accesses); + to->start = vec_idx; + to->end = vec_idx; + to->addr = op->addr; + } else { + R_LOG_WARN ("Couldn't allocate(emplace_back) trace op"); + //anything to do here? + } + r_esil_parse (esil, expr); + r_esil_stack_free (esil); + trace->idx++; + trace->end_idx++; // should be vector length? +fail_set_pc: + r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_MEM_WRITE]); +fail_memw_voy: + r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_MEM_READ]); +fail_memr_voy: + r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_WRITE]); +fail_regw_voy: + r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_READ]); +} + +static bool count_changes_above_idx_cb (void *user, const ut64 key, const void *val) { + RVector *vec = val; + if (R_UNLIKELY (r_vector_empty (vec))) { + return true; + } + ut64 *v = user; + const int idx = v[0] >> 32; + ut32 count = v[0] & UT32_MAX; + v[0] &= UT64_MAX ^ UT64_MAX; + ut32 i = r_vector_length (vec) - 1; + TypeTraceMemChange *change = r_vector_index_ptr (vec, i); + //idx is guaranteed to be at struct offset 0 for MemChange and RegChange, so this hack is fine + while (change->idx >= idx) { + count++; + if (!i) { + break; + } + i--; + change = r_vector_index_ptr (vec, i); + } + v[0] |= count; + return true; +} + +typedef struct { + int idx; + union { + TypeTraceRegChange *rc_ptr; + TypeTraceMemChange *mc_ptr; + void *data; + }; +} TTChangeCollector; + +static bool collect_reg_changes_cb (void *user, const ut64 key, const void *val) { + RVector *vec = val; + if (R_UNLIKELY (r_vector_empty (vec))) { + return true; + } + TTChangeCollector *cc = user; + ut32 i = r_vector_length (vec) - 1; + TypeTraceRegChange *rc = r_vector_index_ptr (vec, i); + while (rc->idx >= cc->idx) { + r_vector_remove_at (vec, i, cc->rc_ptr); + cc->rc_ptr++; + if (!i) { + return true; + } + i--; + } + return true; +} + +static bool collect_mem_changes_cb (void *user, const ut64 key, const void *val) { + RVector *vec = val; + if (R_UNLIKELY (r_vector_empty (vec))) { + return true; + } + TTChangeCollector *cc = user; + ut32 i = r_vector_length (vec) - 1; + TypeTraceMemChange *rc = r_vector_index_ptr (vec, i); + while (rc->idx >= cc->idx) { + r_vector_remove_at (vec, i, cc->mc_ptr); + cc->mc_ptr++; + if (!i) { + return true; + } + i--; + } + return true; +} + +static int sort_reg_changes_cb (const void *v0, const void *v1) { + const TypeTraceRegChange *a = v0; + const TypeTraceRegChange *b = v1; + if (a->idx == b->idx) { + return (int)b->cc - (int)a->cc; + } + return b->idx - a->idx; +} + +static int sort_mem_changes_cb (const void *v0, const void *v1) { + const TypeTraceMemChange *a = v0; + const TypeTraceMemChange *b = v1; + if (a->idx == b->idx) { + return (int)b->cc - (int)a->cc; + } + return b->idx - a->idx; +} + +static void type_trace_restore(TypeTrace *trace, REsil *esil, int idx) { + R_RETURN_IF_FAIL (trace && esil && (idx < trace->idx)); + ut64 v = ((ut64)idx) << 32; + ht_up_foreach (trace->registers, count_changes_above_idx_cb, &v); + ut32 c_num = v & UT32_MAX; + void *data = NULL; + if (c_num) { + data = R_NEWS (TypeTraceRegChange, c_num); + TTChangeCollector collector = {.idx = idx, .data = data}; + ht_up_foreach (trace->registers, collect_reg_changes_cb, &collector); + //sort collected reg changes so that the newest come first + qsort (data, c_num, sizeof (TypeTraceRegChange), sort_reg_changes_cb); + collector.data = data; + ut32 i = 0; + for (; i < c_num; i++) { + r_esil_reg_write_silent (esil, collector.rc_ptr[i].name, collector.rc_ptr[i].odata); + R_FREE (collector.rc_ptr[i].name); + } + } + v &= UT64_MAX ^ UT32_MAX; + ht_up_foreach (trace->memory, count_changes_above_idx_cb, &v); + if (data && (((v & UT32_MAX) * sizeof (TypeTraceMemChange)) > + (c_num * sizeof (TypeTraceRegChange)))) { + c_num = v & UT32_MAX; + void *new_data = realloc (data, sizeof (TypeTraceMemChange) * c_num); + if (!new_data) { + free (data); + return; + } + data = new_data; + } else { + c_num = v & UT32_MAX; + } + if (!c_num) { + free (data); + return; + } + if (R_UNLIKELY (!data)) { + data = R_NEWS (TypeTraceMemChange, c_num); + if (!data) { + return; + } + } + ChangeCollector collector = {.idx = idx, .data = data}; + ht_up_foreach (trace->memory, collect_mem_changes_cb, &collector); + //sort collected mem changes so that the newest come first + qsort (data, c_num, sizeof (TypeTraceMemChange), sort_mem_changes_cb); + collector.data = data; + ut32 i = 0; + for (;i < c_num; i++) { + r_esil_mem_write_silent (esil, collector.mc_ptr[i].addr, &collector.rc_ptr[i].odata, 1); + } +} + R_VEC_TYPE (RVecUT64, ut64); R_VEC_TYPE (RVecBuf, ut8); From 9fa53cea54b78b1b8a84eff303b0d0922d497dd3 Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 22 Apr 2025 02:36:44 +0200 Subject: [PATCH 02/61] bvhjik --- libr/core/anal_tp.c | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index dde890b2af6b3..6a337bd065580 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -197,7 +197,7 @@ static void type_trace_voyeur_mem_write (void *user, ut64 addr, const ut8 *old, return; } TypeTrace *trace = user; - TypeTraceAccess *access = RVecAccess_emplace_back (&trace->db.accesses); + TypeTraceAccess *access = VecAccess_emplace_back (&trace->db.accesses); if (!access) { free (hexbuf); R_LOG_ERROR ("Failed to allocate memory for storing access"); @@ -501,7 +501,7 @@ static void type_trace_restore(TypeTrace *trace, REsil *esil, int idx) { return; } } - ChangeCollector collector = {.idx = idx, .data = data}; + TTChangeCollector collector = {.idx = idx, .data = data}; ht_up_foreach (trace->memory, collect_mem_changes_cb, &collector); //sort collected mem changes so that the newest come first qsort (data, c_num, sizeof (TypeTraceMemChange), sort_mem_changes_cb); @@ -528,23 +528,23 @@ typedef struct { /// BEGIN /////////////////// esil trace helpers /////////////////////// -static int etrace_index(REsilTrace *etrace) { - int len = RVecTraceOp_length (&etrace->db.ops); +static int etrace_index(TypeTrace *etrace) { + int len = VecTraceOp_length (&etrace->db.ops); etrace->cur_idx = len; // > 0? len -1: 0; - return etrace->cur_idx; // RVecTraceOp_length (&etrace->db.ops); + return etrace->cur_idx; // VecTraceOp_length (&etrace->db.ops); } -static ut64 etrace_addrof(REsilTrace *etrace, ut32 idx) { - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); +static ut64 etrace_addrof(TypeTrace *etrace, ut32 idx) { + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); return op? op->addr: 0; } -static ut64 etrace_memwrite_addr(REsilTrace *etrace, ut32 idx) { - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); +static ut64 etrace_memwrite_addr(TypeTrace *etrace, ut32 idx) { + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); R_LOG_DEBUG ("memwrite %d %d", etrace->idx, idx); if (op && op->start != op->end) { - REsilTraceAccess *start = RVecAccess_at (&etrace->db.accesses, op->start); - REsilTraceAccess *end = RVecAccess_at (&etrace->db.accesses, op->end - 1); + TypeTraceAccess *start = VecAccess_at (&etrace->db.accesses, op->start); + TypeTraceAccess *end = VecAccess_at (&etrace->db.accesses, op->end - 1); while (start <= end) { if (!start->is_reg && start->is_write) { return start->mem.addr; @@ -556,11 +556,11 @@ static ut64 etrace_memwrite_addr(REsilTrace *etrace, ut32 idx) { } static bool etrace_have_memread(REsilTrace *etrace, ut32 idx) { - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); R_LOG_DEBUG ("memread %d %d", etrace->idx, idx); if (op && op->start != op->end) { - REsilTraceAccess *start = RVecAccess_at (&etrace->db.accesses, op->start); - REsilTraceAccess *end = RVecAccess_at (&etrace->db.accesses, op->end - 1); + TypeTraceAccess *start = VecAccess_at (&etrace->db.accesses, op->start); + TypeTraceAccess *end = VecAccess_at (&etrace->db.accesses, op->end - 1); while (start <= end) { if (!start->is_reg && !start->is_write) { return true; @@ -573,10 +573,10 @@ static bool etrace_have_memread(REsilTrace *etrace, ut32 idx) { static ut64 etrace_regread_value(REsilTrace *etrace, ut32 idx, const char *rname) { R_LOG_DEBUG ("regread %d %d", etrace->idx, idx); - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); if (op && op->start != op->end) { - REsilTraceAccess *start = RVecAccess_at (&etrace->db.accesses, op->start); - REsilTraceAccess *end = RVecAccess_at (&etrace->db.accesses, op->end - 1); + TypeTraceAccess *start = VecAccess_at (&etrace->db.accesses, op->start); + TypeTraceAccess *end = VecAccess_at (&etrace->db.accesses, op->end - 1); while (start <= end) { if (start->is_reg && !start->is_write) { if (!strcmp (rname, start->reg.name)) { @@ -591,10 +591,10 @@ static ut64 etrace_regread_value(REsilTrace *etrace, ut32 idx, const char *rname static const char *etrace_regwrite(REsilTrace *etrace, ut32 idx) { R_LOG_DEBUG ("regwrite %d %d", etrace->idx, idx); - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); if (op && op->start != op->end) { - REsilTraceAccess *start = RVecAccess_at (&etrace->db.accesses, op->start); - REsilTraceAccess *end = RVecAccess_at (&etrace->db.accesses, op->end - 1); + TypeTraceAccess *start = VecAccess_at (&etrace->db.accesses, op->start); + TypeTraceAccess *end = VecAccess_at (&etrace->db.accesses, op->end - 1); while (start <= end) { if (start->is_reg && start->is_write) { return start->reg.name; @@ -610,10 +610,10 @@ static const char *etrace_regwrite(REsilTrace *etrace, ut32 idx) { static bool etrace_regwrite_contains(REsilTrace *etrace, ut32 idx, const char *rname) { R_LOG_DEBUG ("regwrite contains %d %s", idx, rname); R_RETURN_VAL_IF_FAIL (etrace && rname, false); - REsilTraceOp *op = RVecTraceOp_at (&etrace->db.ops, idx); // AAA + 1); + TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); // AAA + 1); if (op && op->start != op->end) { - REsilTraceAccess *start = RVecAccess_at (&etrace->db.accesses, op->start); - REsilTraceAccess *end = RVecAccess_at (&etrace->db.accesses, op->end - 1); + TypeTraceAccess *start = VecAccess_at (&etrace->db.accesses, op->start); + TypeTraceAccess *end = VecAccess_at (&etrace->db.accesses, op->end - 1); while (start <= end) { if (start->is_reg && start->is_write) { if (!strcmp (rname, start->reg.name)) { From 0c05247451421c11ccb4aa23fccfa92c4d3c708d Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 22 Apr 2025 04:15:31 +0200 Subject: [PATCH 03/61] 56ftgyhuji --- libr/core/anal_tp.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 6a337bd065580..aa91b2c58e0b9 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -91,7 +91,6 @@ static void update_trace_db_op(TypeTraceDB *db) { return; } const ut32 vec_idx = VecAccess_length (&db->accesses); - if (!vec_idx) { R_LOG_ERROR ("Invalid access database"); return; } @@ -518,8 +517,10 @@ R_VEC_TYPE (RVecBuf, ut8); typedef struct { RCore *core; RAnal *anal; - REsilTrace *et; - REsilTrace *_et; + int stack_fd; + ut32 stack_map; + ut64 stack_base; + TypeTrace *et; RConfigHold *hc; char *cfg_spec; bool cfg_breakoninvalid; @@ -555,7 +556,7 @@ static ut64 etrace_memwrite_addr(TypeTrace *etrace, ut32 idx) { return 0; } -static bool etrace_have_memread(REsilTrace *etrace, ut32 idx) { +static bool etrace_have_memread(TypeTrace *etrace, ut32 idx) { TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); R_LOG_DEBUG ("memread %d %d", etrace->idx, idx); if (op && op->start != op->end) { @@ -571,7 +572,7 @@ static bool etrace_have_memread(REsilTrace *etrace, ut32 idx) { return false; } -static ut64 etrace_regread_value(REsilTrace *etrace, ut32 idx, const char *rname) { +static ut64 etrace_regread_value(TypeTrace *etrace, ut32 idx, const char *rname) { R_LOG_DEBUG ("regread %d %d", etrace->idx, idx); TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); if (op && op->start != op->end) { @@ -589,7 +590,7 @@ static ut64 etrace_regread_value(REsilTrace *etrace, ut32 idx, const char *rname return 0; } -static const char *etrace_regwrite(REsilTrace *etrace, ut32 idx) { +static const char *etrace_regwrite(TypeTrace *etrace, ut32 idx) { R_LOG_DEBUG ("regwrite %d %d", etrace->idx, idx); TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); if (op && op->start != op->end) { @@ -607,7 +608,7 @@ static const char *etrace_regwrite(REsilTrace *etrace, ut32 idx) { /// END ///////////////////// esil trace helpers /////////////////////// -static bool etrace_regwrite_contains(REsilTrace *etrace, ut32 idx, const char *rname) { +static bool etrace_regwrite_contains(TypeTrace *etrace, ut32 idx, const char *rname) { R_LOG_DEBUG ("regwrite contains %d %s", idx, rname); R_RETURN_VAL_IF_FAIL (etrace && rname, false); TypeTraceOp *op = VecTraceOp_at (&etrace->db.ops, idx); // AAA + 1); @@ -765,7 +766,7 @@ static void get_src_regname(RCore *core, ut64 addr, char *regname, int size) { r_anal_op_free (op); } -static ut64 get_addr(REsilTrace *et, const char *regname, int idx) { +static ut64 get_addr(TypeTrace *et, const char *regname, int idx) { if (R_STR_ISEMPTY (regname)) { return 0; } @@ -886,7 +887,7 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons int prev_idx, bool userfnc, ut64 caddr) { RAnal *anal = tps->core->anal; RCons *cons = tps->core->cons; - REsilTrace *et= tps->et; + REsilTrace *et = tps->et; Sdb *TDB = anal->sdb_types; const int idx = etrace_index (et) -1; const bool verbose = r_config_get_b (tps->core->config, "anal.types.verbose"); // XXX @@ -1087,9 +1088,21 @@ static TPState *tps_init(RCore *core) { TPState *tps = R_NEW0 (TPState); RConfig *cfg = core->config; tps->core = core; - tps->hc = r_config_hold_new (cfg); // tps->_dt = core->dbg->trace; - tps->_et = core->anal->esil->trace; + int align = r_arch_info (core->anal->arch, R_ARCH_INFO_DATA_ALIGN); + align = R_MAX (r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN), align); + align = R_MAX (align, 1); + tps->stack_base = r_config_get_i (core->config, "esil.stack.addr"); + ut64 stack_size = r_config_get_i (core->config, "esil.stack.size"); + //ideally this all would happen in a dedicated temporal io bank + if (!r_io_map_locate (core->io, &tps->stack_base, stack_size, align)) { + free (tps); + return NULL; + } + char *uri = r_str_newf ("malloc://0x%"PFMT64x, stack_size); + tps->stack_fd = r_io_fd_open (core->io, uri, R_PERM_RW, 0); + tps->stack_map = r_io_map_add (core->io, tps->stack_fd, R_PERM_RW, 0, tps->stack_base, stack_size)->id; + tps->hc = r_config_hold_new (cfg); tps->cfg_spec = strdup (r_config_get (cfg, "anal.types.spec")); tps->cfg_breakoninvalid = r_config_get_b (cfg, "esil.breakoninvalid"); tps->cfg_chk_constraint = r_config_get_b (cfg, "anal.types.constraint"); @@ -1169,7 +1182,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } int i, j; r_config_set_b (core->config, "dbg.trace.eval", false); - REsilTrace *etrace = tps->et; + TypeTrace *etrace = tps->et; for (j = 0; j < bblist_size; j++) { const ut64 bbat = *RVecUT64_at (&bblist, j); bb = r_anal_get_block_at (core->anal, bbat); From 3f3823e508d02e2d8e3b01361465a3c552e37332 Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 23 Apr 2025 04:03:18 +0200 Subject: [PATCH 04/61] Stack map setup + esil interfaces for type trace --- libr/core/anal_tp.c | 87 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index aa91b2c58e0b9..02b202301ce37 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -515,6 +515,7 @@ R_VEC_TYPE (RVecUT64, ut64); R_VEC_TYPE (RVecBuf, ut8); typedef struct { + REsil esil; RCore *core; RAnal *anal; int stack_fd; @@ -1078,13 +1079,74 @@ static void tps_fini(TPState *tps) { free (tps->cfg_spec); r_config_hold_restore (tps->hc); r_config_hold_free (tps->hc); - r_esil_trace_free (tps->et); - tps->core->anal->esil->trace = tps->_et; +// r_esil_trace_free (tps->et); +// tps->core->anal->esil->trace = tps->_et; free (tps); } +static bool tt_is_reg(void *reg, const char *name) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return false; + } + r_unref (ri); + return true; +} + +static bool tt_reg_read(void *reg, const char *name, ut64 *val) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return false; + } + *val = r_reg_get_value ((RReg *)reg, ri); + r_unref (ri); + return true; +} + +static ut32 tt_reg_size(void *reg, const char *name) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return 0; + } + r_unref (ri); + return ri->size; +} + +static REsilRegInterface type_trace_reg_if = { + .is_reg = tt_is_reg, + .reg_read = tt_reg_read, + .reg_write = (REsilRegWrite)r_reg_setv, + .reg_size = tt_reg_size, + // .reg_alias = default_reg_alias +}; + +static bool tt_mem_read (void *mem, ut64 addr, ut8 *buf, int len) { + TPState *tps = (TPState *)mem; + return r_io_read_at (tps->core->io, addr, buf, len); +} + +// ensures type trace esil engine only writes to it's designated stack map. +// writes outside of that itv will be assumed as valid and return true. +// this function assumes, that stack map has highest priority, +// or does not overlap with any other map. +static bool tt_mem_write (void *mem, ut64 addr, const ut8 *buf, int len) { + TPState *tps = (TPState *)mem; + RIOMap *map = r_io_map_get (tps->core->io, tps->stack_map); + RInterval itv = {addr, len}; + if (!r_itv_overlap (map->itv, itv)) { + return true; + } + itv = r_itv_intersect (map->itv, itv); + return r_io_write_at (tps->core->io, itv.addr, &buf[itv.addr - addr], (int)itv.size); +} + +static REsilMemInterface type_trace_mem_if = { + .mem_read = tt_mem_read, + .mem_write = tt_mem_write +}; + static TPState *tps_init(RCore *core) { - R_RETURN_VAL_IF_FAIL (core && core->anal && core->anal->esil, NULL); + R_RETURN_VAL_IF_FAIL (core && core->io && core->anal && core->anal->esil, NULL); TPState *tps = R_NEW0 (TPState); RConfig *cfg = core->config; tps->core = core; @@ -1100,15 +1162,30 @@ static TPState *tps_init(RCore *core) { return NULL; } char *uri = r_str_newf ("malloc://0x%"PFMT64x, stack_size); + if (!uri) { + free (tps); + return NULL; + } tps->stack_fd = r_io_fd_open (core->io, uri, R_PERM_RW, 0); - tps->stack_map = r_io_map_add (core->io, tps->stack_fd, R_PERM_RW, 0, tps->stack_base, stack_size)->id; + free (uri); + RIOMap *map = r_io_map_add (core->io, tps->stack_fd, R_PERM_RW, 0, tps->stack_base, stack_size); + if (!map) { + r_io_fd_close (core->io, tps->stack_fd); + free (tps); + return NULL; + } + tps->stack_map = map->id; + //todo fix addrsize + type_trace_reg_if.reg = core->anal->reg; + type_trace_mem_if.mem = tps; + r_esil_init (&tps->esil, 4096, false, 64, &type_trace_reg_if, &type_trace_mem_if); tps->hc = r_config_hold_new (cfg); tps->cfg_spec = strdup (r_config_get (cfg, "anal.types.spec")); tps->cfg_breakoninvalid = r_config_get_b (cfg, "esil.breakoninvalid"); tps->cfg_chk_constraint = r_config_get_b (cfg, "anal.types.constraint"); tps->et = r_esil_trace_new (core->anal->esil); // tps->dt = r_debug_trace_new (); - core->anal->esil->trace = tps->et; + //core->anal->esil->trace = tps->et; // core->dbg->trace = tps->dt; r_config_hold (tps->hc, "esil.romem", "esil.nonull", "dbg.follow", NULL); r_config_set_b (cfg, "esil.romem", true); From b2e9f72602c7856cfb8ae7e67c584a5bec0fec5d Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 24 Apr 2025 14:25:12 +0200 Subject: [PATCH 05/61] Finish refactoring tps_{init/fini} for now --- libr/core/anal_tp.c | 53 ++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 02b202301ce37..5ca0f2ebe24ac 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -516,12 +516,13 @@ R_VEC_TYPE (RVecBuf, ut8); typedef struct { REsil esil; + TypeTrace tt; + ut64 stack_base; + ut64 sp; //old sp + ut64 bp; //old bp RCore *core; - RAnal *anal; int stack_fd; ut32 stack_map; - ut64 stack_base; - TypeTrace *et; RConfigHold *hc; char *cfg_spec; bool cfg_breakoninvalid; @@ -1076,11 +1077,14 @@ static int bb_cmpaddr(const void *_a, const void *_b) { static void tps_fini(TPState *tps) { R_RETURN_IF_FAIL (tps); + type_trace_fini (&tps->tt); + r_esil_fini (&tps->esil); + r_io_fd_close (tps->core->io, tps->stack_fd); + r_reg_setv (core->anal->reg, "SP", tps->sp); + r_reg_setv (core->anal->reg, "BP", tps->bp); free (tps->cfg_spec); r_config_hold_restore (tps->hc); r_config_hold_free (tps->hc); -// r_esil_trace_free (tps->et); -// tps->core->anal->esil->trace = tps->_et; free (tps); } @@ -1145,12 +1149,12 @@ static REsilMemInterface type_trace_mem_if = { .mem_write = tt_mem_write }; +//XXX: this name is wrong static TPState *tps_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io && core->anal && core->anal->esil, NULL); TPState *tps = R_NEW0 (TPState); RConfig *cfg = core->config; tps->core = core; - // tps->_dt = core->dbg->trace; int align = r_arch_info (core->anal->arch, R_ARCH_INFO_DATA_ALIGN); align = R_MAX (r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN), align); align = R_MAX (align, 1); @@ -1171,6 +1175,7 @@ static TPState *tps_init(RCore *core) { RIOMap *map = r_io_map_add (core->io, tps->stack_fd, R_PERM_RW, 0, tps->stack_base, stack_size); if (!map) { r_io_fd_close (core->io, tps->stack_fd); + r_reg_free (tps->reg); free (tps); return NULL; } @@ -1178,25 +1183,33 @@ static TPState *tps_init(RCore *core) { //todo fix addrsize type_trace_reg_if.reg = core->anal->reg; type_trace_mem_if.mem = tps; - r_esil_init (&tps->esil, 4096, false, 64, &type_trace_reg_if, &type_trace_mem_if); + ut64 sp = tps->stack_base + stack_size - (stack_size % align) - align * 8; + //todo: this probably needs some boundary checks + tps->sp = r_reg_getv (core->anal->reg, "SP"); + tps->bp = r_reg_getv (core->anal->reg, "BP"); + r_reg_setv (core->anal->reg, "SP", sp); + r_reg_setv (core->anal->reg, "BP", sp); + if (!r_esil_init (&tps->esil, 4096, false, 64, &type_trace_reg_if, &type_trace_mem_if)) { + r_reg_setv (core->anal->reg, "SP", tps->sp); + r_reg_setv (core->anal->reg, "BP", tps->bp); + r_io_fd_close (core->io, tps->stack_fd); + free (tps); + return NULL; + } + if (!type_trace_init (&tps->tt, &tps->esil, tps->reg, sp, sp - tps->stack_base)) { + r_esil_fini (&tps->esil); + r_reg_setv (core->anal->reg, "SP", tps->sp); + r_reg_setv (core->anal->reg, "BP", tps->bp); + r_io_fd_close (core->io, tps->stack_fd); + free (tps); + return NULL; + } tps->hc = r_config_hold_new (cfg); tps->cfg_spec = strdup (r_config_get (cfg, "anal.types.spec")); tps->cfg_breakoninvalid = r_config_get_b (cfg, "esil.breakoninvalid"); tps->cfg_chk_constraint = r_config_get_b (cfg, "anal.types.constraint"); - tps->et = r_esil_trace_new (core->anal->esil); - // tps->dt = r_debug_trace_new (); - //core->anal->esil->trace = tps->et; - // core->dbg->trace = tps->dt; - r_config_hold (tps->hc, "esil.romem", "esil.nonull", "dbg.follow", NULL); - r_config_set_b (cfg, "esil.romem", true); - r_config_set_b (cfg, "esil.nonull", true); + r_config_hold (tps->hc, "dbg.follow", NULL); r_config_set_i (cfg, "dbg.follow", 0); - RReg *reg = core->anal->reg; - if (!r_reg_getv (reg, "BP") && !r_reg_getv (reg, "SP")) { - R_LOG_WARN ("The virtual stack is not yet available. Run aeim or aei and try again"); - tps_fini (tps); - return NULL; - } return tps; } From e3e72a6f96ce1cbc95affd0e4758251220325c9d Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 24 Apr 2025 14:36:19 +0200 Subject: [PATCH 06/61] Some more refactoring --- libr/core/anal_tp.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 5ca0f2ebe24ac..56d0f34eb1e76 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -457,6 +457,7 @@ static int sort_mem_changes_cb (const void *v0, const void *v1) { return b->idx - a->idx; } +#if 0 static void type_trace_restore(TypeTrace *trace, REsil *esil, int idx) { R_RETURN_IF_FAIL (trace && esil && (idx < trace->idx)); ut64 v = ((ut64)idx) << 32; @@ -510,6 +511,7 @@ static void type_trace_restore(TypeTrace *trace, REsil *esil, int idx) { r_esil_mem_write_silent (esil, collector.mc_ptr[i].addr, &collector.rc_ptr[i].odata, 1); } } +#endif R_VEC_TYPE (RVecUT64, ut64); R_VEC_TYPE (RVecBuf, ut8); @@ -633,10 +635,10 @@ static bool type_pos_hit(TPState *tps, bool in_stack, int idx, int size, const c R_LOG_DEBUG ("Type pos hit %d %d %d %s", in_stack, idx, size, place); if (in_stack) { ut64 sp = r_reg_getv (tps->core->anal->reg, "SP"); // XXX this is slow too and we can cache - const ut64 write_addr = etrace_memwrite_addr (tps->et, idx); // AAA -1 + const ut64 write_addr = etrace_memwrite_addr (&tps->tt, idx); // AAA -1 return (write_addr == sp + size); } - return place && etrace_regwrite_contains (tps->et, idx, place); + return place && etrace_regwrite_contains (&tps->tt, idx, place); } static void var_rename(RAnal *anal, RAnalVar *v, const char *name, ut64 addr) { @@ -1239,7 +1241,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { dtrace->ht = ht_pp_new_size (fcn->ninstr, opt.dupvalue, opt.freefn, opt.calcsizeV); dtrace->ht->opt = opt; - tps->et->cur_idx = 0; + tps->tt.cur_idx = 0; const bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (core->rasm->config); char *fcn_name = NULL; char *ret_type = NULL; @@ -1272,7 +1274,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } int i, j; r_config_set_b (core->config, "dbg.trace.eval", false); - TypeTrace *etrace = tps->et; + TypeTrace *etrace = &tps->tt; for (j = 0; j < bblist_size; j++) { const ut64 bbat = *RVecUT64_at (&bblist, j); bb = r_anal_get_block_at (core->anal, bbat); @@ -1354,7 +1356,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { if (cur_idx < 0) { cur_idx = 0; } - tps->et->cur_idx = etrace_index (etrace); + tps->tt.cur_idx = etrace_index (etrace); RAnalVar *var = r_anal_get_used_function_var (anal, aop.addr); // XXX this is analyzing the same op twice wtf this is so wrong @@ -1406,7 +1408,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { if (Cc && r_anal_cc_exist (anal, Cc)) { char *cc = strdup (Cc); type_match (tps, fcn_name, addr, bb->addr, cc, prev_idx, userfnc, callee_addr); - // prev_idx = tps->et->cur_idx; + // prev_idx = tps->tt.cur_idx; prev_idx = tps->core->anal->esil->trace->cur_idx; R_FREE (ret_type); const char *rt = r_type_func_ret (TDB, fcn_name); @@ -1424,7 +1426,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { if (!strcmp (fcn_name, "__stack_chk_fail")) { // r_strf_var (query, 32, "%d.addr", cur_idx - 1); // ut64 mov_addr = sdb_num_get (trace, query, 0); - // cur_idx = tps->et->cur_idx - 2; + // cur_idx = tps->tt.cur_idx - 2; cur_idx = tps->core->anal->esil->trace->cur_idx - 2; // eprintf (Color_GREEN"ADDROF %d\n"Color_RESET, cur_idx); ut64 mov_addr = etrace_addrof (etrace, cur_idx); @@ -1446,7 +1448,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { // r_strf_var (query, 32, "%d.reg.write", cur_idx); // const char *cur_dest = sdb_const_get (trace, query, 0); // sdb_const_get (trace, query, 0); - // cur_idx = tps->et->cur_idx - 1; + // cur_idx = tps->tt.cur_idx - 1; cur_idx = tps->core->anal->esil->trace->cur_idx - 1; const char *cur_dest = etrace_regwrite (etrace, cur_idx); get_src_regname (core, aop.addr, src, sizeof (src)); From 96f93fed3cf935fbd5c2fbeee7df333b4a82ec17 Mon Sep 17 00:00:00 2001 From: condret Date: Fri, 25 Apr 2025 23:56:59 +0200 Subject: [PATCH 07/61] Add missing LOC --- libr/core/anal_tp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 56d0f34eb1e76..6e3599d4fdd13 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -91,6 +91,7 @@ static void update_trace_db_op(TypeTraceDB *db) { return; } const ut32 vec_idx = VecAccess_length (&db->accesses); + if (!vec_idx) { R_LOG_ERROR ("Invalid access database"); return; } From 5393ca0a07218ad12f29250ce1adbbb08ba59904 Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 26 Apr 2025 00:26:57 +0200 Subject: [PATCH 08/61] wooooops --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 6e3599d4fdd13..0a8e14ce72991 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -232,7 +232,7 @@ static void htup_vector_free(HtUPKv *kv) { } } -static void trace_db_init(TraceDB *db) { +static void trace_db_init(TypeTraceDB *db) { VecTraceOp_init (&db->ops); VecAccess_init (&db->accesses); db->loop_counts = ht_uu_new0 (); From a0f9d8ab3a7698b9d0bce18123c68c7ac99945f8 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 04:21:42 +0200 Subject: [PATCH 09/61] Add type_trace_loopcount functions --- libr/core/anal_tp.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 0a8e14ce72991..f084452fd3674 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -291,6 +291,17 @@ static bool type_trace_init(TypeTrace *trace, REsil *esil, RReg *reg, return false; } +static ut64 type_trace_loopcount(TypeTrace *trace, ut64 addr) { + bool found = false; + const ut64 count = ht_uu_find (trace->db.loop_counts, addr, &found); + return found? count: 0; +} + +static void type_trace_loopcount_increment(TypeTrace *trace, ut64 addr) { + const ut64 count = type_trace_loopcount (trace, addr); + ht_uu_update (trace->db.loop_counts, addr, count + 1); +} + static void type_trace_fini(TypeTrace *trace) { R_RETURN_IF_FAIL (trace); VecTraceOp_fini (&trace->db.ops); @@ -1075,7 +1086,7 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons static int bb_cmpaddr(const void *_a, const void *_b) { const RAnalBlock *a = _a, *b = _b; - return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0); + return a->addr > b->addr? 1: (a->addr < b->addr? -1: 0); } static void tps_fini(TPState *tps) { @@ -1320,14 +1331,14 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { r_anal_op_fini (&aop); continue; } - const int loop_count = r_esil_trace_loopcount (etrace, addr); + const int loop_count = type_trace_loopcount (etrace, addr); #if 1 if (loop_count > LOOP_MAX || aop.type == R_ANAL_OP_TYPE_RET) { r_anal_op_fini (&aop); break; } #endif - r_esil_trace_loopcount_increment (etrace, addr); + type_trace_loopcount_increment (etrace, addr); if (r_anal_op_nonlinear (aop.type)) { // skip jmp/cjmp/trap/ret/call ops // eprintf ("%x nonlinear\n", pcval); r_reg_setv (core->dbg->reg, "PC", addr + aop.size); From 41016b2a7e44100c3954ed49e0008a3040ec3a53 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 05:32:24 +0200 Subject: [PATCH 10/61] Avoid use of r_core_esil_step in type_trace --- libr/core/anal_tp.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index f084452fd3674..6d0fe0dd1648e 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1231,7 +1231,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { R_RETURN_IF_FAIL (core && core->anal && fcn); // const int op_tions = R_ARCH_OP_MASK_BASIC ;//| R_ARCH_OP_MASK_VAL | R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT; - const int op_tions = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_HINT; + const int op_tions = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_HINT | R_ARCH_OP_MASK_ESIL; RAnalBlock *bb; RListIter *it; RAnalOp aop = {0}; @@ -1246,12 +1246,6 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { if (!tps) { return; } - // TODO: maybe move into tps - RDebugTrace *dtrace = core->dbg->trace; // tps->dt; // core->dbg->trace; - HtPPOptions opt = dtrace->ht->opt; - ht_pp_free (dtrace->ht); - dtrace->ht = ht_pp_new_size (fcn->ninstr, opt.dupvalue, opt.freefn, opt.calcsizeV); - dtrace->ht->opt = opt; tps->tt.cur_idx = 0; const bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (core->rasm->config); @@ -1285,7 +1279,6 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { RVecUT64_push_back (&bblist, &bb->addr); } int i, j; - r_config_set_b (core->config, "dbg.trace.eval", false); TypeTrace *etrace = &tps->tt; for (j = 0; j < bblist_size; j++) { const ut64 bbat = *RVecUT64_at (&bblist, j); @@ -1312,22 +1305,17 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } // XXX fail sometimes /// addr = bb_addr + i; - r_reg_setv (core->dbg->reg, "PC", addr); + r_reg_setv (core->anal->reg, "PC", addr); ut64 bb_left = bb_size - i; if ((addr >= bb_addr + bb_size) || (addr < bb_addr)) { // stop emulating this bb if pc is outside the basic block boundaries break; } - if (0&&next_op->addr == addr) { - memcpy (&aop, next_op, sizeof (aop)); - ret = next_op->size; - } else { - ret = r_anal_op (anal, &aop, addr, buf_ptr + i, bb_left, op_tions); - } + ret = r_anal_op (anal, &aop, addr, buf_ptr + i, bb_left, op_tions); if (ret <= 0) { i += minopcode; addr += minopcode; - r_reg_setv (core->dbg->reg, "PC", addr); + r_reg_setv (core->anal->reg, "PC", addr); r_anal_op_fini (&aop); continue; } @@ -1339,18 +1327,26 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } #endif type_trace_loopcount_increment (etrace, addr); - if (r_anal_op_nonlinear (aop.type)) { // skip jmp/cjmp/trap/ret/call ops - // eprintf ("%x nonlinear\n", pcval); - r_reg_setv (core->dbg->reg, "PC", addr + aop.size); - } else { - // eprintf ("STEP 0x%"PFMT64x"\n", addr); - int res = r_core_esil_step (core, UT64_MAX, NULL, NULL, false); - if (tps->cfg_breakoninvalid && !res) { + r_reg_setv (core->anal->reg, "PC", addr + aop.size); + if (!r_anal_op_nonlinear (aop.type)) { // skip jmp/cjmp/trap/ret/call ops +//this shit probably needs further refactoring. i hate this code + if (aop.type == R_ANAL_OP_TYPE_ILL || aop.type == R_ANAL_OP_TYPE_UNK) { + if (tps->cfg_breakoninvalid) { + R_LOG_ERROR ("step failed at 0x%08"PFMT64x, addr); + r_anal_op_fini (&aop); + retries = -1; + goto repeat; + } + goto bla; + } + char *expr = r_strbuf_drain_nofree (&op.esil); + if ((!expr || !r_esil_parse (&tps->esil, expr)) && tps->cfg_breakoninvalid) { R_LOG_ERROR ("step failed at 0x%08"PFMT64x, addr); retries--; goto repeat; } } +bla: #if 1 // XXX this code looks wrong and slow maybe is not needed // maybe the basic block is gone after the step @@ -1603,7 +1599,6 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } } R_FREE (next_op); - r_config_set_b (core->config, "dbg.trace.eval", true); RVecBuf_fini (&buf); RVecUT64_fini (&bblist); From fb60597f4692d342c2a782ee23ef6ff307c80e25 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 05:39:30 +0200 Subject: [PATCH 11/61] Use type_trace_op instead of r_esil_parse in type propagation --- libr/core/anal_tp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 6d0fe0dd1648e..9903719662337 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1339,8 +1339,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } goto bla; } - char *expr = r_strbuf_drain_nofree (&op.esil); - if ((!expr || !r_esil_parse (&tps->esil, expr)) && tps->cfg_breakoninvalid) { + if ((type_trace_op (etrace, &tps->esil, &aop)) && tps->cfg_breakoninvalid) { R_LOG_ERROR ("step failed at 0x%08"PFMT64x, addr); retries--; goto repeat; From c0980d52612e381dd045fbac66e0058d600cdfc3 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 05:42:36 +0200 Subject: [PATCH 12/61] blub --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 9903719662337..46b655eb06bf3 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -356,7 +356,7 @@ static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { } } - RAnalEsilTraceOp *to = VecTraceOp_emplace_back (&trace->db.ops); + TypeTraceOp *to = VecTraceOp_emplace_back (&trace->db.ops); if (R_LIKELY (to)) { ut32 vec_idx = VecAccess_length (&trace->db.accesses); to->start = vec_idx; From f467545d09aedd392614132d36df1aa0fa8d5e8a Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 05:59:36 +0200 Subject: [PATCH 13/61] tyfvguhbjnkm --- libr/core/anal_tp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 46b655eb06bf3..60acaa31a1dfd 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -317,33 +317,37 @@ static void type_trace_fini(TypeTrace *trace) { trace[0] = (const TypeTrace){0}; } -static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { +static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { R_RETURN_IF_FAIL (trace && esil && op); const char *expr = r_strbuf_get (&op->esil); if (R_UNLIKELY (!expr || !strlen (expr))) { R_LOG_WARN ("expr is empty or null"); - return; + return false; } trace->cc = 0; ut32 voy[4]; voy[R_ESIL_VOYEUR_REG_READ] = r_esil_add_voyeur (esil, &trace->db, type_trace_voyeur_reg_read, R_ESIL_VOYEUR_REG_READ); if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_READ] == R_ESIL_VOYEUR_ERR)) { - return; + return false; } + bool ret = true; voy[R_ESIL_VOYEUR_REG_WRITE] = r_esil_add_voyeur (esil, trace, type_trace_voyeur_reg_write, R_ESIL_VOYEUR_REG_WRITE); if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_WRITE] == R_ESIL_VOYEUR_ERR)) { + ret = false; goto fail_regw_voy; } voy[R_ESIL_VOYEUR_MEM_READ] = r_esil_add_voyeur (esil, &trace->db, type_trace_voyeur_mem_read, R_ESIL_VOYEUR_MEM_READ); if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_READ] == R_ESIL_VOYEUR_ERR)) { + ret = false; goto fail_memr_voy; } voy[R_ESIL_VOYEUR_MEM_WRITE] = r_esil_add_voyeur (esil, trace, type_trace_voyeur_mem_write, R_ESIL_VOYEUR_MEM_WRITE); if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_WRITE] == R_ESIL_VOYEUR_ERR)) { + ret = false; goto fail_memw_voy; } @@ -352,6 +356,7 @@ static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { const bool suc = r_esil_reg_write (esil, ri->name, op->addr); r_unref (ri); if (!suc) { + ret = false; goto fail_set_pc; } } @@ -366,7 +371,9 @@ static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { R_LOG_WARN ("Couldn't allocate(emplace_back) trace op"); //anything to do here? } - r_esil_parse (esil, expr); + if (!r_esil_parse (esil, expr)) { + ret = false; + } r_esil_stack_free (esil); trace->idx++; trace->end_idx++; // should be vector length? @@ -378,6 +385,7 @@ static void type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_WRITE]); fail_regw_voy: r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_READ]); + return ret; } static bool count_changes_above_idx_cb (void *user, const ut64 key, const void *val) { @@ -1094,8 +1102,8 @@ static void tps_fini(TPState *tps) { type_trace_fini (&tps->tt); r_esil_fini (&tps->esil); r_io_fd_close (tps->core->io, tps->stack_fd); - r_reg_setv (core->anal->reg, "SP", tps->sp); - r_reg_setv (core->anal->reg, "BP", tps->bp); + r_reg_setv (tps->core->anal->reg, "SP", tps->sp); + r_reg_setv (tps->core->anal->reg, "BP", tps->bp); free (tps->cfg_spec); r_config_hold_restore (tps->hc); r_config_hold_free (tps->hc); @@ -1189,7 +1197,6 @@ static TPState *tps_init(RCore *core) { RIOMap *map = r_io_map_add (core->io, tps->stack_fd, R_PERM_RW, 0, tps->stack_base, stack_size); if (!map) { r_io_fd_close (core->io, tps->stack_fd); - r_reg_free (tps->reg); free (tps); return NULL; } @@ -1210,7 +1217,7 @@ static TPState *tps_init(RCore *core) { free (tps); return NULL; } - if (!type_trace_init (&tps->tt, &tps->esil, tps->reg, sp, sp - tps->stack_base)) { + if (!type_trace_init (&tps->tt, &tps->esil, core->anal->reg, sp, sp - tps->stack_base)) { r_esil_fini (&tps->esil); r_reg_setv (core->anal->reg, "SP", tps->sp); r_reg_setv (core->anal->reg, "BP", tps->bp); From 29c8f7ef0674677a5aafb2b017d35c1beae4d698 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 06:21:22 +0200 Subject: [PATCH 14/61] tfygvuhbijnkm --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 60acaa31a1dfd..5b18d95ab588b 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -318,7 +318,7 @@ static void type_trace_fini(TypeTrace *trace) { } static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { - R_RETURN_IF_FAIL (trace && esil && op); + R_RETURN_VAL_IF_FAIL (trace && esil && op, false); const char *expr = r_strbuf_get (&op->esil); if (R_UNLIKELY (!expr || !strlen (expr))) { R_LOG_WARN ("expr is empty or null"); From 7f0a5b826b8ad244e771dc0ac476059f5cec6ebb Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 06:48:34 +0200 Subject: [PATCH 15/61] fix segfault --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 5b18d95ab588b..1a69b21de9202 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -351,7 +351,7 @@ static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { goto fail_memw_voy; } - RRegItem *ri = r_reg_get (esil->anal->reg, "PC", -1); + RRegItem *ri = r_reg_get (trace->reg, "PC", -1); if (ri) { const bool suc = r_esil_reg_write (esil, ri->name, op->addr); r_unref (ri); From d50428e3b1d1cb19d1e56a41cb238d08798dae63 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 06:52:55 +0200 Subject: [PATCH 16/61] Fix another segfault --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 1a69b21de9202..1fe5ae87a362b 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1423,7 +1423,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { char *cc = strdup (Cc); type_match (tps, fcn_name, addr, bb->addr, cc, prev_idx, userfnc, callee_addr); // prev_idx = tps->tt.cur_idx; - prev_idx = tps->core->anal->esil->trace->cur_idx; + prev_idx = etrace->cur_idx; R_FREE (ret_type); const char *rt = r_type_func_ret (TDB, fcn_name); if (rt) { From e02497a907adb7904c18d8b3acec74d932771f50 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 28 Apr 2025 06:59:04 +0200 Subject: [PATCH 17/61] Fix 2 more segfaults --- libr/core/anal_tp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 1fe5ae87a362b..6bbd35beba3a3 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1441,7 +1441,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { // r_strf_var (query, 32, "%d.addr", cur_idx - 1); // ut64 mov_addr = sdb_num_get (trace, query, 0); // cur_idx = tps->tt.cur_idx - 2; - cur_idx = tps->core->anal->esil->trace->cur_idx - 2; + cur_idx = etrace->cur_idx - 2; // eprintf (Color_GREEN"ADDROF %d\n"Color_RESET, cur_idx); ut64 mov_addr = etrace_addrof (etrace, cur_idx); RAnalOp *mop = r_core_anal_op (core, mov_addr, R_ARCH_OP_MASK_VAL | R_ARCH_OP_MASK_BASIC); @@ -1463,7 +1463,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { // const char *cur_dest = sdb_const_get (trace, query, 0); // sdb_const_get (trace, query, 0); // cur_idx = tps->tt.cur_idx - 1; - cur_idx = tps->core->anal->esil->trace->cur_idx - 1; + cur_idx = etrace->cur_idx - 1; const char *cur_dest = etrace_regwrite (etrace, cur_idx); get_src_regname (core, aop.addr, src, sizeof (src)); if (ret_reg && *src && strstr (ret_reg, src)) { From c45497ed2bff70d939721b019a84043946b810f8 Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 29 Apr 2025 09:58:58 +0200 Subject: [PATCH 18/61] Remove unused type_trace_restore helpers --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 6bbd35beba3a3..65568423ecdaa 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -412,6 +412,7 @@ static bool count_changes_above_idx_cb (void *user, const ut64 key, const void * return true; } +#if 0 typedef struct { int idx; union { @@ -477,7 +478,6 @@ static int sort_mem_changes_cb (const void *v0, const void *v1) { return b->idx - a->idx; } -#if 0 static void type_trace_restore(TypeTrace *trace, REsil *esil, int idx) { R_RETURN_IF_FAIL (trace && esil && (idx < trace->idx)); ut64 v = ((ut64)idx) << 32; From 63995909e7926d9d98323370730ad1c7ff069b90 Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 29 Apr 2025 11:22:55 +0200 Subject: [PATCH 19/61] Remove a bunch of crap and overall speedup typetrace --- libr/core/anal_tp.c | 152 ++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 96 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 65568423ecdaa..b9545cffbba26 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -72,10 +72,7 @@ typedef struct type_trace_t { RReg *reg; HtUP *registers; HtUP *memory; - RRegArena *arena[R_REG_TYPE_LAST]; - ut64 stack_addr; - ut64 stack_size; - ut8 *stack_data; + ut32 voy[4]; } TypeTrace; #define CMP_REG_CHANGE(x, y) ((x) - ((TypeTraceRegChange *)y)->idx) @@ -238,9 +235,8 @@ static void trace_db_init(TypeTraceDB *db) { db->loop_counts = ht_uu_new0 (); } -static bool type_trace_init(TypeTrace *trace, REsil *esil, RReg *reg, - ut64 stack_addr, ut64 stack_size) { - R_RETURN_VAL_IF_FAIL (trace && esil && reg && stack_size, false); +static bool type_trace_init(TypeTrace *trace, REsil *esil, RReg *reg) { + R_RETURN_VAL_IF_FAIL (trace && esil && reg, false); *trace = (const TypeTrace){0}; trace_db_init (&trace->db); trace->registers = ht_up_new (NULL, htup_vector_free, NULL); @@ -251,37 +247,35 @@ static bool type_trace_init(TypeTrace *trace, REsil *esil, RReg *reg, if (!trace->memory) { goto fail_memory_ht; } - trace->stack_data = malloc (stack_size); - if (!trace->stack_data) { - goto fail_malloc; + trace->voy[R_ESIL_VOYEUR_REG_READ] = r_esil_add_voyeur (esil, &trace->db, + type_trace_voyeur_reg_read, R_ESIL_VOYEUR_REG_READ); + if (R_UNLIKELY (trace->voy[R_ESIL_VOYEUR_REG_READ] == R_ESIL_VOYEUR_ERR)) { + goto fail_regr_voy; } - if (!r_esil_mem_read_silent (esil, stack_addr, trace->stack_data, stack_size)) { - goto fail_read; + trace->voy[R_ESIL_VOYEUR_REG_WRITE] = r_esil_add_voyeur (esil, trace, + type_trace_voyeur_reg_write, R_ESIL_VOYEUR_REG_WRITE); + if (R_UNLIKELY (trace->voy[R_ESIL_VOYEUR_REG_WRITE] == R_ESIL_VOYEUR_ERR)) { + goto fail_regw_voy; } - ut32 i; - for (i = 0; i < R_REG_TYPE_LAST; i++) { - RRegArena *a = reg->regset[i].arena; - RRegArena *b = r_reg_arena_new (a->size); - if (!b) { - goto fail_regs_copy; - } - if (b->bytes && a->bytes && b->size > 0) { - memcpy (b->bytes, a->bytes, b->size); - } - trace->arena[i] = b; + trace->voy[R_ESIL_VOYEUR_MEM_READ] = r_esil_add_voyeur (esil, &trace->db, + type_trace_voyeur_mem_read, R_ESIL_VOYEUR_MEM_READ); + if (R_UNLIKELY (trace->voy[R_ESIL_VOYEUR_MEM_READ] == R_ESIL_VOYEUR_ERR)) { + goto fail_memr_voy; + } + trace->voy[R_ESIL_VOYEUR_MEM_WRITE] = r_esil_add_voyeur (esil, trace, + type_trace_voyeur_mem_write, R_ESIL_VOYEUR_MEM_WRITE); + if (R_UNLIKELY (trace->voy[R_ESIL_VOYEUR_MEM_WRITE] == R_ESIL_VOYEUR_ERR)) { + goto fail_memw_voy; } trace->reg = reg; - trace->stack_addr = stack_addr; - trace->stack_size = stack_size; return true; -fail_regs_copy: - while (i) { - i--; - r_reg_arena_free (trace->arena[i]); - } -fail_read: - R_FREE (trace->stack_data); -fail_malloc: +fail_memw_voy: + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_MEM_READ]); +fail_memr_voy: + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_REG_WRITE]); +fail_regw_voy: + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_REG_READ]); +fail_regr_voy: ht_up_free (trace->memory); trace->memory = NULL; fail_memory_ht: @@ -302,18 +296,19 @@ static void type_trace_loopcount_increment(TypeTrace *trace, ut64 addr) { ht_uu_update (trace->db.loop_counts, addr, count + 1); } -static void type_trace_fini(TypeTrace *trace) { - R_RETURN_IF_FAIL (trace); +//XXX: trace should be the only parameter +static void type_trace_fini(TypeTrace *trace, REsil *esil) { + R_RETURN_IF_FAIL (trace && esil); VecTraceOp_fini (&trace->db.ops); VecAccess_fini (&trace->db.accesses); ht_uu_free (trace->db.loop_counts); ht_up_free (trace->registers); ht_up_free (trace->memory); - free (trace->stack_data); - ut32 i; - for (i = 0; i < R_REG_TYPE_LAST; i++) { - r_reg_arena_free (trace->arena[i]); - } + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_MEM_WRITE]); + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_MEM_READ]); + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_REG_WRITE]); + r_esil_del_voyeur (esil, trace->voy[R_ESIL_VOYEUR_REG_READ]); + r_reg_free (trace->reg); trace[0] = (const TypeTrace){0}; } @@ -325,39 +320,13 @@ static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { return false; } trace->cc = 0; - ut32 voy[4]; - voy[R_ESIL_VOYEUR_REG_READ] = r_esil_add_voyeur (esil, &trace->db, - type_trace_voyeur_reg_read, R_ESIL_VOYEUR_REG_READ); - if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_READ] == R_ESIL_VOYEUR_ERR)) { - return false; - } - bool ret = true; - voy[R_ESIL_VOYEUR_REG_WRITE] = r_esil_add_voyeur (esil, trace, - type_trace_voyeur_reg_write, R_ESIL_VOYEUR_REG_WRITE); - if (R_UNLIKELY (voy[R_ESIL_VOYEUR_REG_WRITE] == R_ESIL_VOYEUR_ERR)) { - ret = false; - goto fail_regw_voy; - } - voy[R_ESIL_VOYEUR_MEM_READ] = r_esil_add_voyeur (esil, &trace->db, - type_trace_voyeur_mem_read, R_ESIL_VOYEUR_MEM_READ); - if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_READ] == R_ESIL_VOYEUR_ERR)) { - ret = false; - goto fail_memr_voy; - } - voy[R_ESIL_VOYEUR_MEM_WRITE] = r_esil_add_voyeur (esil, trace, - type_trace_voyeur_mem_write, R_ESIL_VOYEUR_MEM_WRITE); - if (R_UNLIKELY (voy[R_ESIL_VOYEUR_MEM_WRITE] == R_ESIL_VOYEUR_ERR)) { - ret = false; - goto fail_memw_voy; - } RRegItem *ri = r_reg_get (trace->reg, "PC", -1); if (ri) { - const bool suc = r_esil_reg_write (esil, ri->name, op->addr); + const bool suc = r_esil_reg_write_silent (esil, ri->name, op->addr + op->size); r_unref (ri); if (!suc) { - ret = false; - goto fail_set_pc; + return false; } } @@ -371,20 +340,10 @@ static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { R_LOG_WARN ("Couldn't allocate(emplace_back) trace op"); //anything to do here? } - if (!r_esil_parse (esil, expr)) { - ret = false; - } + const bool ret = r_esil_parse (esil, expr); r_esil_stack_free (esil); trace->idx++; trace->end_idx++; // should be vector length? -fail_set_pc: - r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_MEM_WRITE]); -fail_memw_voy: - r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_MEM_READ]); -fail_memr_voy: - r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_WRITE]); -fail_regw_voy: - r_esil_del_voyeur (esil, voy[R_ESIL_VOYEUR_REG_READ]); return ret; } @@ -654,7 +613,7 @@ static bool etrace_regwrite_contains(TypeTrace *etrace, ut32 idx, const char *rn static bool type_pos_hit(TPState *tps, bool in_stack, int idx, int size, const char *place) { R_LOG_DEBUG ("Type pos hit %d %d %d %s", in_stack, idx, size, place); if (in_stack) { - ut64 sp = r_reg_getv (tps->core->anal->reg, "SP"); // XXX this is slow too and we can cache + ut64 sp = r_reg_getv (tps->tt.reg, "SP"); // XXX this is slow too and we can cache const ut64 write_addr = etrace_memwrite_addr (&tps->tt, idx); // AAA -1 return (write_addr == sp + size); } @@ -1099,11 +1058,9 @@ static int bb_cmpaddr(const void *_a, const void *_b) { static void tps_fini(TPState *tps) { R_RETURN_IF_FAIL (tps); - type_trace_fini (&tps->tt); + type_trace_fini (&tps->tt, &tps->esil); r_esil_fini (&tps->esil); r_io_fd_close (tps->core->io, tps->stack_fd); - r_reg_setv (tps->core->anal->reg, "SP", tps->sp); - r_reg_setv (tps->core->anal->reg, "BP", tps->bp); free (tps->cfg_spec); r_config_hold_restore (tps->hc); r_config_hold_free (tps->hc); @@ -1200,27 +1157,30 @@ static TPState *tps_init(RCore *core) { free (tps); return NULL; } + //XXX: r_reg_clone should be invoked in type_trace_init + RReg *reg = r_reg_clone (core->anal->reg); + if (!reg) { + r_io_fd_close (core->io, tps->stack_fd); + free (tps); + return NULL; + } tps->stack_map = map->id; //todo fix addrsize - type_trace_reg_if.reg = core->anal->reg; + type_trace_reg_if.reg = reg; type_trace_mem_if.mem = tps; ut64 sp = tps->stack_base + stack_size - (stack_size % align) - align * 8; //todo: this probably needs some boundary checks - tps->sp = r_reg_getv (core->anal->reg, "SP"); - tps->bp = r_reg_getv (core->anal->reg, "BP"); - r_reg_setv (core->anal->reg, "SP", sp); - r_reg_setv (core->anal->reg, "BP", sp); + r_reg_setv (reg, "SP", sp); + r_reg_setv (reg, "BP", sp); if (!r_esil_init (&tps->esil, 4096, false, 64, &type_trace_reg_if, &type_trace_mem_if)) { - r_reg_setv (core->anal->reg, "SP", tps->sp); - r_reg_setv (core->anal->reg, "BP", tps->bp); + r_reg_free (reg); r_io_fd_close (core->io, tps->stack_fd); free (tps); return NULL; } - if (!type_trace_init (&tps->tt, &tps->esil, core->anal->reg, sp, sp - tps->stack_base)) { + if (!type_trace_init (&tps->tt, &tps->esil, reg)) { r_esil_fini (&tps->esil); - r_reg_setv (core->anal->reg, "SP", tps->sp); - r_reg_setv (core->anal->reg, "BP", tps->bp); + r_reg_free (reg); r_io_fd_close (core->io, tps->stack_fd); free (tps); return NULL; @@ -1312,7 +1272,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } // XXX fail sometimes /// addr = bb_addr + i; - r_reg_setv (core->anal->reg, "PC", addr); + r_reg_setv (etrace->reg, "PC", addr); ut64 bb_left = bb_size - i; if ((addr >= bb_addr + bb_size) || (addr < bb_addr)) { // stop emulating this bb if pc is outside the basic block boundaries @@ -1322,7 +1282,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { if (ret <= 0) { i += minopcode; addr += minopcode; - r_reg_setv (core->anal->reg, "PC", addr); + r_reg_setv (etrace->reg, "PC", addr); r_anal_op_fini (&aop); continue; } @@ -1334,7 +1294,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) { } #endif type_trace_loopcount_increment (etrace, addr); - r_reg_setv (core->anal->reg, "PC", addr + aop.size); + r_reg_setv (etrace->reg, "PC", addr + aop.size); if (!r_anal_op_nonlinear (aop.type)) { // skip jmp/cjmp/trap/ret/call ops //this shit probably needs further refactoring. i hate this code if (aop.type == R_ANAL_OP_TYPE_ILL || aop.type == R_ANAL_OP_TYPE_UNK) { From a00c67da032cec64be84b7cd5ec48dbe132472dd Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 29 Apr 2025 11:44:38 +0200 Subject: [PATCH 20/61] Hackfix --- libr/core/anal_tp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index b9545cffbba26..9395a02dc71ff 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -499,9 +499,8 @@ typedef struct { REsil esil; TypeTrace tt; ut64 stack_base; - ut64 sp; //old sp - ut64 bp; //old bp RCore *core; + RReg *anal_reg; int stack_fd; ut32 stack_map; RConfigHold *hc; @@ -1058,6 +1057,7 @@ static int bb_cmpaddr(const void *_a, const void *_b) { static void tps_fini(TPState *tps) { R_RETURN_IF_FAIL (tps); + tps->core->anal->reg = tps->anal_reg; type_trace_fini (&tps->tt, &tps->esil); r_esil_fini (&tps->esil); r_io_fd_close (tps->core->io, tps->stack_fd); @@ -1185,6 +1185,10 @@ static TPState *tps_init(RCore *core) { free (tps); return NULL; } +//XXX: HACK + tps->anal_reg = core->anal->reg; + tps->esil.anal = core->anal; + core->anal->reg = reg; tps->hc = r_config_hold_new (cfg); tps->cfg_spec = strdup (r_config_get (cfg, "anal.types.spec")); tps->cfg_breakoninvalid = r_config_get_b (cfg, "esil.breakoninvalid"); From 77fed3b27ef4192215044f5ce81159372073e070 Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 29 Apr 2025 11:50:25 +0200 Subject: [PATCH 21/61] disable forgotten unused function to stop compiler bitching --- libr/core/anal_tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 9395a02dc71ff..5e3662026ae68 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -347,6 +347,7 @@ static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { return ret; } +#if 0 static bool count_changes_above_idx_cb (void *user, const ut64 key, const void *val) { RVector *vec = val; if (R_UNLIKELY (r_vector_empty (vec))) { @@ -371,7 +372,6 @@ static bool count_changes_above_idx_cb (void *user, const ut64 key, const void * return true; } -#if 0 typedef struct { int idx; union { From 47ca8d42cd1c323bb4a4e982271a9be968e6843f Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 30 Apr 2025 14:46:48 +0200 Subject: [PATCH 22/61] use new esil api to see what happens --- libr/include/r_esil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 60cbec23167c1..81edeca80a47d 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -14,7 +14,7 @@ extern "C" { #endif -#define USE_NEW_ESIL 0 +#define USE_NEW_ESIL 1 #define esilprintf(op, fmt, ...) r_strbuf_setf (&op->esil, fmt, ##__VA_ARGS__) // only flags that affect control flow From 55c579e37b85c1789bf72cf5c236e62e163a62a5 Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 30 Apr 2025 17:55:13 +0200 Subject: [PATCH 23/61] Fix some bugz --- libr/core/anal_tp.c | 3 ++- libr/esil/esil.c | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 5e3662026ae68..af3b53e5cca58 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1091,8 +1091,9 @@ static ut32 tt_reg_size(void *reg, const char *name) { if (!ri) { return 0; } + ut32 size = ri->size; r_unref (ri); - return ri->size; + return size; } static REsilRegInterface type_trace_reg_if = { diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 5661d839fe0f8..0f21da5193f8a 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -75,6 +75,7 @@ R_API bool r_esil_init(REsil *esil, int stacksize, bool iotrap, if (r_id_storage_init (&esil->voyeur[i], 0, MAX_VOYEURS)) { continue; } + R_LOG_ERROR ("voyeur init failed"); do { r_id_storage_fini (&esil->voyeur[i]); i--; @@ -399,9 +400,9 @@ R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { return true; } do { - REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], i); + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], i); voy->mem_write (voy->user, addr, o.buf, buf, len); - } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], &i)); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)); return true; } o.ptr = R_NEWS (ut8, len); @@ -416,9 +417,9 @@ R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { return false; } do { - REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], i); + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], i); voy->mem_write (voy->user, addr, o.ptr, buf, len); - } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], &i)); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)); free (o.ptr); return true; #else From 7d1ef8a1e293346f6126e04e4baf65e369e324ab Mon Sep 17 00:00:00 2001 From: condret Date: Fri, 2 May 2025 03:00:32 +0200 Subject: [PATCH 24/61] Prepare esil_dfg for switch to new esil api --- libr/anal/esil_dfg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libr/anal/esil_dfg.c b/libr/anal/esil_dfg.c index 71a080e72867c..e47b888e4998f 100644 --- a/libr/anal/esil_dfg.c +++ b/libr/anal/esil_dfg.c @@ -1554,7 +1554,11 @@ R_API RAnalEsilDFG *r_anal_esil_dfg_new(RAnal* anal, bool use_map_info, bool use free (dfg); return NULL; } +#if USE_NEW_ESIL + dfg->esil = r_esil_new_simple (1, anal->reg, &anal->iob); +#else dfg->esil = r_esil_new (4096, 0, 1); +#endif if (!dfg->esil) { r_reg_free (dfg->reg); free (dfg); @@ -1644,13 +1648,17 @@ R_API void r_anal_esil_dfg_free(RAnalEsilDFG *dfg) { R_API RAnalEsilDFG *r_anal_esil_dfg_expr(RAnal *anal, RAnalEsilDFG * R_NULLABLE dfg, const char *expr, bool use_map_info, bool use_maps) { R_RETURN_VAL_IF_FAIL (anal && expr, NULL); +#if USE_NEW_ESIL + REsil *esil = r_esil_new_simple (1, anal->reg, &anal->iob); +#else REsil *esil = r_esil_new (4096, 0, 1); +#endif if (!esil) { return NULL; } esil->anal = anal; - RAnalEsilDFG *edf = dfg ? dfg : r_anal_esil_dfg_new (anal, use_map_info, use_maps); + RAnalEsilDFG *edf = dfg? dfg: r_anal_esil_dfg_new (anal, use_map_info, use_maps); if (!edf) { r_esil_free (esil); return NULL; From 60b3c4b41894a464e8a06dd3d03890e70cbc03c5 Mon Sep 17 00:00:00 2001 From: condret Date: Fri, 2 May 2025 03:50:03 +0200 Subject: [PATCH 25/61] Prepare vmenus for switch to new esil api --- libr/core/vmenus.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/libr/core/vmenus.c b/libr/core/vmenus.c index 7f5dcf2bc4908..ab8dd74df1a61 100644 --- a/libr/core/vmenus.c +++ b/libr/core/vmenus.c @@ -237,10 +237,16 @@ R_API bool r_core_visual_esil(RCore *core, const char *input) { } RCons *cons = core->cons; r_reg_arena_push (core->anal->reg); +#if USE_NEW_ESIL + REsil *esil = r_esil_new_simple (addrsize, core->anal->reg, &core->anal->iob); + const char *pc_name = r_reg_alias_getname (core->anal->reg, R_REG_ALIAS_PC); + r_reg_setv (core->anal->reg, pc_name, core->addr); +#else REsil *esil = r_esil_new (20, 0, addrsize); r_esil_setup (esil, core->anal, false, false, false); // esil->anal = core->anal; r_esil_set_pc (esil, core->addr); +#endif char *expr = NULL; bool refresh = false; for (;;) { @@ -336,19 +342,29 @@ R_API bool r_core_visual_esil(RCore *core, const char *input) { case 'P': x = 0; r_esil_free (esil); - esil = r_esil_new (20, 0, addrsize); - esil->anal = core->anal; r_core_cmd0 (core, "so+1"); +#if USE_NEW_ESIL + esil = r_esil_new_simple (addrsize, core->anal->reg, &core->anal->iob); + r_reg_setv (core->anal->reg, pc_name, core->addr); +#else + esil = r_esil_new (20, 0, addrsize); r_esil_set_pc (esil, core->addr); +#endif + esil->anal = core->anal; break; case 'N': case 'p': x = 0; r_esil_free (esil); - esil = r_esil_new (20, 0, addrsize); - esil->anal = core->anal; r_core_cmd0 (core, "so-1"); +#if USE_NEW_ESIL + esil = r_esil_new_simple (addrsize, core->anal->reg, &core->anal->iob); + r_reg_setv (core->anal->reg, pc_name, core->addr); +#else + esil = r_esil_new (20, 0, addrsize); r_esil_set_pc (esil, core->addr); +#endif + esil->anal = core->anal; break; case '=': { // TODO: edit From 1fa053b28bb3de2ff3ac888302a6112c5fda3af8 Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 3 May 2025 06:02:20 +0200 Subject: [PATCH 26/61] Prepare cmd_search for switch to new esil api --- libr/core/cmd_search.inc.c | 134 ++++++++++++++++++++++++++++++------- libr/core/core_esil.c | 3 +- 2 files changed, 112 insertions(+), 25 deletions(-) diff --git a/libr/core/cmd_search.inc.c b/libr/core/cmd_search.inc.c index 41ed0430a42e1..8b40993dede99 100644 --- a/libr/core/cmd_search.inc.c +++ b/libr/core/cmd_search.inc.c @@ -1829,8 +1829,79 @@ static int r_core_search_rop(RCore *core, RInterval search_itv, int opt, const c return result; } +#if USE_NEW_ESIL +static bool search_esil_mem_read (void *mem, ut64 addr, ut8 *buf, int len) { + RCore *core = mem; + if (!addr && r_config_get_b (core->config, "esil.nonull")) { + return false; + } + return r_io_read_at (core->io, addr, buf, len); +} + +static bool search_esil_mem_write_ro (void *mem, ut64 addr, const ut8 *buf, int len) { + RCore *core = mem; + if (!addr && r_config_get_b (core->config, "esil.nonull")) { + return false; + } + RIORegion region; + if (!r_io_get_region_at (core->io, ®ion, addr)) { + //maybe check voidwrites config here + return true; + } + if (!(region.perm & R_PERM_W)) { + return false; + } + if (r_itv_contain (region.itv, addr + len - 1)) { + return true; + } + return search_esil_mem_write_ro (mem, r_itv_end (region.itv), + NULL, addr + len - r_itv_end (region.itv)); //no need to pass buf, because this is RO mode +} + +REsilMemInterface search_esil_mem_if = { + .mem_read = search_esil_mem_read, + .mem_write = search_esil_mem_write_ro, +}; + +static bool search_esil_is_reg (void *reg, const char *name) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return false; + } + r_unref (ri); + return true; +} + +static bool search_esil_reg_read (void *reg, const char *name, ut64 *val) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return false; + } + *val = r_reg_get_value ((RReg *)reg, ri); + r_unref (ri); + return true; +} + +static const ut32 search_esil_reg_size (void *reg, const char *name) { + RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); + if (!ri) { + return 0; + } + const ut32 size = ri->size; + r_unref (ri); + return size; +} + +REsilRegInterface search_esil_reg_if = { + .is_reg = search_esil_is_reg, + .reg_read = search_esil_reg_read, + .reg_write = (REsilRegWrite)r_reg_setv, + .reg_size = search_esil_reg_size, +}; +#endif + static bool esil_addrinfo(REsil *esil) { - RCore *core = (RCore *) esil->cb.user; + RCore *core = esil->user; ut64 num = 0; char *src = r_esil_pop (esil); if (src && *src && r_esil_get_parm (esil, src, &num)) { @@ -1865,26 +1936,43 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c r_core_cmd_help (core, help_msg_slash_esil); return; } - const unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size"); + const ut32 addrsize = r_config_get_i (core->config, "esil.addr.size"); const int iotrap = r_config_get_i (core->config, "esil.iotrap"); - int stacksize = r_config_get_i (core->config, "esil.stack.size"); - const int nonull = r_config_get_i (core->config, "esil.nonull"); - const int romem = r_config_get_i (core->config, "esil.romem"); - const int stats = r_config_get_i (core->config, "esil.stats"); - if (stacksize < 16) { - stacksize = 16; + const int stacksize = R_MAX (r_config_get_i (core->config, "esil.stack.size"), 16); +#if USE_NEW_ESIL + search_esil_reg_if.user = core->anal->reg; + search_esil_mem_if.user = core; + REsil stack_located_esil = {0}; + if (!r_esil_init (&stack_located_esil, stacksize, iotrap, addrsize, + &search_esil_reg_if, &search_esil_mem_if)) { + R_LOG_ERROR ("Cannot initialize search esil instance"); + return; + } + if (!r_reg_arena_push (core->anal->reg)) { + r_esil_fini (&stack_located_esil); + R_LOG_ERROR ("Cannot push reg arena instance"); + return; } + REsil *esil = &stack_located_esil; +#else + const int nonull = r_config_get_i (core->config, "esil.nonull"); +// const int romem = r_config_get_i (core->config, "esil.romem"); +// const int stats = r_config_get_i (core->config, "esil.stats"); REsil *esil = r_esil_new (stacksize, iotrap, addrsize); if (!esil) { R_LOG_ERROR ("Cannot create an esil instance"); return; } +// r_esil_setup (esil, core->anal, romem, stats, nonull); + r_esil_setup (esil, core->anal, true, false, nonull); +#endif + esil->user = core; //this is fine, because no arch plugin custom ops are registered r_esil_set_op (esil, "$$", esil_address, 0, 1, R_ESIL_OP_TYPE_UNKNOWN, "current address"); - esil->cb.user = core; + /* hook addrinfo */ + r_esil_set_op (esil, "AddrInfo", esil_addrinfo, 1, 1, R_ESIL_OP_TYPE_UNKNOWN, NULL); // TODO:? cmd_aei (core); RIOMap *map; RListIter *iter; - r_esil_setup (esil, core->anal, romem, stats, nonull); r_list_foreach (param->boundaries, iter, map) { bool hit_happens = false; size_t hit_combo = 0; @@ -1892,10 +1980,7 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c ut64 nres, addr; ut64 from = r_io_map_begin (map); ut64 to = r_io_map_end (map); - /* hook addrinfo */ - r_esil_set_op (esil, "AddrInfo", esil_addrinfo, 1, 1, R_ESIL_OP_TYPE_UNKNOWN, NULL); - /* hook addrinfo */ - r_esil_setup (esil, core->anal, 1, 0, nonull); + //r_esil_setup (esil, core->anal, 1, 0, nonull); r_esil_stack_free (esil); esil->verbose = 0; @@ -1921,7 +2006,12 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c R_LOG_INFO ("Breaked at 0x%08"PFMT64x, addr); break; } +#if USE_NEW_ESIL + const char *pc_name = r_reg_alias_getname (core->anal->reg, R_REG_ALIAS_PC); + r_reg_setv (core->anal->reg, pc_name, core->addr); +#else r_esil_set_pc (esil, addr); +#endif if (!r_esil_parse (esil, input + 2)) { // XXX: return value doesnt seems to be correct here R_LOG_ERROR ("Cannot parse esil (%s)", input + 2); @@ -1978,7 +2068,12 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c if (param->outmode == R_MODE_JSON) { pj_end (param->pj); } +#if USE_NEW_ESIL + r_esil_fini (&stack_located_esil); + r_reg_arena_pop (core->anal->reg); +#else r_esil_free (esil); +#endif } #define MAXINSTR 8 @@ -2069,29 +2164,20 @@ static void do_syscall_search(RCore *core, struct search_parameters *param) { RAnalOp aop = {0}; int i, ret, bsize = R_MAX (64, core->blocksize); int kwidx = core->search->n_kws; - RIOMap* map; + RIOMap *map; RListIter *iter; const int mininstrsz = r_anal_archinfo (core->anal, R_ARCH_INFO_MINOP_SIZE); const int minopcode = R_MAX (1, mininstrsz); - REsil *esil; int align = core->search->align; - int stacksize = r_config_get_i (core->config, "esil.stack.depth"); - int iotrap = r_config_get_i (core->config, "esil.iotrap"); - unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size"); const bool isx86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86"); - if (!(esil = r_esil_new (stacksize, iotrap, addrsize))) { - return; - } int *previnstr = calloc (MAXINSTR + 1, sizeof (int)); if (!previnstr) { - r_esil_free (esil); return; } ut8 *buf = malloc (bsize); if (!buf) { R_LOG_ERROR ("Cannot allocate %d byte(s)", bsize); - r_esil_free (esil); free (previnstr); return; } diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 0a0007101b52e..8410cb4fb102b 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -57,8 +57,9 @@ static ut32 core_esil_reg_size (void *core, const char *name) { if (!ri) { return 0; } + const ut32 size = ri->size; r_unref (ri); - return ri->size; + return size; } static REsilRegInterface core_esil_reg_if = { From b40be03efac9842b00e14d800da257bb1b6689ed Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 5 May 2025 02:42:55 +0200 Subject: [PATCH 27/61] Fix esil_dfg unit tests for new api --- test/unit/test_esil_dfg_filter.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/unit/test_esil_dfg_filter.c b/test/unit/test_esil_dfg_filter.c index 0cb3fb7820412..8e7f0772a3cc1 100644 --- a/test/unit/test_esil_dfg_filter.c +++ b/test/unit/test_esil_dfg_filter.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include "minunit.h" @@ -8,7 +10,13 @@ bool test_filter_regs(void) { r_anal_use (anal, "x86"); r_anal_set_bits (anal, 32); r_anal_set_reg_profile (anal, NULL); +#if USE_NEW_ESIL + RIO *io = r_io_new (); + r_io_bind (io, &anal->iob); + REsil *esil = r_esil_new_simple (1, anal->reg, &anal->iob); +#else REsil *esil = r_esil_new (4096, 0, 1); +#endif esil->anal = anal; // create expected results @@ -43,6 +51,9 @@ bool test_filter_regs(void) { r_anal_esil_dfg_free (dfg); r_esil_free (esil); r_anal_free (anal); +#if USE_NEW_ESIL + r_io_free (io); +#endif mu_assert ("filtering for ax failed", ax == filtered_ax); mu_assert ("filtering for ah failed", ah == filtered_ah); @@ -56,6 +67,11 @@ bool test_lemon_const_folder(void) { r_anal_set_bits (anal, 32); r_anal_set_reg_profile (anal, NULL); +#if USE_NEW_ESIL + RIO *io = r_io_new (); + r_io_bind (io, &anal->iob); +#endif + RAnalEsilDFG *dfg = r_anal_esil_dfg_expr (anal, NULL, "4,!,3,ebx,:=,!,1,+,eax,:=", false, false); r_anal_esil_dfg_fold_const (anal, dfg); RStrBuf *filtered = r_anal_esil_dfg_filter (dfg, "eax"); @@ -63,6 +79,9 @@ bool test_lemon_const_folder(void) { r_strbuf_free (filtered); r_anal_esil_dfg_free (dfg); r_anal_free (anal); +#if USE_NEW_ESIL + r_io_free (io); +#endif mu_assert_true (cmp_result, "esil dfg const folding is broken"); mu_end; From 5754a4df8153e54c498a8ae10121330b95fc7200 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 5 May 2025 02:57:32 +0200 Subject: [PATCH 28/61] Prepare anal for switch to new esil api --- libr/anal/anal.c | 2 ++ libr/core/core.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 32da07cec611c..4ea9f42a9f018 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -113,8 +113,10 @@ R_API RAnal *r_anal_new(void) { anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1); anal->zign_path = strdup (""); anal->cb_printf = (PrintfCallback) printf; +#if USE_NEW_ESIL == 0 anal->esil = r_esil_new (4096, 0, 1); anal->esil->anal = anal; +#endif (void)r_anal_pin_init (anal); (void)r_anal_xrefs_init (anal); anal->diff_thbb = R_ANAL_THRESHOLDBB; diff --git a/libr/core/core.c b/libr/core/core.c index 859aff7634c14..4fdbdf31717d4 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2710,6 +2710,10 @@ R_API bool r_core_init(RCore *core) { r_io_bind (core->io, &(core->fs->iob)); r_cons_bind (core->cons, &(core->fs->csb)); r_cons_bind (core->cons, &(core->search->consb)); +#if USE_NEW_ESIL + core->anal->esil = r_esil_new_simple (1, core->anal->reg, &core->anal->iob); + core->anal->esil->anal = core->anal; +#endif r_core_bind (core, &(core->fs->cob)); r_io_bind (core->io, &(core->bin->iob)); r_flag_bind (core->flags, &(core->anal->flb)); From 66e0a8485da070aa70e7af7bd52261b06469e661 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 5 May 2025 03:01:58 +0200 Subject: [PATCH 29/61] Fix annoying warning when using new esil api --- libr/esil/esil.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 0f21da5193f8a..709d4053113a6 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -44,8 +44,10 @@ R_API REsil *r_esil_new(int stacksize, int iotrap, unsigned int addrsize) { r_esil_plugins_init (esil); esil->addrmask = r_num_genmask (addrsize - 1); esil->trace = r_esil_trace_new (esil); +#if USE_NEW_ESIL == 0 int stats = 1; r_esil_stats (esil, NULL, stats); +#endif r_esil_setup_ops (esil); return esil; } @@ -1106,7 +1108,9 @@ R_API bool r_esil_setup(REsil *esil, RAnal *anal, bool romem, bool stats, bool n esil->cb.mem_write = internal_esil_mem_write; } r_esil_mem_ro (esil, romem); +#if USE_NEW_ESIL == 0 r_esil_stats (esil, NULL, stats); +#endif r_esil_setup_ops (esil); // Try arch esil init cb first, then anal as fallback From 9230ae328178b01236aa3222d1a1786ce7bcf258 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 5 May 2025 04:41:24 +0200 Subject: [PATCH 30/61] Fix esil_toc for switch to new esil api --- libr/esil/esil_toc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libr/esil/esil_toc.c b/libr/esil/esil_toc.c index 0bbd0cbea14cc..e8f0a352074fd 100644 --- a/libr/esil/esil_toc.c +++ b/libr/esil/esil_toc.c @@ -1,6 +1,7 @@ /* radare - LGPL - Copyright 2021-2024 - pancake */ #include +#include static bool esil2c_eq(REsil *esil) { REsilC *user = esil->user; @@ -199,8 +200,13 @@ static void esil2c_setup(REsil *esil) { REsilC *user = R_NEW (REsilC); esil->user = user; esil->verbose = true; // r_config_get_b (core->config, "esil.verbose"); +#if USE_NEW_ESIL + r_esil_add_voyeur (esil, NULL, esil2c_mw, R_ESIL_VOYEUR_MEM_WRITE); + r_esil_add_voyeur (esil, NULL, esil2c_mr, R_ESIL_VOYEUR_MEM_READ); +#else esil->cb.mem_read = esil2c_mr; esil->cb.mem_write = esil2c_mw; +#endif r_esil_set_op (esil, "=", esil2c_eq, 0, 2, R_ESIL_OP_TYPE_REG_WRITE, NULL); r_esil_set_op (esil, ":=", esil2c_eq, 0, 2, R_ESIL_OP_TYPE_REG_WRITE, NULL); r_esil_set_op (esil, "-", esil2c_sub, 1, 2, R_ESIL_OP_TYPE_REG_WRITE, NULL); @@ -222,8 +228,13 @@ static void esil2c_setup(REsil *esil) { R_API REsilC *r_esil_toc_new(struct r_anal_t *anal, const int bits) { REsilC *ec = R_NEW0 (REsilC); if (ec) { +#if USE_NEW_ESIL + REsil *esil = r_esil_new_simple (bits, anal->reg, &anal->iob); + esil->anal = anal; +#else int ss = 16 * 1024; REsil *esil = r_esil_new (ss, 0, bits); +#endif if (esil) { esil2c_setup (esil); ec->anal = anal; From d106e6fea476f2930525210c11ef699f7d5c986d Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 7 May 2025 02:21:03 +0200 Subject: [PATCH 31/61] Prepare esil_cost in cmd_anal.inc.c for switch to new esil api --- libr/core/cmd_anal.inc.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 41fc144c1da56..9c4181b42142f 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2446,6 +2446,28 @@ R_API char *cmd_syscall_dostr(RCore *core, st64 n, ut64 addr) { r_syscall_item_free (item); return r_str_append (res, ")"); } +#if USE_NEW_ESIL +static bool mw(int *ec, ut64 addr, const ut8 *old, const ut8 *buf, int len) { + *ec += (len * 2); + return true; +} + +#if 0 +static bool rw(void *null, const char *regname, ut64 old, ut64 num) { + return true; +} + +static bool rr(void *null, const char *regname, ut64 num) { + return true; +} +#endif + +static bool mr(int *ec, ut64 addr, const ut8 *buf, int len) { + *ec += len; + return true; +} + +#else static bool mw(REsil *esil, ut64 addr, const ut8 *buf, int len) { int *ec = (int*)esil->user; @@ -2466,12 +2488,23 @@ static bool mr(REsil *esil, ut64 addr, ut8 *buf, int len) { *ec += len; return true; } +#endif static int esil_cost(RCore *core, ut64 addr, const char *expr) { if (R_STR_ISEMPTY (expr)) { return 0; } int ec = 0; +#if USE_NEW_ESIL + REsil *e = r_esil_new_simple (0, core->anal->reg, &core->anal->iob); + //preserve regs? enforce ro mem access? + r_esil_add_voyeur (e, &ec, mr, R_ESIL_VOYEUR_MEM_READ); + r_esil_add_voyeur (e, &ec, mw, R_ESIL_VOYEUR_MEM_WRITE); +#if 0 + r_esil_add_voyeur (e, NULL, rr, R_ESIL_VOYEUR_REG_READ); + r_esil_add_voyeur (e, NULL, rw, R_ESIL_VOYEUR_REG_WRITE); +#endif +#else REsil *e = r_esil_new (256, 0, 0); r_esil_setup (e, core->anal, false, false, false); e->user = &ec; @@ -2479,6 +2512,7 @@ static int esil_cost(RCore *core, ut64 addr, const char *expr) { e->cb.mem_write = mw; e->cb.reg_write = rw; e->cb.reg_read = rr; +#endif r_esil_parse (e, expr); r_esil_free (e); return ec; From d0b2f2770a4104eb49e5ed5265c1791b1ef9d7a3 Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 7 May 2025 02:24:04 +0200 Subject: [PATCH 32/61] Fix esil_toc --- libr/esil/esil_toc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libr/esil/esil_toc.c b/libr/esil/esil_toc.c index e8f0a352074fd..4a80e5433be25 100644 --- a/libr/esil/esil_toc.c +++ b/libr/esil/esil_toc.c @@ -185,7 +185,11 @@ static void esil2c_free(REsilC *user) { free (user); } +#if USE_NEW_ESIL +static bool esil2c_mw(void *null, ut64 addr, const ut8 *old, const ut8 *buf, int len) { +#else static bool esil2c_mw(REsil *esil, ut64 addr, const ut8 *buf, int len) { +#endif R_LOG_TODO ("poke%d 0x%08"PFMT64x" %d", len, addr, *buf); return true; } From 670657e72995ddba943790207ab6aa5657aebfd0 Mon Sep 17 00:00:00 2001 From: condret Date: Wed, 7 May 2025 04:09:53 +0200 Subject: [PATCH 33/61] Continue massaging cmd_anal.inc.c for new esil api --- libr/core/cmd_anal.inc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 9c4181b42142f..57d0bda102fed 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2574,22 +2574,35 @@ static void val_tojson(PJ *pj, RAnalValue *val) { pj_end (pj); } - +#if USE_NEW_ESIL +static bool mw2(void *null, ut64 addr, const ut8 *old, const ut8 *buf, int len) { +#else static bool mw2(REsil *esil, ut64 addr, const ut8 *buf, int len) { R_LOG_INFO ("WRITE 0x%08"PFMT64x" %d", addr, len); +#endif return true; } +#if USE_NEW_ESIL +static bool mr2(void *null, ut64 addr, const ut8 *buf, int len) { +#else static bool mr2(REsil *esil, ut64 addr, ut8 *buf, int len) { R_LOG_INFO ("READ 0x%08"PFMT64x" %d", addr, len); +#endif return true; } static void esilmemrefs(RCore *core, const char *expr) { +#if USE_NEW_ESIL + REsil *e = r_esil_new_simple (0, core->anal->reg, &core->anal->iob); + r_esil_add_voyeur (e, NULL, mw2, R_ESIL_VOYEUR_MEM_WRITE); + r_esil_add_voyeur (e, NULL, mr2, R_ESIL_VOYEUR_MEM_READ); +#else REsil *e = r_esil_new (256, 0, 0); r_esil_setup (e, core->anal, false, false, false); e->cb.mem_read = mr2; e->cb.mem_write = mw2; +#endif r_esil_parse (e, expr); r_esil_free (e); } @@ -2607,20 +2620,7 @@ static void core_anal_bytes(RCore *core, const ut8 *buf, int len, int nops, int ut64 addr; PJ *pj = NULL; int totalsize = 0; -#if 1 - REsil *esil = r_esil_new (256, 0, 0); - r_esil_setup (esil, core->anal, false, false, false); - esil->user = &core; - esil->cb.mem_read = mr; - esil->cb.mem_write = mw; -#else - REsil *esil = core->anal->esil; - //esil->user = &ec; - esil->cb.mem_read = mr; - esil->cb.mem_write = mw; -#endif - // Variables required for setting up ESIL to REIL conversion if (use_color) { color = core->cons->context->pal.label; } @@ -3099,7 +3099,6 @@ static void core_anal_bytes(RCore *core, const ut8 *buf, int len, int nops, int r_cons_println (core->cons, pj_string (pj)); pj_free (pj); } - r_esil_free (esil); } static int bb_cmp(const void *a, const void *b) { @@ -8461,6 +8460,7 @@ static void cmd_debug_stack_init(RCore *core, int argc, char **argv, char **envp } R_IPI void cmd_aei(RCore *core) { +//TODO use core_esil here REsil *esil = esil_new_setup (core); if (esil) { r_esil_free (core->anal->esil); From bc1bbfcaaafc300c6c3be12d982a70957853df1d Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 8 May 2025 02:30:21 +0200 Subject: [PATCH 34/61] Add anal specific esil mem and reg interfaces --- libr/anal/anal.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-- libr/core/core.c | 4 --- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 4ea9f42a9f018..378d462ffd99a 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -69,6 +69,81 @@ static void r_meta_item_free(void *_item) { } } +#if USE_NEW_ESIL +static bool anal_esil_mem_switch (void *mem, ut32 idx) { + RAnal *anal = mem; + if (!anal || !anal->iob.init) { + R_LOG_WARN ("anal->iob is not setup"); + return false; + } + return anal->iob.bank_use (anal->iob.io, idx); +} + +static bool anal_esil_mem_read (void *mem, ut64 addr, ut8 *buf, int len) { + RAnal *anal = mem; + if (!anal || !anal->iob.init) { + R_LOG_WARN ("anal->iob is not setup"); + return false; + } + return anal->iob.read_at (anal->iob.io, addr, buf, len); +} + +static bool anal_esil_mem_write (void *mem, ut64 addr, const ut8 *buf, int len) { + RAnal *anal = mem; + if (!anal || !anal->iob.init) { + R_LOG_WARN ("anal->iob is not setup"); + return false; + } + return anal->iob.write_at (anal->iob.io, addr, buf, len); +} + +REsilMemInterface anal_esil_mem_if = { + .mem_switch = anal_esil_mem_switch, + .mem_read = anal_esil_mem_read, + .mem_write = anal_esil_mem_write +}; + +static bool anal_esil_is_reg (void *user, const char *name) { + RRegItem *ri = r_reg_get (((RAnal *)user)->reg, name, -1); + if (!ri) { + return false; + } + r_unref (ri); + return true; +} + +static bool anal_esil_reg_read (void *user, const char *name, ut64 *val) { + RRegItem *ri = r_reg_get (((RAnal *)user)->reg, name, -1); + if (!ri) { + return false; + } + *val = r_reg_get_value (((RAnal *)user)->reg, ri); + r_unref (ri); + return true; +} + +static bool anal_esil_reg_write (void *user, const char *name, ut64 val) { + return r_reg_setv (((RAnal *)user)->reg, name, val); +} + +static ut32 anal_esil_reg_size (void *user, const char *name) { + RRegItem *ri = r_reg_get (((RAnal *)user)->reg, name, -1); + if (!ri) { + return 0; + } + const ut32 size = ri->size; + r_unref (ri); + return size; +} + +static REsilRegInterface anal_esil_reg_if = { + .is_reg = anal_esil_is_reg, + .reg_read = anal_esil_reg_read, + .reg_write = anal_esil_reg_write, + .reg_size = anal_esil_reg_size +}; +#endif + // Take nullable RArchConfig as argument? R_API RAnal *r_anal_new(void) { int i; @@ -113,10 +188,14 @@ R_API RAnal *r_anal_new(void) { anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1); anal->zign_path = strdup (""); anal->cb_printf = (PrintfCallback) printf; -#if USE_NEW_ESIL == 0 +#if USE_NEW_ESIL + anal_esil_reg_if.user = anal; + anal_esil_mem_if.user = anal; + anal->esil = r_esil_new_ex (4096, 0, 1, &anal_esil_reg_if, &anal_esil_mem_if); +#else anal->esil = r_esil_new (4096, 0, 1); - anal->esil->anal = anal; #endif + anal->esil->anal = anal; (void)r_anal_pin_init (anal); (void)r_anal_xrefs_init (anal); anal->diff_thbb = R_ANAL_THRESHOLDBB; diff --git a/libr/core/core.c b/libr/core/core.c index 4fdbdf31717d4..859aff7634c14 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2710,10 +2710,6 @@ R_API bool r_core_init(RCore *core) { r_io_bind (core->io, &(core->fs->iob)); r_cons_bind (core->cons, &(core->fs->csb)); r_cons_bind (core->cons, &(core->search->consb)); -#if USE_NEW_ESIL - core->anal->esil = r_esil_new_simple (1, core->anal->reg, &core->anal->iob); - core->anal->esil->anal = core->anal; -#endif r_core_bind (core, &(core->fs->cob)); r_io_bind (core->io, &(core->bin->iob)); r_flag_bind (core->flags, &(core->anal->flb)); From b5b9c1a098f13cef350476e087cedab112f209fd Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 8 May 2025 03:56:04 +0200 Subject: [PATCH 35/61] Use esil->reg_if.is_reg in not_a_number (libr/esil/esil.c) if new esil api is used --- libr/esil/esil.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 709d4053113a6..ad127c2cea9df 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -554,9 +554,13 @@ R_API char *r_esil_pop(REsil *esil) { } static int not_a_number(REsil *esil, const char *str) { +#if USE_NEW_ESIL + if (esil->reg_if.is_reg (esil->reg_if.reg, str)) { +#else RRegItem *ri = r_reg_get (esil->anal->reg, str, -1); if (ri) { r_unref (ri); +#endif return R_ESIL_PARM_REG; } return R_ESIL_PARM_INVALID; From a333fe065e393c45d672a09d0d926010ac381da5 Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 8 May 2025 04:10:56 +0200 Subject: [PATCH 36/61] Further massage cmd_anal.inc.c for new esil api --- libr/core/cmd_anal.inc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 57d0bda102fed..c2f242dff7c0e 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2497,6 +2497,7 @@ static int esil_cost(RCore *core, ut64 addr, const char *expr) { int ec = 0; #if USE_NEW_ESIL REsil *e = r_esil_new_simple (0, core->anal->reg, &core->anal->iob); + e->anal = core->anal; //XXX //preserve regs? enforce ro mem access? r_esil_add_voyeur (e, &ec, mr, R_ESIL_VOYEUR_MEM_READ); r_esil_add_voyeur (e, &ec, mw, R_ESIL_VOYEUR_MEM_WRITE); @@ -2597,6 +2598,7 @@ static void esilmemrefs(RCore *core, const char *expr) { REsil *e = r_esil_new_simple (0, core->anal->reg, &core->anal->iob); r_esil_add_voyeur (e, NULL, mw2, R_ESIL_VOYEUR_MEM_WRITE); r_esil_add_voyeur (e, NULL, mr2, R_ESIL_VOYEUR_MEM_READ); + e->anal = core->anal; //XXX #else REsil *e = r_esil_new (256, 0, 0); r_esil_setup (e, core->anal, false, false, false); From c6babb6b00a8c015ff086637516d499c456ac6fa Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 10 May 2025 01:47:33 +0200 Subject: [PATCH 37/61] Add mdev and ioer support to core_esil --- libr/core/cconfig.c | 30 ++++++++++++++++++++++++------ libr/core/core_esil.c | 23 ++++++++++++++++++++--- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 4a57dee0c1dff..618d864c6a1cc 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -2131,12 +2131,18 @@ R_API bool r_core_esil_cmd(REsil *esil, const char *cmd, ut64 a1, ut64 a2) { } static bool cb_cmd_esil_ioer(void *user, void *data) { - RCore *core = (RCore *) user; - RConfigNode *node = (RConfigNode *) data; + RCore *core = user; + RConfigNode *node = data; +#if USE_NEW_ESIL + if (core) { + free (core->esil.cmd_ioer); + core->esil.cmd_ioer = strdup (node->value); +#else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; free (core->anal->esil->cmd_ioer); core->anal->esil->cmd_ioer = strdup (node->value); +#endif } return true; } @@ -2164,12 +2170,18 @@ static bool cb_cmd_esil_intr(void *user, void *data) { } static bool cb_mdevrange(void *user, void *data) { - RCore *core = (RCore *) user; - RConfigNode *node = (RConfigNode *) data; + RCore *core = user; + RConfigNode *node = data; +#if USE_NEW_ESIL + if (core) { + free (core->esil.mdev_range); + core->esil.mdev_range = strdup (node->value); +#else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; free (core->anal->esil->mdev_range); core->anal->esil->mdev_range = strdup (node->value); +#endif } return true; } @@ -2207,12 +2219,18 @@ static bool cb_cmd_esil_step_out(void *user, void *data) { } static bool cb_cmd_esil_mdev(void *user, void *data) { - RCore *core = (RCore *) user; - RConfigNode *node = (RConfigNode *) data; + RCore *core = user; + RConfigNode *node = data; +#if USE_NEW_ESIL + if (core) { + free (core->esil.cmd_mdev); + core->esil.cmd_mdev = strdup (node->value); +#else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; free (core->anal->esil->cmd_mdev); core->anal->esil->cmd_mdev = strdup (node->value); +#endif } return true; } diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 8410cb4fb102b..c27d1dc3e5cdd 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2024 - condret */ +/* radare - LGPL - Copyright 2024 - 2025 - condret */ #define R_LOG_ORIGIN "core.esil" #include @@ -85,6 +85,10 @@ static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) { if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } + if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { + r_core_cmdf (c, "%s %"PFMT64d" 0", c->esil.cmd_mdev, c->esil.old_pc); + return c->num->value; + } return r_io_read_at (c->io, addr, buf, len); } @@ -100,6 +104,10 @@ static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } + if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { + r_core_cmdf (c, "%s %"PFMT64d" 1", c->esil.cmd_mdev, c->esil.old_pc); + return c->num->value; + } if (c->esil.cfg & R_CORE_ESIL_RO) { RIORegion region; if (!r_io_get_region_at (c->io, ®ion, addr)) { @@ -274,6 +282,7 @@ R_API void r_core_esil_single_step(RCore *core) { r_anal_hint_free (hint); hint = NULL; } + ut32 trap_code = R_ANAL_TRAP_NONE; if (op.size < 1 || op.type == R_ANAL_OP_TYPE_ILL || op.type == R_ANAL_OP_TYPE_UNK) { goto op_trap; @@ -301,11 +310,11 @@ R_API void r_core_esil_single_step(RCore *core) { } return; } + trap_code = core->esil.esil.trap_code; if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { //disable trap_revert voyeurs core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; char *expr = r_strbuf_drain_nofree (&core->esil.trap_revert); - //TODO: check trap codes here //revert all changes r_esil_parse (&core->esil.esil, expr); free (expr); @@ -313,7 +322,6 @@ R_API void r_core_esil_single_step(RCore *core) { } //restore pc r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); - //TODO: check trap codes here goto trap; op_trap: r_anal_op_fini (&op); @@ -321,6 +329,15 @@ R_API void r_core_esil_single_step(RCore *core) { if (core->esil.cmd_trap) { r_core_cmd0 (core, core->esil.cmd_trap); } + switch (trap_code) { + case R_ANAL_TRAP_WRITE_ERR: + case R_ANAL_TRAP_READ_ERR: + if (core->esil.cmd_ioer) { + r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL); + r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, pc); + } + break; + } return; } From b233134b03fa2f8edff5944ae288d635ca2d3c7f Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 10 May 2025 05:29:21 +0200 Subject: [PATCH 38/61] Add cmd_step and cmd_step_out support to core_esil --- libr/core/cconfig.c | 20 ++++++++++++++++---- libr/core/core_esil.c | 23 ++++++++++++++++++----- libr/include/r_core.h | 6 ++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 618d864c6a1cc..76263454cdc56 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -2197,23 +2197,35 @@ static bool cb_cmd_esil_pin(void *user, void *data) { } static bool cb_cmd_esil_step(void *user, void *data) { - RCore *core = (RCore *) user; - RConfigNode *node = (RConfigNode *) data; + RCore *core = user; + RConfigNode *node = data; +#if USE_NEW_ESIL + if (core) { + free (core->esil.cmd_step); + core->esil.cmd_step = strdup (node->value); +#else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; free (core->anal->esil->cmd_step); core->anal->esil->cmd_step = strdup (node->value); +#endif } return true; } static bool cb_cmd_esil_step_out(void *user, void *data) { - RCore *core = (RCore *) user; - RConfigNode *node = (RConfigNode *) data; + RCore *core = user; + RConfigNode *node = data; +#if USE_NEW_ESIL + if (core) { + free (core->esil.cmd_step_out); + core->esil.cmd_step_out = strdup (node->value); +#else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; free (core->anal->esil->cmd_step_out); core->anal->esil->cmd_step_out = strdup (node->value); +#endif } return true; } diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index c27d1dc3e5cdd..022d4ae04e755 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -85,6 +85,7 @@ static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) { if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } + if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { r_core_cmdf (c, "%s %"PFMT64d" 0", c->esil.cmd_mdev, c->esil.old_pc); return c->num->value; @@ -232,6 +233,7 @@ R_API void r_core_esil_single_step(RCore *core) { R_LOG_ERROR ("Couldn't read from PC register"); return; } + ut32 trap_code = R_ANAL_TRAP_READ_ERR; //check if pc is in mapped rx area, //or in case io is pa //check if pc is within desc and desc is at least readable @@ -243,6 +245,7 @@ R_API void r_core_esil_single_step(RCore *core) { (!core->io->va && !(region.perm & R_PERM_R))) { goto trap; } + trap_code = R_ANAL_TRAP_NONE; int max_opsize = R_MIN (64, r_arch_info (core->anal->arch, R_ARCH_INFO_MAXOP_SIZE)); if (R_UNLIKELY (max_opsize < 1)) { @@ -282,7 +285,6 @@ R_API void r_core_esil_single_step(RCore *core) { r_anal_hint_free (hint); hint = NULL; } - ut32 trap_code = R_ANAL_TRAP_NONE; if (op.size < 1 || op.type == R_ANAL_OP_TYPE_ILL || op.type == R_ANAL_OP_TYPE_UNK) { goto op_trap; @@ -296,18 +298,29 @@ R_API void r_core_esil_single_step(RCore *core) { "0x%"PFMT64x",%s,:=", pc, pc_name); } else { core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; - core->esil.old_pc = pc; } + core->esil.old_pc = pc; pc += op.size; char *expr = r_strbuf_drain_nofree (&op.esil); - r_anal_op_fini (&op); r_esil_reg_write_silent (&core->esil.esil, pc_name, pc); + r_anal_op_fini (&op); + if (core->esil.cmd_step) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step, core->esil.old_pc); + if (core->num->value) { + free (expr); + goto skip; + } + } const bool suc = r_esil_parse (&core->esil.esil, expr); free (expr); if (suc) { +skip: if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { r_strbuf_fini (&core->esil.trap_revert); } + if (core->esil.cmd_step_out) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step_out, core->esil.old_pc); + } return; } trap_code = core->esil.esil.trap_code; @@ -333,8 +346,8 @@ R_API void r_core_esil_single_step(RCore *core) { case R_ANAL_TRAP_WRITE_ERR: case R_ANAL_TRAP_READ_ERR: if (core->esil.cmd_ioer) { - r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL); - r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, pc); + r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, + core->esil.old_pc); } break; } diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 9ef28704a549a..c9e5054bd63a9 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -309,10 +309,16 @@ typedef struct { typedef struct r_core_esil_t { REsil esil; +#if 0 union { RStrBuf trap_revert; ut64 old_pc; }; +#else + //ideally this would be a union, but cmd_mdev need to know the old pc + RStrBuf trap_revert; + ut64 old_pc; +#endif ut32 tr_reg; ut32 tr_mem; RReg *reg; From b5de016634c58f067691c46768c656a90d74feae Mon Sep 17 00:00:00 2001 From: condret Date: Sun, 11 May 2025 08:00:28 +0200 Subject: [PATCH 39/61] Implement step back capabilities in RCoreEsil --- libr/core/core_esil.c | 69 +++++++++++++++++++++++++++++++++++++++++-- libr/include/r_core.h | 17 ++++++----- 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 022d4ae04e755..e524e3ff19fd9 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -148,6 +148,9 @@ static void core_esil_voyeur_trap_revert_mem_write (void *user, ut64 addr, if (!(cesil->cfg & R_CORE_ESIL_TRAP_REVERT)) { return; } + if (cesil->cfg & R_CORE_ESIL_RO) { + return; + } int i; for (i = 0; i < len; i++) { //TODO: optimize this after breaking @@ -156,8 +159,17 @@ static void core_esil_voyeur_trap_revert_mem_write (void *user, ut64 addr, } } +static void core_esil_stepback_free (void *data) { + if (data) { + RCoreEsilStepBack *cesb = data; + free (cesb->expr); + free (data); + } +} + R_API bool r_core_esil_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io, false); + core->esil = (const RCoreEsil){0}; core->esil.reg = r_reg_new (); if (!core->esil.reg) { return false; @@ -179,6 +191,7 @@ R_API bool r_core_esil_init(RCore *core) { 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); + core->esil.stepback.free = core_esil_stepback_free; return true; op_fail: r_esil_fini (&core->esil.esil); @@ -292,7 +305,7 @@ R_API void r_core_esil_single_step(RCore *core) { if (!r_itv_contain (region.itv, pc + op.size)) { goto op_trap; } - if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) { + if ((core->esil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->esil.max_stepback) { core->esil.cfg |= R_CORE_ESIL_TRAP_REVERT; r_strbuf_initf (&core->esil.trap_revert, "0x%"PFMT64x",%s,:=", pc, pc_name); @@ -316,7 +329,38 @@ R_API void r_core_esil_single_step(RCore *core) { if (suc) { skip: if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { - r_strbuf_fini (&core->esil.trap_revert); + if (core->esil.max_stepback) { + if (core->esil.max_stepback > r_list_length (&core->esil.stepback)) { + RCoreEsilStepBack *cesb = R_NEW (RCoreEsilStepBack); + if (!cesb) { + R_LOG_WARN ("RCoreEsilStepBack allocation failed"); + r_strbuf_fini (&core->esil.trap_revert); + } else { + if (!r_list_push (&core->esil.stepback, cesb)) { + R_LOG_WARN ("Pushing RCoreEsilStepBack failed"); + } else { + cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + cesb->addr = core->esil.old_pc; + } + } + } else { + //this is like r_list_pop_head + r_list_push, + //but without expensive calls to malloc and free + RListIter *iter = core->esil.stepback.head; + iter->p->n = NULL; + core->esil.stepback.head = iter->p; + iter->p = NULL; + iter->n = core->esil.stepback.tail; + core->esil.stepback.tail->p = iter; + core->esil.stepback.tail = iter; + RCoreEsilStepBack *cesb = iter->data; + free (cesb->expr); + cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + cesb->addr = core->esil.old_pc; + } + } else { + r_strbuf_fini (&core->esil.trap_revert); + } } if (core->esil.cmd_step_out) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step_out, core->esil.old_pc); @@ -354,6 +398,26 @@ R_API void r_core_esil_single_step(RCore *core) { return; } +R_API void r_core_esil_stepback (RCore *core) { + R_RETURN_IF_FAIL (core && core->io && core->esil.reg); + if (!r_list_length (&core->esil.stepback)) { + //not an error + return; + } + RCoreEsilStepBack *cesb = r_list_pop (&core->esil.stepback); + core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + r_esil_parse (&core->esil.esil, cesb->expr); + core_esil_stepback_free (cesb); +} + +R_API void r_core_esil_set_max_stepback (RCore *core, ut32 max_stepback) { + R_RETURN_IF_FAIL (core && core->esil.stepback.free); + core->esil.max_stepback = max_stepback; + while (r_list_length (&core->esil.stepback) > max_stepback) { + core_esil_stepback_free (r_list_pop_head (&core->esil.stepback)); + } +} + R_API void r_core_esil_fini(RCoreEsil *cesil) { R_RETURN_IF_FAIL (cesil); r_esil_del_voyeur (&cesil->esil, cesil->tr_reg); @@ -372,5 +436,6 @@ R_API void r_core_esil_fini(RCoreEsil *cesil) { R_FREE (cesil->cmd_todo); R_FREE (cesil->cmd_ioer); R_FREE (cesil->mdev_range); + r_list_purge (&cesil->stepback); cesil->esil = (const REsil){0}; } diff --git a/libr/include/r_core.h b/libr/include/r_core.h index c9e5054bd63a9..ebb16769e2751 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -307,18 +307,16 @@ typedef struct { int y; } VisualMark; +typedef struct r_core_esil_stepback_t { + char *expr; + ut64 addr; +} RCoreEsilStepBack; + typedef struct r_core_esil_t { REsil esil; -#if 0 - union { - RStrBuf trap_revert; - ut64 old_pc; - }; -#else - //ideally this would be a union, but cmd_mdev need to know the old pc + RList stepback; RStrBuf trap_revert; ut64 old_pc; -#endif ut32 tr_reg; ut32 tr_mem; RReg *reg; @@ -330,6 +328,7 @@ typedef struct r_core_esil_t { char *cmd_todo; // command to run when esil expr contains TODO char *cmd_ioer; // command to run when esil fails to IO char *mdev_range; // string containing the r_str_range to match for read/write accesses + ut32 max_stepback; ut8 cfg; } RCoreEsil; @@ -796,6 +795,8 @@ R_API void r_core_esil_fini(RCoreEsil *cesil); R_API void r_core_esil_load_arch(RCore *core); R_API void r_core_esil_unload_arch(RCore *core); R_API void r_core_esil_single_step(RCore *core); +R_API void r_core_esil_stepback(RCore *core); //replacement for r_core_esil_step_back; rename later +R_API void r_core_esil_set_max_stepback(RCore *core, ut32 max_stepback); // both do the same, we should get rid of one of them R_API bool r_core_bin_raise(RCore *core, ut32 bfid); From 1348d8fb69f4b7ac562ca7d71c0ab3c00c50b577 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 26 May 2025 07:18:59 +0200 Subject: [PATCH 40/61] Add esil back step config var --- libr/core/cconfig.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 76263454cdc56..b77fae9135689 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -1877,6 +1877,15 @@ static bool cb_gotolimit(void *user, void *data) { return true; } +static bool cb_esilmaxbacksteps(void *user, void *data) { + RCore *core = user; + RConfigNode *node = data; + if (core->esil.reg) { //hack + r_core_esil_set_max_stepback (core, node->i_value); + } + return true; +} + static bool cb_esilverbose(void *user, void *data) { RCore *core = user; RConfigNode *node = data; @@ -3777,6 +3786,7 @@ R_API int r_core_config_init(RCore *core) { SETB ("dbg.glibc.demangle", "false", "demangle linked-lists pointers introduced in glibc 2.32"); SETB ("esil.prestep", "true", "step before esil evaluation in `de` commands"); SETI ("esil.maxsteps", 0, "If !=0 defines the maximum amount of steps to perform on aesu/aec/.."); + SETICB ("esil.maxbacksteps", 256, &cb_esilmaxbacksteps, "esil back step capacity"); SETS ("esil.fillstack", "", "initialize ESIL stack with (random, debruijn, sequence, zeros, ...)"); SETICB ("esil.verbose", 0, &cb_esilverbose, "show ESIL verbose level (0, 1, 2)"); SETICB ("esil.gotolimit", core->anal->esil_goto_limit, &cb_gotolimit, "maximum number of gotos per ESIL expression"); From d20e48714565f35bfc28a9e5a4e03bbde2542b07 Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 27 May 2025 14:20:24 +0200 Subject: [PATCH 41/61] Initialize core_esil on core init and autoupdate on arch config changes --- libr/core/cconfig.c | 36 +++++++++++++++++++++++++++++++++--- libr/core/core.c | 6 ++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index b77fae9135689..573c35574f942 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -464,9 +464,15 @@ static bool cb_arch_platform(void *user, void *data) { static bool cb_archbits(void *user, void *data) { R_RETURN_VAL_IF_FAIL (user && data, false); - RCore *core = (RCore *)user; + RCore *core = user; +#if USE_NEW_ESIL + r_core_esil_unload_arch (core); +#endif RConfigNode *node = (RConfigNode *)data; r_arch_set_bits (core->anal->arch, node->i_value); +#if USE_NEW_ESIL + r_core_esil_load_arch (core); +#endif return true; } @@ -479,15 +485,27 @@ static bool cb_archbits_getter(RCore *core, RConfigNode *node) { } static bool cb_archendian(void *user, void *data) { - RCore *core = (RCore *)user; - RConfigNode *node = (RConfigNode *)data; + RCore *core = user; + RConfigNode *node = data; R_RETURN_VAL_IF_FAIL (node && core && core->anal && core->anal->arch, false); if (!strcmp (node->value, "big") || !strcmp (node->value, "bigswap")) { +#if USE_NEW_ESIL + r_core_esil_unload_arch (core); +#endif r_arch_set_endian (core->anal->arch, R_SYS_ENDIAN_BIG); +#if USE_NEW_ESIL + r_core_esil_load_arch (core); +#endif return true; } if (!strcmp (node->value, "little") || !strcmp (node->value, "littleswap")) { +#if USE_NEW_ESIL + r_core_esil_unload_arch (core); +#endif r_arch_set_endian (core->anal->arch, R_SYS_ENDIAN_LITTLE); +#if USE_NEW_ESIL + r_core_esil_load_arch (core); +#endif return true; } return false; @@ -684,7 +702,13 @@ static bool cb_asmcpu(void *user, void *data) { #endif return 0; } +#if USE_NEW_ESIL + r_core_esil_unload_arch (core); +#endif r_arch_config_set_cpu (core->rasm->config, node->value); +#if USE_NEW_ESIL + r_core_esil_load_arch (core); +#endif const int v = r_anal_archinfo (core->anal, R_ARCH_INFO_CODE_ALIGN); if (v >= 0) { core->anal->config->codealign = v; @@ -1285,7 +1309,13 @@ static bool cb_bigendian(void *user, void *data) { } core->rasm->config->endian = endianType; +#if USE_NEW_ESIL + r_core_esil_unload_arch (core); +#endif r_arch_set_endian (core->anal->arch, endianType); +#if USE_NEW_ESIL + r_core_esil_load_arch (core); +#endif return true; } diff --git a/libr/core/core.c b/libr/core/core.c index 859aff7634c14..7a1153e3390ed 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2740,6 +2740,9 @@ R_API bool r_core_init(RCore *core) { core->io->cb_printf = r_cons_gprintf; core->dbg->cb_printf = r_cons_gprintf; core->dbg->ev = core->ev; +#if USE_NEW_ESIL + r_core_esil_init (core); +#endif r_core_config_init (core); r_core_loadlibs_init (core); //r_core_loadlibs (core); @@ -2845,6 +2848,9 @@ R_API void r_core_fini(RCore *c) { /* r_unref (c->anal->config); */ +#if USE_NEW_ESIL + r_core_esil_fini (&c->esil); +#endif if (c->anal->esil) { c->anal->esil->anal = NULL; } From a1a843fbcedcc3d6c1d7ae543b84044dc5f7e20e Mon Sep 17 00:00:00 2001 From: condret Date: Thu, 5 Jun 2025 15:52:45 +0200 Subject: [PATCH 42/61] Start rewriting r_core_esil_step --- libr/core/cmd_anal.inc.c | 74 ++++++++++++++++++++++++++++++++++++++++ libr/core/core_esil.c | 14 ++++---- libr/include/r_core.h | 2 +- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index c2f242dff7c0e..ce4a7ee6f949d 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7222,6 +7222,80 @@ void cmd_anal_reg(RCore *core, const char *str) { } } +#if 0 +R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) { + const bool is_x86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86"); + const bool r2wars = is_x86 && r_config_get_b (core->config, "cfg.r2wars"); + const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid"); + const int esiltimeout = r_config_get_i (core->config, "esil.timeout"); + int ret = true; + ut64 startTime = 0; + + if (esiltimeout > 0) { + startTime = r_time_now_mono (); + } + ut64 addr = r_reg_getv (core->esil.reg, "PC"); + r_cons_break_push (NULL, NULL); + while (addr != until_addr) { + if (esiltimeout > 0) { + ut64 elapsedTime = r_time_now_mono () - startTime; + elapsedTime >>= 20; + if (elapsedTime >= esiltimeout) { + R_LOG_INFO ("[ESIL] Timeout exceeded"); + ret = false; + break; + } + } + RAnalOp op; + if (until_expr || stepOver) { + r_anal_op_init (&op); + ut8 buf[64]; + r_io_read_at (core->io, addr, buf, 64); + r_anal_op_set_bytes (&op, addr, buf, 64); + r_arch_decode (core->anal->arch, &op, R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_ESIL); + } + if (until_expr) { + RAnalHint *hint = r_anal_hint_get (core->anal, addr); + if (hint && hint->esil) { + r_strbuf_set (&op.esil, hint->esil); + } + if (!strcmp (r_strbuf_get (&op.esil), until_expr)) { + r_anal_op_fini (&op); + break; + } + } + if (prev_addr) { + prev_addr[0] = addr; + } + if (stepOver) { + switch (op.type) { + case R_ANAL_OP_TYPE_SWI: + case R_ANAL_OP_TYPE_UCALL: + case R_ANAL_OP_TYPE_CALL: + case R_ANAL_OP_TYPE_JMP: + case R_ANAL_OP_TYPE_RCALL: + case R_ANAL_OP_TYPE_RJMP: + case R_ANAL_OP_TYPE_CJMP: + case R_ANAL_OP_TYPE_RET: + case R_ANAL_OP_TYPE_CRET: + case R_ANAL_OP_TYPE_UJMP: + r_reg_setv (core->esil.reg, "PC", op.addr + op.size); + } + if (until_expr || stepOver) { + r_anal_op_fini (&op); + } + if (!r_core_esil_single_step (core)) { + ret = false; + break; + } + addr = r_reg_getv (core->esil.reg, "PC"); + } + r_cons_break_pop (); + return ret; +} + +#endif + R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) { #define return_tail(x) { tail_return_value = x; goto tail_return; } int tail_return_value = 0; diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index e524e3ff19fd9..8c3fdcfecc5de 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -234,17 +234,17 @@ R_API void r_core_esil_unload_arch(RCore *core) { core->anal->arch->esil = arch_esil; } -R_API void r_core_esil_single_step(RCore *core) { +R_API bool r_core_esil_single_step(RCore *core) { R_RETURN_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->esil.reg); const char *pc_name = r_reg_alias_getname (core->esil.reg, R_REG_ALIAS_PC); if (!pc_name) { R_LOG_ERROR ("CoreEsil reg profile has no pc register"); - return; + return false; } ut64 pc; if (!r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL)) { R_LOG_ERROR ("Couldn't read from PC register"); - return; + return false; } ut32 trap_code = R_ANAL_TRAP_READ_ERR; //check if pc is in mapped rx area, @@ -268,7 +268,7 @@ R_API void r_core_esil_single_step(RCore *core) { ut8 buf[64]; if (R_UNLIKELY (!r_io_read_at (core->io, pc, buf, max_opsize))) { R_LOG_ERROR ("Couldn't read data to decode from 0x%"PFMT64x, pc); - return; + return false; } RAnalOp op; r_anal_op_init (&op); @@ -279,7 +279,7 @@ R_API void r_core_esil_single_step(RCore *core) { R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_ESIL)) { R_LOG_ERROR ("COuldn't decode instruction at 0x%"PFMT64x, pc); r_anal_op_fini (&op); - return; + return false; } RAnalHint *hint = r_anal_hint_get (core->anal, pc); if (hint) { @@ -365,7 +365,7 @@ R_API void r_core_esil_single_step(RCore *core) { if (core->esil.cmd_step_out) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step_out, core->esil.old_pc); } - return; + return true; } trap_code = core->esil.esil.trap_code; if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { @@ -395,7 +395,7 @@ R_API void r_core_esil_single_step(RCore *core) { } break; } - return; + return false; } R_API void r_core_esil_stepback (RCore *core) { diff --git a/libr/include/r_core.h b/libr/include/r_core.h index ebb16769e2751..56e01f79cf8ab 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -794,7 +794,7 @@ R_API bool r_core_esil_init(RCore *core); R_API void r_core_esil_fini(RCoreEsil *cesil); R_API void r_core_esil_load_arch(RCore *core); R_API void r_core_esil_unload_arch(RCore *core); -R_API void r_core_esil_single_step(RCore *core); +R_API bool r_core_esil_single_step(RCore *core); R_API void r_core_esil_stepback(RCore *core); //replacement for r_core_esil_step_back; rename later R_API void r_core_esil_set_max_stepback(RCore *core, ut32 max_stepback); From faf8e0c6b283afcc3855b1a7142d6e948a15aacd Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 10 Jun 2025 10:21:27 +0200 Subject: [PATCH 43/61] Add r_core_esil_run_expr_at and fix some things pointed out by @trufae --- libr/core/cmd_search.inc.c | 2 +- libr/core/core_esil.c | 85 +++++++++++++++++++++++++++++++++++++- libr/esil/esil.c | 11 +++-- libr/include/r_core.h | 1 + 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/libr/core/cmd_search.inc.c b/libr/core/cmd_search.inc.c index 8b40993dede99..533f54a1a4f7a 100644 --- a/libr/core/cmd_search.inc.c +++ b/libr/core/cmd_search.inc.c @@ -1882,7 +1882,7 @@ static bool search_esil_reg_read (void *reg, const char *name, ut64 *val) { return true; } -static const ut32 search_esil_reg_size (void *reg, const char *name) { +static ut32 search_esil_reg_size (void *reg, const char *name) { RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); if (!ri) { return 0; diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 8c3fdcfecc5de..4078bee614864 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -234,8 +234,91 @@ R_API void r_core_esil_unload_arch(RCore *core) { core->anal->arch->esil = arch_esil; } +R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr) { + R_RETURN_VAL_IF_FAIL (expr && core && core->anal && core->anal->arch && core->io && core->esil.reg, false); + const char *pc_name = r_reg_alias_getname (core->esil.reg, R_REG_ALIAS_PC); + if (!pc_name) { + R_LOG_ERROR ("CoreEsil reg profile has no pc register"); + return false; + } + ut64 pc; + if (!r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL)) { + R_LOG_ERROR ("Couldn't read from PC register"); + return false; + } + if ((core->esil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->esil.max_stepback) { + core->esil.cfg |= R_CORE_ESIL_TRAP_REVERT; + r_strbuf_initf (&core->esil.trap_revert, + "0x%"PFMT64x",%s,:=", pc, pc_name); + } else { + core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + } + core->esil.old_pc = pc; + r_esil_reg_write_silent (&core->esil.esil, pc_name, addr); + if (r_esil_parse (&core->esil.esil, expr)) { + if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { + if (core->esil.max_stepback) { + if (core->esil.max_stepback > r_list_length (&core->esil.stepback)) { + RCoreEsilStepBack *cesb = R_NEW (RCoreEsilStepBack); + if (!cesb) { + R_LOG_WARN ("RCoreEsilStepBack allocation failed"); + r_strbuf_fini (&core->esil.trap_revert); + } else { + if (!r_list_push (&core->esil.stepback, cesb)) { + R_LOG_WARN ("Pushing RCoreEsilStepBack failed"); + } else { + cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + cesb->addr = core->esil.old_pc; + } + } + } else { + //this is like r_list_pop_head + r_list_push, + //but without expensive calls to malloc and free + RListIter *iter = core->esil.stepback.head; + iter->p->n = NULL; + core->esil.stepback.head = iter->p; + iter->p = NULL; + iter->n = core->esil.stepback.tail; + core->esil.stepback.tail->p = iter; + core->esil.stepback.tail = iter; + RCoreEsilStepBack *cesb = iter->data; + free (cesb->expr); + cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + cesb->addr = core->esil.old_pc; + } + } else { + r_strbuf_fini (&core->esil.trap_revert); + } + } + return true; + } + if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { + //disable trap_revert voyeurs + core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + char *expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + //revert all changes + r_esil_parse (&core->esil.esil, expr); + free (expr); + } else { + r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); + } + if (core->esil.cmd_trap) { + r_core_cmd0 (core, core->esil.cmd_trap); + } + switch (core->esil.esil.trap_code) { + case R_ANAL_TRAP_WRITE_ERR: + case R_ANAL_TRAP_READ_ERR: + if (core->esil.cmd_ioer) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, + core->esil.old_pc); + } + break; + } + return false; +} + R_API bool r_core_esil_single_step(RCore *core) { - R_RETURN_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->esil.reg); + R_RETURN_VAL_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->esil.reg, false); const char *pc_name = r_reg_alias_getname (core->esil.reg, R_REG_ALIAS_PC); if (!pc_name) { R_LOG_ERROR ("CoreEsil reg profile has no pc register"); diff --git a/libr/esil/esil.c b/libr/esil/esil.c index ad127c2cea9df..5ec2fbcaf249d 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -416,12 +416,15 @@ R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { esil->trap = R_ANAL_TRAP_NONE; } if (R_UNLIKELY (!r_esil_mem_write_silent (esil, addr, buf, len))) { + free (o.ptr); return false; } - do { - REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], i); - voy->mem_write (voy->user, addr, o.ptr, buf, len); - } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)); + if (!r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)) { + do { + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], i); + voy->mem_write (voy->user, addr, o.ptr, buf, len); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)); + } free (o.ptr); return true; #else diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 56e01f79cf8ab..b308abf23302e 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -794,6 +794,7 @@ R_API bool r_core_esil_init(RCore *core); R_API void r_core_esil_fini(RCoreEsil *cesil); R_API void r_core_esil_load_arch(RCore *core); R_API void r_core_esil_unload_arch(RCore *core); +R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr); R_API bool r_core_esil_single_step(RCore *core); R_API void r_core_esil_stepback(RCore *core); //replacement for r_core_esil_step_back; rename later R_API void r_core_esil_set_max_stepback(RCore *core, ut32 max_stepback); From d425851b0ea17c0a7295a43d01e75856e26dbc2f Mon Sep 17 00:00:00 2001 From: condret Date: Fri, 20 Jun 2025 03:20:33 +0200 Subject: [PATCH 44/61] Rewrite r_core_esil_step{_back} using new esil api --- libr/core/cmd_anal.inc.c | 27 ++++++++++++++++++++++++--- libr/core/core_esil.c | 11 ++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index ce4a7ee6f949d..8edf5f81f5342 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7222,10 +7222,9 @@ void cmd_anal_reg(RCore *core, const char *str) { } } -#if 0 +#if USE_NEW_ESIL R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) { const bool is_x86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86"); - const bool r2wars = is_x86 && r_config_get_b (core->config, "cfg.r2wars"); const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid"); const int esiltimeout = r_config_get_i (core->config, "esil.timeout"); int ret = true; @@ -7279,7 +7278,16 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, case R_ANAL_OP_TYPE_RET: case R_ANAL_OP_TYPE_CRET: case R_ANAL_OP_TYPE_UJMP: + if (addr % R_MAX (r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN), 1)) { + if (core->esil.cmd_trap) { + r_core_cmd0 (core, core->esil.cmd_trap); + } + r_anal_op_fini (&op); + goto out; + } r_reg_setv (core->esil.reg, "PC", op.addr + op.size); + r_anal_op_fini (&op); + continue; } if (until_expr || stepOver) { r_anal_op_fini (&op); @@ -7290,11 +7298,12 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, } addr = r_reg_getv (core->esil.reg, "PC"); } +out: r_cons_break_pop (); return ret; } -#endif +#else R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) { #define return_tail(x) { tail_return_value = x; goto tail_return; } @@ -7597,6 +7606,17 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, r_cons_break_pop (core->cons); return tail_return_value; } +#endif + +#if USE_NEW_ESIL +R_API bool r_core_esil_step_back(RCore *core) { + R_RETURN_VAL_IF_FAIL (core && core->io && core->esil.reg && + r_list_length (&core->esil.stepback), false); + r_core_esil_stepback (core); + return true; +} + +#else R_API bool r_core_esil_step_back(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->anal, false); @@ -7613,6 +7633,7 @@ R_API bool r_core_esil_step_back(RCore *core) { } return false; } +#endif static void cmd_address_info(RCore *core, const char *addrstr, int fmt) { ut64 addr = R_STR_ISEMPTY (addrstr)? core->addr: r_num_math (core->num, addrstr); diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 4078bee614864..3fd17b1fa8ea8 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -329,7 +329,12 @@ R_API bool r_core_esil_single_step(RCore *core) { R_LOG_ERROR ("Couldn't read from PC register"); return false; } - ut32 trap_code = R_ANAL_TRAP_READ_ERR; + ut32 trap_code = R_ANAL_TRAP_UNALIGNED; + const int align = R_MAX (1, r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN)); + if (pc % align) { + goto trap; + } + trap_code = R_ANAL_TRAP_READ_ERR; //check if pc is in mapped rx area, //or in case io is pa //check if pc is within desc and desc is at least readable @@ -481,7 +486,7 @@ R_API bool r_core_esil_single_step(RCore *core) { return false; } -R_API void r_core_esil_stepback (RCore *core) { +R_API void r_core_esil_stepback(RCore *core) { R_RETURN_IF_FAIL (core && core->io && core->esil.reg); if (!r_list_length (&core->esil.stepback)) { //not an error @@ -493,7 +498,7 @@ R_API void r_core_esil_stepback (RCore *core) { core_esil_stepback_free (cesb); } -R_API void r_core_esil_set_max_stepback (RCore *core, ut32 max_stepback) { +R_API void r_core_esil_set_max_stepback(RCore *core, ut32 max_stepback) { R_RETURN_IF_FAIL (core && core->esil.stepback.free); core->esil.max_stepback = max_stepback; while (r_list_length (&core->esil.stepback) > max_stepback) { From f4ed57775668ce9cfde9184797e6732c675b6988 Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 28 Jun 2025 02:29:18 +0200 Subject: [PATCH 45/61] Add missing brace --- libr/core/cmd_anal.inc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 8edf5f81f5342..1337e27e400fe 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7288,6 +7288,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, r_reg_setv (core->esil.reg, "PC", op.addr + op.size); r_anal_op_fini (&op); continue; + } } if (until_expr || stepOver) { r_anal_op_fini (&op); From 09ed840685cdfdfdbd01bd9bfe0233d976b6fb85 Mon Sep 17 00:00:00 2001 From: condret Date: Sat, 28 Jun 2025 02:40:47 +0200 Subject: [PATCH 46/61] Add sanity check --- libr/esil/esil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 5ec2fbcaf249d..91f6dc4602f6b 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -558,6 +558,7 @@ R_API char *r_esil_pop(REsil *esil) { static int not_a_number(REsil *esil, const char *str) { #if USE_NEW_ESIL + R_RETURN_VAL_IF_FAIL (esil && str && esil->reg_if.is_reg, R_ESIL_PARM_INVALID); if (esil->reg_if.is_reg (esil->reg_if.reg, str)) { #else RRegItem *ri = r_reg_get (esil->anal->reg, str, -1); From dc1ffee6bac456de5810367f3af4bce426ba0f2d Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 11 Jul 2025 20:45:48 +0200 Subject: [PATCH 47/61] Fix warnings --- libr/core/anal_tp.c | 14 +++++++------- libr/core/cmd_anal.inc.c | 4 ++-- libr/core/cmd_search.inc.c | 2 +- libr/esil/esil_stats.c | 2 ++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index af3b53e5cca58..260f9a6065909 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -869,9 +869,9 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons int prev_idx, bool userfnc, ut64 caddr) { RAnal *anal = tps->core->anal; RCons *cons = tps->core->cons; - REsilTrace *et = tps->et; + TypeTrace *tt = &tps->tt; Sdb *TDB = anal->sdb_types; - const int idx = etrace_index (et) -1; + const int idx = etrace_index (tt) -1; const bool verbose = r_config_get_b (tps->core->config, "anal.types.verbose"); // XXX bool stack_rev = false, in_stack = false, format = false; R_LOG_DEBUG ("type_match %s %"PFMT64x" %"PFMT64x" %s %d", fcn_name, addr, baddr, cc, prev_idx); @@ -947,7 +947,7 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons for (j = idx; j >= prev_idx; j--) { // r_strf_var (k, 32, "%d.addr", j); // ut64 instr_addr = sdb_num_get (trace, k, 0); - ut64 instr_addr = etrace_addrof (et, j); + ut64 instr_addr = etrace_addrof (tt, j); R_LOG_DEBUG ("0x%08"PFMT64x" back traceing %d", instr_addr, j); if (instr_addr < baddr) { break; @@ -964,7 +964,7 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons break; } RAnalVar *var = r_anal_get_used_function_var (anal, op->addr); - if (op->type == R_ANAL_OP_TYPE_MOV && etrace_have_memread (et, j)) { + if (op->type == R_ANAL_OP_TYPE_MOV && etrace_have_memread (tt, j)) { memref = ! (!memref && var && (var->kind != R_ANAL_VAR_KIND_REG)); } // Match type from function param to instr @@ -1004,11 +1004,11 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons res = true; } else { get_src_regname (tps->core, instr_addr, regname, sizeof (regname)); - xaddr = get_addr (et, regname, j); + xaddr = get_addr (tt, regname, j); } } // Type propagate by following source reg - if (!res && *regname && etrace_regwrite_contains (et, j, regname)) { + if (!res && *regname && etrace_regwrite_contains (tt, j, regname)) { if (var) { if (!userfnc) { // not a userfunction, propagate the callee's arg types into our function's vars @@ -1035,7 +1035,7 @@ static void type_match(TPState *tps, char *fcn_name, ut64 addr, ut64 baddr, cons } else if (var && res && (xaddr && xaddr != UT64_MAX)) { // Type progation using value char tmp[REGNAME_SIZE] = {0}; get_src_regname (tps->core, instr_addr, tmp, sizeof (tmp)); - ut64 ptr = get_addr (et, tmp, j); + ut64 ptr = get_addr (tt, tmp, j); if (ptr == xaddr) { var_retype (anal, var, name, r_str_get_fail (type, "int"), memref, false); } diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 1337e27e400fe..1ba5b175ab4f8 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7234,7 +7234,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, startTime = r_time_now_mono (); } ut64 addr = r_reg_getv (core->esil.reg, "PC"); - r_cons_break_push (NULL, NULL); + r_cons_break_push (core->cons, NULL, NULL); while (addr != until_addr) { if (esiltimeout > 0) { ut64 elapsedTime = r_time_now_mono () - startTime; @@ -7300,7 +7300,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, addr = r_reg_getv (core->esil.reg, "PC"); } out: - r_cons_break_pop (); + r_cons_break_pop (core->cons); return ret; } diff --git a/libr/core/cmd_search.inc.c b/libr/core/cmd_search.inc.c index 533f54a1a4f7a..ee50fe1b04636 100644 --- a/libr/core/cmd_search.inc.c +++ b/libr/core/cmd_search.inc.c @@ -2350,7 +2350,7 @@ static void do_syscall_search(RCore *core, struct search_parameters *param) { pj_end (param->pj); } r_core_seek (core, oldoff, true); - r_esil_free (esil); + // r_esil_free (esil); r_cons_break_pop (core->cons); free (buf); free (esp32); diff --git a/libr/esil/esil_stats.c b/libr/esil/esil_stats.c index 4dc47472e8c2b..6d653f8b2dc63 100644 --- a/libr/esil/esil_stats.c +++ b/libr/esil/esil_stats.c @@ -104,6 +104,7 @@ R_API void r_esil_mem_ro(REsil *esil, bool mem_readonly) { } } +#if UNUSED static void esil_stats_old(REsil *esil, bool enable) { if (enable) { if (esil->stats) { @@ -124,3 +125,4 @@ static void esil_stats_old(REsil *esil, bool enable) { esil->stats = NULL; } } +#endif From e15b8c725c3255f335acdd00182e35d3d39831b4 Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 12 Jul 2025 19:21:20 +0200 Subject: [PATCH 48/61] i --- libr/esil/esil_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libr/esil/esil_stats.c b/libr/esil/esil_stats.c index 6d653f8b2dc63..9b30d02b8aa02 100644 --- a/libr/esil/esil_stats.c +++ b/libr/esil/esil_stats.c @@ -104,7 +104,7 @@ R_API void r_esil_mem_ro(REsil *esil, bool mem_readonly) { } } -#if UNUSED +#if MYUNUSED static void esil_stats_old(REsil *esil, bool enable) { if (enable) { if (esil->stats) { From 122eae9fb4afa42ca71be2553686284ff3f70de2 Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 12 Jul 2025 19:23:13 +0200 Subject: [PATCH 49/61] fw --- libr/esil/esil_stats.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libr/esil/esil_stats.c b/libr/esil/esil_stats.c index 9b30d02b8aa02..6d4e206fdf89c 100644 --- a/libr/esil/esil_stats.c +++ b/libr/esil/esil_stats.c @@ -1,9 +1,7 @@ -/* radare - LGPL - Copyright 2014-2024 - pancake, condret */ +/* radare - LGPL - Copyright 2014-2025 - pancake, condret */ #include -static void esil_stats_old(REsil *esil, bool enable); - #if USE_NEW_ESIL static void stats_voyeur_reg_read (void *user, const char *name, ut64 val) { const char *key = (*name>='0' && *name<='9')? "num.load": "reg.read"; @@ -25,6 +23,8 @@ static void stats_voyeur_mem_write (void *user, ut64 addr, const ut8 *old, const static void stats_voyeur_op (void *user, const char *op) { sdb_array_add ((Sdb *)user, "ops.list", op, 0); } +#else +static void esil_stats_old(REsil *esil, bool enable); #endif R_API void r_esil_stats(REsil *esil, REsilStats *stats, bool enable) { @@ -65,6 +65,9 @@ R_API void r_esil_stats(REsil *esil, REsilStats *stats, bool enable) { #endif } +#if USE_NEW_ESIL +// +#else static bool hook_command(REsil *esil, const char *op) { sdb_array_add (esil->stats, "ops.list", op, 0); return false; @@ -90,6 +93,7 @@ static bool hook_reg_write(REsil *esil, const char *name, ut64 *val) { sdb_array_add (esil->stats, "reg.write", name, 0); return false; } +#endif static bool hook_NOP_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { eprintf ("NOP WRITE AT 0x%08"PFMT64x"\n", addr); @@ -104,7 +108,8 @@ R_API void r_esil_mem_ro(REsil *esil, bool mem_readonly) { } } -#if MYUNUSED +#if USE_NEW_ESIL +#else static void esil_stats_old(REsil *esil, bool enable) { if (enable) { if (esil->stats) { From 8057a8044867b43d88c9ce7da9358e249b979f05 Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 12 Jul 2025 19:33:18 +0200 Subject: [PATCH 50/61] fw --- libr/core/anal_tp.c | 1 - libr/core/cmd_anal.inc.c | 4 ++-- libr/core/core_esil.c | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 260f9a6065909..9a5c388648c7f 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -320,7 +320,6 @@ static bool type_trace_op(TypeTrace *trace, REsil *esil, RAnalOp *op) { return false; } trace->cc = 0; - RRegItem *ri = r_reg_get (trace->reg, "PC", -1); if (ri) { const bool suc = r_esil_reg_write_silent (esil, ri->name, op->addr + op->size); diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 1ba5b175ab4f8..a25c5a3d9e235 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7224,8 +7224,8 @@ void cmd_anal_reg(RCore *core, const char *str) { #if USE_NEW_ESIL R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) { - const bool is_x86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86"); - const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid"); +// const bool is_x86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86"); +// const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid"); const int esiltimeout = r_config_get_i (core->config, "esil.timeout"); int ret = true; ut64 startTime = 0; diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 3fd17b1fa8ea8..d66ccacc5e0ba 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -85,7 +85,6 @@ static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) { if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } - if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { r_core_cmdf (c, "%s %"PFMT64d" 0", c->esil.cmd_mdev, c->esil.old_pc); return c->num->value; From c86e8032e3d867f7f20771f654a642c16c0addbf Mon Sep 17 00:00:00 2001 From: pancake Date: Mon, 14 Jul 2025 17:37:04 +0200 Subject: [PATCH 51/61] more fixes --- libr/esil/esil_ops.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/libr/esil/esil_ops.c b/libr/esil/esil_ops.c index 34e8fb74f27f3..70bb3f8296583 100644 --- a/libr/esil/esil_ops.c +++ b/libr/esil/esil_ops.c @@ -23,6 +23,14 @@ #define OT_FLAG R_ESIL_OP_TYPE_FLAG #define OT_TRAP R_ESIL_OP_TYPE_TRAP +static ut64 reg_getv(REsil *esil, const char* name) { + ut64 v = UT64_MAX; + if (r_esil_reg_read (esil, name, &v, NULL)) { + return v; + } + return UT64_MAX; +} + R_IPI bool alignCheck(REsil *esil, ut64 addr); /// XXX R2_600 - must be internal imho @@ -125,6 +133,7 @@ static bool popRN(REsil *esil, ut64 *n) { } static ut8 esil_internal_sizeof_reg(REsil *esil, const char *r) { +#if 0 R_RETURN_VAL_IF_FAIL (esil && esil->anal && esil->anal->reg && r, 0); RRegItem *ri = r_reg_get (esil->anal->reg, r, -1); if (ri) { @@ -132,6 +141,14 @@ static ut8 esil_internal_sizeof_reg(REsil *esil, const char *r) { r_unref (ri); return reg_size; } +#else + R_RETURN_VAL_IF_FAIL (esil && r, 0); + ut32 size = 0; + ut64 val = 0; // XXX esil_reg_read cant take val as null + if (r_esil_reg_read (esil, r, &val, &size)) { + return size; + } +#endif return 0; } @@ -334,7 +351,7 @@ static bool esil_js(REsil *esil) { } static bool esil_weak_eq(REsil *esil) { - R_RETURN_VAL_IF_FAIL (esil && esil->anal, false); + R_RETURN_VAL_IF_FAIL (esil, false); char *dst = r_esil_pop (esil); char *src = r_esil_pop (esil); @@ -371,6 +388,7 @@ static bool esil_eq(REsil *esil) { } bool is128reg = false; bool ispacked = false; +#if 0 RRegItem *ri = r_reg_get (esil->anal->reg, dst, -1); if (ri) { is128reg = ri->size == 128; @@ -379,6 +397,9 @@ static bool esil_eq(REsil *esil) { } else { R_LOG_DEBUG ("esil_eq: %s is not a register", dst); } +#else + // TODO: r_esil_reg can get regsize, but not the packed size +#endif if (is128reg && esil->stackptr > 0) { char *src2 = r_esil_pop (esil); // pop the higher 64bit value ut64 n0 = r_num_get (NULL, src); @@ -1543,6 +1564,8 @@ static bool esil_deceq(REsil *esil) { /* POKE */ static bool esil_poke_n(REsil *esil, int bits) { + R_RETURN_VAL_IF_FAIL (esil, false); + const bool be = (esil->anal)? R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config): false; ut64 bitmask = r_num_genmask (bits - 1); ut64 num, addr; ut8 b[8] = {0}; @@ -1566,9 +1589,9 @@ static bool esil_poke_n(REsil *esil, int bits) { size_t last = strlen (reg); reg[last + 1] = 0; reg[last] = 'l'; - ut64 loow = r_reg_getv (esil->anal->reg, reg); + ut64 loow = reg_getv (esil, reg); // r_reg_getv (esil->anal->reg, reg); reg[last] = 'h'; - ut64 high = r_reg_getv (esil->anal->reg, reg); + ut64 high = reg_getv (esil, reg); // r_reg_getv (esil->anal->reg, reg); ret = r_esil_mem_write (esil, addr, (const ut8*)&loow, 8); ret = r_esil_mem_write (esil, addr + 8, (const ut8*)&high, 8); #if 0 @@ -1592,12 +1615,12 @@ static bool esil_poke_n(REsil *esil, int bits) { esil->cb.hook_mem_read = NULL; r_esil_mem_read (esil, addr, b, bytes); esil->cb.hook_mem_read = oldhook; - n = r_read_ble64 (b, R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config)); + n = r_read_ble64 (b, be); esil->old = n; esil->cur = num; esil->lastsz = bits; num = num & bitmask; - r_write_ble (b, num, R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config), bits); + r_write_ble (b, num, be, bits); ret = r_esil_mem_write (esil, addr, b, bytes); } } @@ -1683,7 +1706,7 @@ static bool esil_peek_n(REsil *esil, int bits) { if (bits & 7) { return false; } - bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config); + bool be = (esil->anal)? R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config): false; // XXX esil cant determine endian without anal bool ret = false; char res[SDB_NUM_BUFSZ]; ut64 addr; From 80e9bff587018d0a5a2776cc79db90effb8e5ca3 Mon Sep 17 00:00:00 2001 From: pancake Date: Mon, 14 Jul 2025 19:11:45 +0200 Subject: [PATCH 52/61] wiring up more reg/memifs to esil --- libr/anal/anal.c | 5 ++- libr/core/cmd_anal.inc.c | 66 +++++++++++++++++++++++++++++++++++++--- libr/core/core_esil.c | 6 +++- libr/esil/esil.c | 13 +++++--- libr/esil/esil_ops.c | 26 ++++++++-------- libr/include/r_esil.h | 2 +- 6 files changed, 91 insertions(+), 27 deletions(-) diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 378d462ffd99a..50f6be4156f2f 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -117,7 +117,10 @@ static bool anal_esil_reg_read (void *user, const char *name, ut64 *val) { if (!ri) { return false; } - *val = r_reg_get_value (((RAnal *)user)->reg, ri); + ut64 v = r_reg_get_value (((RAnal *)user)->reg, ri); + if (val) { + *val = v; + } r_unref (ri); return true; } diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index a25c5a3d9e235..6b57988b5e31c 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2452,6 +2452,49 @@ static bool mw(int *ec, ut64 addr, const ut8 *old, const ut8 *buf, int len) { return true; } +static bool anal_rr(void *_reg, const char *name, ut64 *val) { + RReg *reg = _reg; + RRegItem *ri = r_reg_get (reg, name, -1); + if (ri) { +#if 0 + if (len) { + *len = ri->size; + } +#endif + if (val) { + *val = r_reg_get_value (reg, ri); + } + return true; + } + return false; +} + +static bool anal_rw(void *_reg, const char *name, ut64 val) { + RReg *reg = _reg; + return r_reg_setv (reg, name, val); +} + +static bool anal_mw(void *user, ut64 addr, const ut8 *buf, int len) { + RCore *core = user; + r_io_write_at (core->io, addr, buf, len); + return true; +} + +static bool anal_mr(void *user, ut64 addr, ut8 *buf, int len) { + RCore *core = user; + (void)r_io_read_at (core->io, addr, (ut8 *)buf, len); + return true; +} + +static bool anal_ir(void *_reg, const char *name) { + RReg *reg = _reg; + RRegItem *ri = r_reg_get (reg, name, -1); + if (ri) { + return true; + } + return false; +} + #if 0 static bool rw(void *null, const char *regname, ut64 old, ut64 num) { return true; @@ -2544,6 +2587,20 @@ static inline REsil *esil_new_setup(RCore *core) { const char *et = r_config_get (core->config, "cmd.esil.trap"); esil->cmd_trap = R_STR_ISNOTEMPTY (et)? strdup (et): NULL; } + esil->user = core; + // reg + esil->reg_if.reg = core->anal->reg; + esil->reg_if.reg_write = anal_rw; + esil->reg_if.reg_read = anal_rr; + esil->reg_if.is_reg = anal_ir; + // mem + esil->mem_if.user = core; + esil->mem_if.mem_read = anal_mr; + esil->mem_if.mem_write = anal_mw; +#if 0 + esil->cb.hook_mem_write = anal_mw; + esil->cb.hook_mem_read = anal_mr; +#endif // run the esilcb from arch if (core->anal->arch) { r_arch_esilcb (core->anal->arch, R_ARCH_ESIL_ACTION_INIT); @@ -8046,11 +8103,9 @@ static bool mymemread(REsil *esil, ut64 addr, ut8 *buf, int len) { return false; } n = R_NEW (AeaMemItem); - if (n) { - n->addr = addr; - n->size = len; - r_list_push (mymemxsr, n); - } + n->addr = addr; + n->size = len; + r_list_push (mymemxsr, n); return true; } @@ -8415,6 +8470,7 @@ static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) { break; default: r_reg_setv (core->anal->reg, "PC", aop.addr + aop.size); +eprintf ("%p\n", esil->cb.hook_reg_write); r_reg_setv (core->dbg->reg, "PC", aop.addr + aop.size); const char *e = R_STRBUF_SAFEGET (&aop.esil); if (R_STR_ISNOTEMPTY (e)) { diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index d66ccacc5e0ba..4be2a01deab91 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -434,7 +434,11 @@ R_API bool r_core_esil_single_step(RCore *core) { //this is like r_list_pop_head + r_list_push, //but without expensive calls to malloc and free RListIter *iter = core->esil.stepback.head; - iter->p->n = NULL; + if (iter->p) { + iter->p->n = NULL; + } else { + R_LOG_ERROR ("iter->p shouldnt be null"); + } core->esil.stepback.head = iter->p; iter->p = NULL; iter->n = core->esil.stepback.tail; diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 91f6dc4602f6b..cd9adde60f60b 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2014-2024 - pancake, condret */ +/* radare - LGPL - Copyright 2014-2025 - pancake, condret */ #define R_LOG_ORIGIN "esil" @@ -135,7 +135,10 @@ static bool default_reg_read(void *reg, const char *name, ut64 *val) { if (!ri) { return false; } - *val = r_reg_get_value ((RReg *)reg, ri); + ut64 v = r_reg_get_value ((RReg *)reg, ri); + if (val) { + *val = v; + } r_unref (ri); return true; } @@ -578,7 +581,7 @@ R_API int r_esil_get_parm_type(REsil *esil, const char *str) { if (r_str_startswith (str, "0x")) { return R_ESIL_PARM_NUM; } - if (!((isdigit(str[0])) || str[0] == '-')) { + if (!((isdigit (str[0])) || str[0] == '-')) { return not_a_number (esil, str); } size_t i; @@ -667,7 +670,7 @@ R_API bool r_esil_reg_read_nocallback(REsil *esil, const char *regname, ut64 *nu R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *size) { #if USE_NEW_ESIL - R_RETURN_VAL_IF_FAIL (esil && regname && val, false); + R_RETURN_VAL_IF_FAIL (esil && regname, false); if (R_UNLIKELY (!r_esil_reg_read_silent (esil, regname, val, size))) { return false; } @@ -702,7 +705,7 @@ R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *si } R_API bool r_esil_reg_read_silent(REsil *esil, const char *name, ut64 *val, ut32 *size) { - R_RETURN_VAL_IF_FAIL (esil && esil->reg_if.reg_read && name && val, false); + R_RETURN_VAL_IF_FAIL (esil && esil->reg_if.reg_read && name, false); if (!esil->reg_if.reg_read (esil->reg_if.reg, name, val)) { return false; } diff --git a/libr/esil/esil_ops.c b/libr/esil/esil_ops.c index 70bb3f8296583..7a38dcbab2d45 100644 --- a/libr/esil/esil_ops.c +++ b/libr/esil/esil_ops.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2024 - pancake, condret */ +/* radare - LGPL - Copyright 2024-2025 - pancake, condret */ #include #include @@ -23,6 +23,9 @@ #define OT_FLAG R_ESIL_OP_TYPE_FLAG #define OT_TRAP R_ESIL_OP_TYPE_TRAP +static bool isreg(REsil *esil, const char* name) { + return r_esil_reg_read (esil, name, NULL, NULL); +} static ut64 reg_getv(REsil *esil, const char* name) { ut64 v = UT64_MAX; if (r_esil_reg_read (esil, name, &v, NULL)) { @@ -616,8 +619,8 @@ static bool esil_bits(REsil *esil) { if (popRN (esil, &s)) { if (esil->anal && esil->anal->coreb.setArchBits) { esil->anal->coreb.setArchBits (esil->anal->coreb.core, NULL, s); + return true; } - return true; } R_LOG_DEBUG ("esil_bits: missing parameters in stack"); return false; @@ -642,9 +645,11 @@ static bool esil_syscall(REsil *esil) { static bool esil_cmd(REsil *esil) { char *str = r_esil_pop (esil); if (str) { - if (esil->anal && esil->anal->coreb.setArchBits) { + if (esil->anal && esil->anal->coreb.core) { esil->anal->coreb.cmd (esil->anal->coreb.core, str); + return true; } + R_LOG_WARN ("Cannot run RCoreBind.cmd"); } return false; } @@ -678,20 +683,13 @@ static void pushnums(REsil *esil, const char *src, ut64 num2, const char *dst, u R_RETURN_IF_FAIL (esil); esil->old = num; esil->cur = num - num2; - RReg *reg = esil->anal->reg; - RRegItem *ri = r_reg_get (reg, dst, -1); - if (ri) { + if (isreg (esil, dst)) { esil->lastsz = esil_internal_sizeof_reg (esil, dst); - r_unref (ri); - return; - } - if (ri = r_reg_get (reg, src, -1), ri) { + } else if (isreg (esil, src)) { esil->lastsz = esil_internal_sizeof_reg (esil, src); - r_unref (ri); - return; + } else { + esil->lastsz = 64; } - // default size is set to 64 as internally operands are ut64 - esil->lastsz = 64; } // This function also sets internal vars which is used in flag calculations. diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 81edeca80a47d..bf11932fab2b6 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -266,7 +266,7 @@ typedef struct r_esil_t { char *cmd_ioer; // r2 (external) command to run when esil fails to IO char *mdev_range; // string containing the r_str_range to match for read/write accesses bool (*cmd)(ESIL *esil, const char *name, ut64 a0, ut64 a1); - void *user; + void *user; // RCore * int stack_fd; // ahem, let's not do this bool in_cmd_step; #if 0 From 5057b3883231dad3bad63de70a32fe9d86269f61 Mon Sep 17 00:00:00 2001 From: pancake Date: Mon, 14 Jul 2025 19:20:17 +0200 Subject: [PATCH 53/61] more segflutes fixed --- libr/core/anal_tp.c | 4 +++- libr/core/cmd_anal.inc.c | 1 - libr/esil/esil.c | 16 +++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libr/core/anal_tp.c b/libr/core/anal_tp.c index 9a5c388648c7f..44fdaf4c37b96 100644 --- a/libr/core/anal_tp.c +++ b/libr/core/anal_tp.c @@ -1080,7 +1080,9 @@ static bool tt_reg_read(void *reg, const char *name, ut64 *val) { if (!ri) { return false; } - *val = r_reg_get_value ((RReg *)reg, ri); + if (val) { + *val = r_reg_get_value ((RReg *)reg, ri); + } r_unref (ri); return true; } diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 6b57988b5e31c..3ee4b181e6395 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -8470,7 +8470,6 @@ static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) { break; default: r_reg_setv (core->anal->reg, "PC", aop.addr + aop.size); -eprintf ("%p\n", esil->cb.hook_reg_write); r_reg_setv (core->dbg->reg, "PC", aop.addr + aop.size); const char *e = R_STRBUF_SAFEGET (&aop.esil); if (R_STR_ISNOTEMPTY (e)) { diff --git a/libr/esil/esil.c b/libr/esil/esil.c index cd9adde60f60b..dd56121c5d02e 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -680,7 +680,9 @@ R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *si } do { REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_REG_READ], i); - voy->reg_read (voy->user, regname, *val); + if (val) { + voy->reg_read (voy->user, regname, *val); + } } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_REG_READ], &i)); return true; #else @@ -691,7 +693,7 @@ R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *si val = &localnum; } *val = 0LL; - if (size) { + if (size && esil->anal && esil->anal->config) { *size = esil->anal->config->bits; } if (esil->cb.hook_reg_read) { @@ -706,12 +708,16 @@ R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *si R_API bool r_esil_reg_read_silent(REsil *esil, const char *name, ut64 *val, ut32 *size) { R_RETURN_VAL_IF_FAIL (esil && esil->reg_if.reg_read && name, false); - if (!esil->reg_if.reg_read (esil->reg_if.reg, name, val)) { - return false; - } if (esil->reg_if.reg_size && size) { *size = esil->reg_if.reg_size (esil->reg_if.reg, name); } + if (val) { + if (!esil->reg_if.reg_read (esil->reg_if.reg, name, val)) { + return false; + } + } else { + return esil->reg_if.is_reg (esil->reg_if.reg, name); + } return true; } From f70b4b0cd567d9769c47c78f1c52dd55549aeb72 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 00:37:44 +0200 Subject: [PATCH 54/61] meh --- libr/anal/anal.c | 2 +- libr/core/cmd_anal.inc.c | 8 ++++---- libr/core/core_esil.c | 39 ++++++++++++++++++++++----------------- libr/esil/esil.c | 22 +++++++++------------- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 50f6be4156f2f..f25269648148d 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -112,7 +112,7 @@ static bool anal_esil_is_reg (void *user, const char *name) { return true; } -static bool anal_esil_reg_read (void *user, const char *name, ut64 *val) { +static bool anal_esil_reg_read(void *user, const char *name, ut64 *val) { RRegItem *ri = r_reg_get (((RAnal *)user)->reg, name, -1); if (!ri) { return false; diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 3ee4b181e6395..e88d76d6aba32 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7470,12 +7470,12 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT); } #if 1 - if (core->dbg->anal->esil->trace) { + if (core->dbg->anal->esil->trace) { // ut64 pc = r_debug_reg_get (core->dbg, "PC"); // ut64 mask = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_VAL; // RAnalOp *op = r_core_anal_op (core, pc, mask); - r_esil_trace_op (core->dbg->anal->esil, &op); - } + r_esil_trace_op (core->dbg->anal->esil, &op); + } #endif // if type is JMP then we execute the next N instructions // update the esil pointer because RAnal.op() can change it @@ -8473,7 +8473,7 @@ static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) { r_reg_setv (core->dbg->reg, "PC", aop.addr + aop.size); const char *e = R_STRBUF_SAFEGET (&aop.esil); if (R_STR_ISNOTEMPTY (e)) { - // eprintf (" 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic); + // eprintf (" 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic); (void)r_esil_parse (esil, e); } break; diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 4be2a01deab91..1d270b808dbf7 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -29,8 +29,9 @@ static bool core_esil_op_interrupt(REsil *esil) { return r_esil_fire_interrupt (esil, (ut32)interrupt); } -static bool core_esil_is_reg (void *core, const char *name) { - RRegItem *ri = r_reg_get (((RCore *)core)->esil.reg, name, -1); +static bool core_esil_is_reg(void *_core, const char *name) { + RCore *core = _core; + RRegItem *ri = r_reg_get (core->anal->reg, name, -1); if (!ri) { return false; } @@ -38,28 +39,30 @@ static bool core_esil_is_reg (void *core, const char *name) { return true; } -static bool core_esil_reg_read (void *core, const char *name, ut64 *val) { - RRegItem *ri = r_reg_get (((RCore *)core)->esil.reg, name, -1); - if (!ri) { - return false; +static bool core_esil_reg_read(void *_core, const char *name, ut64 *val) { + RCore *core = _core; + RRegItem *ri = r_reg_get (core->anal->reg, name, -1); + if (R_LIKELY (ri)) { + *val = r_reg_get_value (core->anal->reg, ri); + r_unref (ri); + return true; } - *val = r_reg_get_value (((RCore *)core)->esil.reg, ri); - r_unref (ri); - return true; + return false; } static bool core_esil_reg_write (void *core, const char *name, ut64 val) { return r_reg_setv (((RCore *)core)->esil.reg, name, val); } -static ut32 core_esil_reg_size (void *core, const char *name) { - RRegItem *ri = r_reg_get (((RCore *)core)->esil.reg, name, -1); - if (!ri) { - return 0; - } - const ut32 size = ri->size; - r_unref (ri); - return size; +static ut32 core_esil_reg_size(void *_core, const char *name) { + RCore *core = _core; + RRegItem *ri = r_reg_get (core->anal->reg, name, -1); + if (R_LIKELY (ri)) { + const ut32 size = ri->size; + r_unref (ri); + return size; + } + return 0; } static REsilRegInterface core_esil_reg_if = { @@ -331,6 +334,7 @@ R_API bool r_core_esil_single_step(RCore *core) { ut32 trap_code = R_ANAL_TRAP_UNALIGNED; const int align = R_MAX (1, r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN)); if (pc % align) { + R_LOG_ERROR ("Unaligned execution at PC=0x%08"PFMT64x, pc); goto trap; } trap_code = R_ANAL_TRAP_READ_ERR; @@ -339,6 +343,7 @@ R_API bool r_core_esil_single_step(RCore *core) { //check if pc is within desc and desc is at least readable RIORegion region; if (!r_io_get_region_at (core->io, ®ion, pc)) { + R_LOG_ERROR ("pc not in region %s = 0x%"PFMT64x, pc_name, pc); goto trap; } if ((region.perm & (R_PERM_R | R_PERM_X)) != (R_PERM_R | R_PERM_X) || diff --git a/libr/esil/esil.c b/libr/esil/esil.c index dd56121c5d02e..55217a45f5815 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -145,11 +145,12 @@ static bool default_reg_read(void *reg, const char *name, ut64 *val) { static ut32 default_reg_size(void *reg, const char *name) { RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); - if (!ri) { - return 0; + if (R_LIKELY (ri)) { + ut32 size = ri->size; + r_unref (ri); + return size; } - r_unref (ri); - return ri->size; + return 0; } static REsilRegInterface simple_reg_if = { @@ -471,9 +472,7 @@ static bool internal_esil_reg_read(REsil *esil, const char *regname, ut64 *num, } if (num) { *num = r_reg_get_value (esil->anal->reg, ri); - if (esil->verbose) { - eprintf ("%s < %x\n", regname, (int)*num); - } + R_LOG_DEBUG ("%s < %x", regname, (int)*num); } r_unref (ri); return true; @@ -711,14 +710,11 @@ R_API bool r_esil_reg_read_silent(REsil *esil, const char *name, ut64 *val, ut32 if (esil->reg_if.reg_size && size) { *size = esil->reg_if.reg_size (esil->reg_if.reg, name); } - if (val) { - if (!esil->reg_if.reg_read (esil->reg_if.reg, name, val)) { - return false; - } - } else { + if (!val) { return esil->reg_if.is_reg (esil->reg_if.reg, name); } - return true; + *val = 0; + return esil->reg_if.reg_read (esil->reg_if.reg, name, val); } R_API const char *r_esil_trapstr(int type) { From 3d3ecd54962e03e334e918669da4d0ea521bfc3c Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 00:41:40 +0200 Subject: [PATCH 55/61] step ismpety --- libr/core/core_esil.c | 2 +- libr/include/r_esil.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 1d270b808dbf7..8a37ef7f01f79 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -409,7 +409,7 @@ R_API bool r_core_esil_single_step(RCore *core) { char *expr = r_strbuf_drain_nofree (&op.esil); r_esil_reg_write_silent (&core->esil.esil, pc_name, pc); r_anal_op_fini (&op); - if (core->esil.cmd_step) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_step)) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step, core->esil.old_pc); if (core->num->value) { free (expr); diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index bf11932fab2b6..cb7bb5f2d5a14 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -252,9 +252,9 @@ typedef struct r_esil_t { REsilRegInterface reg_if; REsilMemInterface mem_if; RIDStorage voyeur[R_ESIL_VOYEUR_LAST]; - REsilCallbacks cb; - REsilCallbacks ocb; - bool ocb_set; + REsilCallbacks cb; // DEPRECATED + REsilCallbacks ocb; // DEPRECATED + bool ocb_set; // DEPRECATED // this is so cursed, can we please remove external commands from esil internals. // Function pointers are fine, but not commands char *cmd_step; // r2 (external) command to run before a step is performed From 74a3570fd2558cd9a8cf1a2bda96f5f022b07b7c Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 01:02:46 +0200 Subject: [PATCH 56/61] fix step --- libr/core/cmd_anal.inc.c | 7 ++++++- libr/core/core_esil.c | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index e88d76d6aba32..5201d5d55714d 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7354,7 +7354,12 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ret = false; break; } - addr = r_reg_getv (core->esil.reg, "PC"); + // addr = r_reg_getv (core->esil.reg, "PC"); + addr = r_reg_getv (core->anal->reg, "PC"); + if (until_addr == UT64_MAX) { + eprintf ("next %llx\n", until_addr); + break; + } } out: r_cons_break_pop (core->cons); diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 8a37ef7f01f79..8571809803f92 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -135,8 +135,7 @@ 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) { +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_TRAP_REVERT)) { return; @@ -144,7 +143,7 @@ static void core_esil_voyeur_trap_revert_reg_write (void *user, const char *name r_strbuf_prependf (&cesil->trap_revert, "0x%"PFMT64x",%s,:=,", old, name); } -static void core_esil_voyeur_trap_revert_mem_write (void *user, ut64 addr, +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_TRAP_REVERT)) { @@ -161,7 +160,7 @@ static void core_esil_voyeur_trap_revert_mem_write (void *user, ut64 addr, } } -static void core_esil_stepback_free (void *data) { +static void core_esil_stepback_free(void *data) { if (data) { RCoreEsilStepBack *cesb = data; free (cesb->expr); @@ -408,6 +407,7 @@ R_API bool r_core_esil_single_step(RCore *core) { pc += op.size; char *expr = r_strbuf_drain_nofree (&op.esil); r_esil_reg_write_silent (&core->esil.esil, pc_name, pc); + r_reg_setv (core->anal->reg, pc_name, pc); // XXX r_anal_op_fini (&op); if (R_STR_ISNOTEMPTY (core->esil.cmd_step)) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step, core->esil.old_pc); @@ -458,7 +458,7 @@ R_API bool r_core_esil_single_step(RCore *core) { r_strbuf_fini (&core->esil.trap_revert); } } - if (core->esil.cmd_step_out) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_step_out)) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step_out, core->esil.old_pc); } return true; @@ -474,6 +474,7 @@ R_API bool r_core_esil_single_step(RCore *core) { goto trap; } //restore pc +// eprintf ("PC WRITE %llx\n", core->esil.old_pc); r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); goto trap; op_trap: From 931be620a76d2b64c0bbd9de17c6ef47283b6c9c Mon Sep 17 00:00:00 2001 From: condret Date: Tue, 15 Jul 2025 01:23:26 +0200 Subject: [PATCH 57/61] Add temporary hack to use anal->reg in core_esil --- libr/core/core_esil.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 8571809803f92..28aa9a645fcbb 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -171,10 +171,14 @@ static void core_esil_stepback_free(void *data) { R_API bool r_core_esil_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io, false); core->esil = (const RCoreEsil){0}; +#if 1 //hack + core->esil.reg = core->anal->reg +#else core->esil.reg = r_reg_new (); if (!core->esil.reg) { return false; } +#endif core_esil_reg_if.reg = core; core_esil_mem_if.mem = core; if (!r_esil_init (&core->esil.esil, 4096, false, 64, @@ -521,10 +525,12 @@ R_API void r_core_esil_fini(RCoreEsil *cesil) { r_esil_del_voyeur (&cesil->esil, cesil->tr_mem); r_esil_fini (&cesil->esil); r_strbuf_fini (&cesil->trap_revert); +#if 0 //hack if (cesil->reg) { r_reg_free (cesil->reg); cesil->reg = NULL; } +#endif R_FREE (cesil->cmd_step); R_FREE (cesil->cmd_step_out); R_FREE (cesil->cmd_intr); From 4499f4e8014426769cb6486f5aae9edfd62b6000 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 01:26:46 +0200 Subject: [PATCH 58/61] Remove esil.verbose and fix null derefs when esil->anal is nul --- libr/core/cconfig.c | 10 -------- libr/core/cmd_anal.inc.c | 4 +-- libr/core/cmd_search.inc.c | 1 - libr/core/core_esil.c | 4 +-- libr/esil/esil.c | 21 +++++++--------- libr/esil/esil_ops.c | 50 +++++++++++++------------------------- libr/esil/esil_toc.c | 3 +-- libr/esil/esil_trace.c | 3 --- libr/include/r_esil.h | 3 +-- 9 files changed, 31 insertions(+), 68 deletions(-) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 573c35574f942..184e3a47140d5 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -1916,15 +1916,6 @@ static bool cb_esilmaxbacksteps(void *user, void *data) { return true; } -static bool cb_esilverbose(void *user, void *data) { - RCore *core = user; - RConfigNode *node = data; - if (core->anal->esil) { - core->anal->esil->verbose = node->i_value; - } - return true; -} - static bool cb_esilstackdepth(void *user, void *data) { RConfigNode *node = data; if (node->i_value < 3) { @@ -3818,7 +3809,6 @@ R_API int r_core_config_init(RCore *core) { SETI ("esil.maxsteps", 0, "If !=0 defines the maximum amount of steps to perform on aesu/aec/.."); SETICB ("esil.maxbacksteps", 256, &cb_esilmaxbacksteps, "esil back step capacity"); SETS ("esil.fillstack", "", "initialize ESIL stack with (random, debruijn, sequence, zeros, ...)"); - SETICB ("esil.verbose", 0, &cb_esilverbose, "show ESIL verbose level (0, 1, 2)"); SETICB ("esil.gotolimit", core->anal->esil_goto_limit, &cb_gotolimit, "maximum number of gotos per ESIL expression"); SETICB ("esil.stack.depth", 256, &cb_esilstackdepth, "number of elements that can be pushed on the esilstack"); SETI ("esil.stack.size", 0xf0000, "set stack size in ESIL VM"); diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 5201d5d55714d..6b75195bd9846 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2582,7 +2582,6 @@ static inline REsil *esil_new_setup(RCore *core) { bool stats = r_config_get_b (core->config, "esil.stats"); bool nonull = r_config_get_b (core->config, "esil.nonull"); r_esil_setup (esil, core->anal, romem, stats, nonull); - esil->verbose = r_config_get_i (core->config, "esil.verbose"); esil->cmd = r_core_esil_cmd; const char *et = r_config_get (core->config, "cmd.esil.trap"); esil->cmd_trap = R_STR_ISNOTEMPTY (et)? strdup (et): NULL; @@ -7356,8 +7355,8 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, } // addr = r_reg_getv (core->esil.reg, "PC"); addr = r_reg_getv (core->anal->reg, "PC"); + // ESIL TODO: use StepOptions with .amount if (until_addr == UT64_MAX) { - eprintf ("next %llx\n", until_addr); break; } } @@ -7617,7 +7616,6 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, } tail_return_value = 1; } - // esil->verbose ? // eprintf ("REPE 0x%"PFMT64x" %s => 0x%"PFMT64x"\n", addr, R_STRBUF_SAFEGET (&op.esil), r_reg_getv (core->anal->reg, "PC")); ut64 pc = r_reg_getv (core->anal->reg, "PC"); if (pc == UT64_MAX || pc == UT32_MAX) { diff --git a/libr/core/cmd_search.inc.c b/libr/core/cmd_search.inc.c index ee50fe1b04636..c683b99eba047 100644 --- a/libr/core/cmd_search.inc.c +++ b/libr/core/cmd_search.inc.c @@ -1982,7 +1982,6 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c ut64 to = r_io_map_end (map); //r_esil_setup (esil, core->anal, 1, 0, nonull); r_esil_stack_free (esil); - esil->verbose = 0; r_cons_break_push (core->cons, NULL, NULL); for (addr = from; addr < to; addr++) { diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 28aa9a645fcbb..4814bb35247bc 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2024 - 2025 - condret */ +/* radare - LGPL - Copyright 2024-2025 - condret */ #define R_LOG_ORIGIN "core.esil" #include @@ -478,7 +478,7 @@ R_API bool r_core_esil_single_step(RCore *core) { goto trap; } //restore pc -// eprintf ("PC WRITE %llx\n", core->esil.old_pc); + // eprintf ("PC WRITE %llx\n", core->esil.old_pc); r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); goto trap; op_trap: diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 55217a45f5815..a56d54f99372a 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -35,7 +35,6 @@ R_API REsil *r_esil_new(int stacksize, int iotrap, unsigned int addrsize) { free (esil); return NULL; } - esil->verbose = false; esil->stacksize = stacksize; esil->parse_goto_count = R_ESIL_GOTO_LIMIT; esil->ops = ht_pp_new (NULL, esil_ops_free, NULL); @@ -132,15 +131,15 @@ static bool default_reg_alias(void *reg, int kind, const char *name) { static bool default_reg_read(void *reg, const char *name, ut64 *val) { RRegItem *ri = r_reg_get ((RReg *)reg, name, -1); - if (!ri) { - return false; - } - ut64 v = r_reg_get_value ((RReg *)reg, ri); - if (val) { - *val = v; + if (R_LIKELY (ri)) { + ut64 v = r_reg_get_value ((RReg *)reg, ri); + if (val) { + *val = v; + } + r_unref (ri); + return true; } - r_unref (ri); - return true; + return false; } static ut32 default_reg_size(void *reg, const char *name) { @@ -869,9 +868,7 @@ static int eval_word(REsil *esil, const char *ostr, const char **str) { esil->parse_goto = -1; return 2; } - if (esil->verbose) { - R_LOG_ERROR ("Cannot find word %d", esil->parse_goto); - } + R_LOG_DEBUG ("Cannot find word %d", esil->parse_goto); return 1; } if (esil->parse_stop) { diff --git a/libr/esil/esil_ops.c b/libr/esil/esil_ops.c index 7a38dcbab2d45..a992e0ca404c6 100644 --- a/libr/esil/esil_ops.c +++ b/libr/esil/esil_ops.c @@ -11,7 +11,6 @@ #include #include -#define IFDBG if (esil->verbose > 1) #define OP(v, w, x, y, z) r_esil_set_op (esil, v, w, x, y, z, NULL) #define OP2(v, w, x, y, z, i) r_esil_set_op (esil, v, w, x, y, z, i) #define OT_UNK R_ESIL_OP_TYPE_UNKNOWN @@ -74,14 +73,6 @@ R_API bool r_esil_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) { esil->trap_code = addr; } } - IFDBG { - size_t i; - eprintf ("0x%08" PFMT64x " R> ", addr); - for (i = 0; i < len; i++) { - eprintf ("%02x", buf[i]); - } - eprintf ("\n"); - } return ret; #endif } @@ -722,7 +713,11 @@ static bool esil_regalias(REsil *esil) { ret = true; int kind = r_reg_alias_fromstring (dst); if (kind != -1) { - r_reg_alias_setname (esil->anal->reg, kind, src); + if (esil->anal) { + r_reg_alias_setname (esil->anal->reg, kind, src); + } else { + R_LOG_ERROR ("ESIL_ANAL_REQUIRED"); + } } } free (dst); @@ -898,9 +893,7 @@ static bool esil_lsreq(REsil *esil) { if (dst && r_esil_reg_read (esil, dst, &num, NULL)) { if (src && r_esil_get_parm (esil, src, &num2)) { if (num2 > 63) { - if (esil->verbose) { - R_LOG_WARN ("Invalid shift at 0x%08"PFMT64x, esil->addr); - } + R_LOG_DEBUG ("Invalid shift at 0x%08"PFMT64x, esil->addr); num2 = 63; } esil->old = num; @@ -951,23 +944,17 @@ static bool esil_asreq(REsil *esil) { ut64 left_bits = 0; int shift = regsize - 1; if (shift < 0 || shift > regsize - 1) { - if (esil->verbose) { - R_LOG_WARN ("Invalid asreq shift of %d at 0x%"PFMT64x, shift, esil->addr); - } + R_LOG_DEBUG ("Invalid asreq shift of %d at 0x%"PFMT64x, shift, esil->addr); shift = 0; } if (param_num > regsize - 1) { // capstone bug? - if (esil->verbose) { - R_LOG_WARN ("Invalid asreq shift of %"PFMT64d" at 0x%"PFMT64x, param_num, esil->addr); - } + R_LOG_DEBUG ("Invalid asreq shift of %"PFMT64d" at 0x%"PFMT64x, param_num, esil->addr); param_num = 30; } if (shift >= 63) { // LL can't handle LShift of 63 or more - if (esil->verbose) { - R_LOG_WARN ("Invalid asreq shift of %d at 0x%08"PFMT64x, shift, esil->addr); - } + R_LOG_DEBUG ("Invalid asreq shift of %d at 0x%08"PFMT64x, shift, esil->addr); } else if (op_num & (1LL << shift)) { left_bits = (1 << param_num) - 1; left_bits <<= regsize - param_num; @@ -984,9 +971,7 @@ static bool esil_asreq(REsil *esil) { // r_esil_pushnum (esil, res); ret = true; } else { - if (esil->verbose) { - R_LOG_WARN ("esil_asr: empty stack"); - } + R_LOG_DEBUG ("esil_asr: empty stack"); } } free (param); @@ -1004,9 +989,7 @@ static bool esil_asr(REsil *esil) { if (param && r_esil_get_parm (esil, param, ¶m_num)) { if (param_num > regsize - 1) { // capstone bug? - if (esil->verbose) { - R_LOG_WARN ("Invalid asr shift of %"PFMT64d" at 0x%"PFMT64x, param_num, esil->addr); - } + R_LOG_DEBUG ("Invalid asr shift of %"PFMT64d" at 0x%"PFMT64x, param_num, esil->addr); param_num = 30; } bool isNegative; @@ -1660,6 +1643,8 @@ static bool esil_poke_some(REsil *esil) { char *count, *dst = r_esil_pop (esil); if (dst && r_esil_get_parm_size (esil, dst, &tmp, ®size)) { + // ESIL TODO - do not depend on esil->anal + const bool be = esil->anal? R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config): false; // reg isregornum (esil, dst, &ptr); count = r_esil_pop (esil); @@ -1678,7 +1663,7 @@ static bool esil_poke_some(REsil *esil) { } r_esil_get_parm_size (esil, foo, &tmp, ®size); isregornum (esil, foo, &num64); - r_write_ble (b, num64, R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config), regsize); + r_write_ble (b, num64, be, regsize); const int size_bytes = regsize / 8; const ut32 written = r_esil_mem_write (esil, ptr, b, size_bytes); if (written != size_bytes) { @@ -1782,6 +1767,7 @@ static bool esil_peek_some(REsil *esil) { isregornum (esil, dst, &ptr); count = r_esil_pop (esil); if (count) { + const bool be = esil->anal? R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config): false; isregornum (esil, count, ®s); if (regs > 0) { ut8 a[4]; @@ -1795,14 +1781,12 @@ static bool esil_peek_some(REsil *esil) { } bool oks = r_esil_mem_read (esil, ptr, a, 4); if (!oks) { - if (esil->verbose) { - R_LOG_ERROR ("Cannot peek from 0x%08" PFMT64x, ptr); - } + R_LOG_DEBUG ("Cannot peek from 0x%08" PFMT64x, ptr); free (dst); free (count); return false; } - ut32 num32 = r_read_ble32 (a, R_ARCH_CONFIG_IS_BIG_ENDIAN (esil->anal->config)); + ut32 num32 = r_read_ble32 (a, be); r_esil_reg_write (esil, foo, num32); ptr += 4; free (foo); diff --git a/libr/esil/esil_toc.c b/libr/esil/esil_toc.c index 4a80e5433be25..49a05ca0810e7 100644 --- a/libr/esil/esil_toc.c +++ b/libr/esil/esil_toc.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2021-2024 - pancake */ +/* radare - LGPL - Copyright 2021-2025 - pancake */ #include #include @@ -203,7 +203,6 @@ static void esil2c_setup(REsil *esil) { R_RETURN_IF_FAIL (esil); REsilC *user = R_NEW (REsilC); esil->user = user; - esil->verbose = true; // r_config_get_b (core->config, "esil.verbose"); #if USE_NEW_ESIL r_esil_add_voyeur (esil, NULL, esil2c_mw, R_ESIL_VOYEUR_MEM_WRITE); r_esil_add_voyeur (esil, NULL, esil2c_mr, R_ESIL_VOYEUR_MEM_READ); diff --git a/libr/esil/esil_trace.c b/libr/esil/esil_trace.c index 48aa6b64b1e67..f23de7873051f 100644 --- a/libr/esil/esil_trace.c +++ b/libr/esil/esil_trace.c @@ -339,11 +339,8 @@ R_API void r_esil_trace_op(REsil *esil, struct r_anal_op_t *op) { esil->cb.hook_mem_read = trace_hook_mem_read; esil->cb.hook_mem_write = trace_hook_mem_write; /* evaluate esil expression */ - const int esil_verbose = esil->verbose; - esil->verbose = 0; // disable verbose logs when tracing r_esil_parse (esil, expr); r_esil_stack_free (esil); - esil->verbose = esil_verbose; /* restore hooks */ esil->cb = esil->ocb; esil->ocb_set = false; diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index cb7bb5f2d5a14..23b29ef6b555d 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -1,4 +1,4 @@ -/* radare2 - LGPL - Copyright 2022-2024 - pancake */ +/* radare2 - LGPL - Copyright 2022-2025 - pancake */ #ifndef R_ESIL_H #define R_ESIL_H @@ -220,7 +220,6 @@ typedef struct r_esil_t { int parse_stop; int parse_goto; int parse_goto_count; - int verbose; ut64 flags; ut64 addr; ut64 stack_addr; From 43b9654a509db5e36338429be382f192fc48ad70 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 01:46:11 +0200 Subject: [PATCH 59/61] bring back --- libr/core/core.c | 1 + libr/core/core_esil.c | 35 +++++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/libr/core/core.c b/libr/core/core.c index 7a1153e3390ed..64a1ad3776917 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2742,6 +2742,7 @@ R_API bool r_core_init(RCore *core) { core->dbg->ev = core->ev; #if USE_NEW_ESIL r_core_esil_init (core); + // core->esil.reg = core->anal->reg; #endif r_core_config_init (core); r_core_loadlibs_init (core); diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 4814bb35247bc..3f2f710f68ac6 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -8,7 +8,7 @@ static bool core_esil_op_todo(REsil *esil) { RCore *core = esil->user; - if (core->esil.cmd_todo) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_todo)) { r_core_cmd0 (core, core->esil.cmd_todo); } return true; @@ -23,7 +23,7 @@ static bool core_esil_op_interrupt(REsil *esil) { } free (str); RCore *core = esil->user; - if (core->esil.cmd_intr) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_intr)) { r_core_cmd0 (core, core->esil.cmd_intr); } return r_esil_fire_interrupt (esil, (ut32)interrupt); @@ -88,7 +88,7 @@ static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) { if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } - if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { + if (R_STR_ISNOTEMPTY (c->esil.cmd_mdev) && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { r_core_cmdf (c, "%s %"PFMT64d" 0", c->esil.cmd_mdev, c->esil.old_pc); return c->num->value; } @@ -107,7 +107,7 @@ static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { return false; } - if (c->esil.cmd_mdev && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { + if (R_STR_ISNOTEMPTY (c->esil.cmd_mdev) && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { r_core_cmdf (c, "%s %"PFMT64d" 1", c->esil.cmd_mdev, c->esil.old_pc); return c->num->value; } @@ -171,8 +171,8 @@ static void core_esil_stepback_free(void *data) { R_API bool r_core_esil_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io, false); core->esil = (const RCoreEsil){0}; -#if 1 //hack - core->esil.reg = core->anal->reg +#if 0 // hack + core->esil.reg = core->anal->reg; #else core->esil.reg = r_reg_new (); if (!core->esil.reg) { @@ -307,13 +307,13 @@ R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr) { } else { r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); } - if (core->esil.cmd_trap) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_trap)) { r_core_cmd0 (core, core->esil.cmd_trap); } switch (core->esil.esil.trap_code) { case R_ANAL_TRAP_WRITE_ERR: case R_ANAL_TRAP_READ_ERR: - if (core->esil.cmd_ioer) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_ioer)) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, core->esil.old_pc); } @@ -324,7 +324,8 @@ R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr) { R_API bool r_core_esil_single_step(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->esil.reg, false); - const char *pc_name = r_reg_alias_getname (core->esil.reg, R_REG_ALIAS_PC); + RReg *reg = core->anal->reg; // core->esil.reg NO + const char *pc_name = r_reg_alias_getname (reg, R_REG_ALIAS_PC); if (!pc_name) { R_LOG_ERROR ("CoreEsil reg profile has no pc register"); return false; @@ -420,7 +421,12 @@ R_API bool r_core_esil_single_step(RCore *core) { goto skip; } } - const bool suc = r_esil_parse (&core->esil.esil, expr); + if (R_STR_ISEMPTY (expr)) { + // nops, endbrp ,.. + goto skip; + } + const bool suc = r_esil_parse (core->anal->esil, expr); + //const bool suc = r_esil_parse (&core->esil.esil, expr); free (expr); if (suc) { skip: @@ -473,7 +479,8 @@ R_API bool r_core_esil_single_step(RCore *core) { core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; char *expr = r_strbuf_drain_nofree (&core->esil.trap_revert); //revert all changes - r_esil_parse (&core->esil.esil, expr); + // r_esil_parse (&core->esil.esil, expr); + r_esil_parse (core->anal->esil, expr); free (expr); goto trap; } @@ -484,13 +491,13 @@ R_API bool r_core_esil_single_step(RCore *core) { op_trap: r_anal_op_fini (&op); trap: - if (core->esil.cmd_trap) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_trap)) { r_core_cmd0 (core, core->esil.cmd_trap); } switch (trap_code) { case R_ANAL_TRAP_WRITE_ERR: case R_ANAL_TRAP_READ_ERR: - if (core->esil.cmd_ioer) { + if (R_STR_ISNOTEMPTY (core->esil.cmd_ioer)) { r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, core->esil.old_pc); } @@ -525,7 +532,7 @@ R_API void r_core_esil_fini(RCoreEsil *cesil) { r_esil_del_voyeur (&cesil->esil, cesil->tr_mem); r_esil_fini (&cesil->esil); r_strbuf_fini (&cesil->trap_revert); -#if 0 //hack +#if 1 if (cesil->reg) { r_reg_free (cesil->reg); cesil->reg = NULL; From 8de3f5a1d768ab54ad1cdf460e80969c2fdd2ee0 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 02:00:37 +0200 Subject: [PATCH 60/61] coreesil is cesil --- libr/core/cconfig.c | 34 +++--- libr/core/cmd_anal.inc.c | 14 +-- libr/core/core.c | 2 +- libr/core/core_esil.c | 257 ++++++++++++++++++++------------------- libr/include/r_core.h | 2 +- libr/include/r_esil.h | 2 + 6 files changed, 157 insertions(+), 154 deletions(-) diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 184e3a47140d5..b51c975e79f43 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -1910,7 +1910,7 @@ static bool cb_gotolimit(void *user, void *data) { static bool cb_esilmaxbacksteps(void *user, void *data) { RCore *core = user; RConfigNode *node = data; - if (core->esil.reg) { //hack + if (core->cesil.reg) { //hack r_core_esil_set_max_stepback (core, node->i_value); } return true; @@ -1929,9 +1929,9 @@ static bool cb_esiltraprevert(void *user, void *data) { RCore *core = user; RConfigNode *node = data; if (node->i_value) { - core->esil.cfg |= R_CORE_ESIL_TRAP_REVERT_CONFIG; + core->cesil.cfg |= R_CORE_ESIL_TRAP_REVERT_CONFIG; } else { - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT_CONFIG; + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT_CONFIG; } return true; } @@ -2165,8 +2165,8 @@ static bool cb_cmd_esil_ioer(void *user, void *data) { RConfigNode *node = data; #if USE_NEW_ESIL if (core) { - free (core->esil.cmd_ioer); - core->esil.cmd_ioer = strdup (node->value); + free (core->cesil.cmd_ioer); + core->cesil.cmd_ioer = strdup (node->value); #else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; @@ -2204,8 +2204,8 @@ static bool cb_mdevrange(void *user, void *data) { RConfigNode *node = data; #if USE_NEW_ESIL if (core) { - free (core->esil.mdev_range); - core->esil.mdev_range = strdup (node->value); + free (core->cesil.mdev_range); + core->cesil.mdev_range = strdup (node->value); #else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; @@ -2231,8 +2231,8 @@ static bool cb_cmd_esil_step(void *user, void *data) { RConfigNode *node = data; #if USE_NEW_ESIL if (core) { - free (core->esil.cmd_step); - core->esil.cmd_step = strdup (node->value); + free (core->cesil.cmd_step); + core->cesil.cmd_step = strdup (node->value); #else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; @@ -2248,8 +2248,8 @@ static bool cb_cmd_esil_step_out(void *user, void *data) { RConfigNode *node = data; #if USE_NEW_ESIL if (core) { - free (core->esil.cmd_step_out); - core->esil.cmd_step_out = strdup (node->value); + free (core->cesil.cmd_step_out); + core->cesil.cmd_step_out = strdup (node->value); #else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; @@ -2265,8 +2265,8 @@ static bool cb_cmd_esil_mdev(void *user, void *data) { RConfigNode *node = data; #if USE_NEW_ESIL if (core) { - free (core->esil.cmd_mdev); - core->esil.cmd_mdev = strdup (node->value); + free (core->cesil.cmd_mdev); + core->cesil.cmd_mdev = strdup (node->value); #else if (core && core->anal && core->anal->esil) { core->anal->esil->cmd = r_core_esil_cmd; @@ -2714,9 +2714,9 @@ static bool cb_romem(void *user, void *data) { RConfigNode *node = (RConfigNode *)data; RCore *core = (RCore*)user; if (node->i_value) { - core->esil.cfg |= R_CORE_ESIL_RO; + core->cesil.cfg |= R_CORE_ESIL_RO; } else { - core->esil.cfg &= ~R_CORE_ESIL_RO; + core->cesil.cfg &= ~R_CORE_ESIL_RO; } return true; } @@ -2725,9 +2725,9 @@ static bool cb_esilnonull(void *user, void *data) { RConfigNode *node = (RConfigNode *)data; RCore *core = (RCore*)user; if (node->i_value) { - core->esil.cfg |= R_CORE_ESIL_NONULL; + core->cesil.cfg |= R_CORE_ESIL_NONULL; } else { - core->esil.cfg &= ~R_CORE_ESIL_NONULL; + core->cesil.cfg &= ~R_CORE_ESIL_NONULL; } return true; } diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 6b75195bd9846..8e1cd314ff26c 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -7289,7 +7289,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, if (esiltimeout > 0) { startTime = r_time_now_mono (); } - ut64 addr = r_reg_getv (core->esil.reg, "PC"); + ut64 addr = r_reg_getv (core->cesil.reg, "PC"); r_cons_break_push (core->cons, NULL, NULL); while (addr != until_addr) { if (esiltimeout > 0) { @@ -7335,13 +7335,13 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, case R_ANAL_OP_TYPE_CRET: case R_ANAL_OP_TYPE_UJMP: if (addr % R_MAX (r_arch_info (core->anal->arch, R_ARCH_INFO_CODE_ALIGN), 1)) { - if (core->esil.cmd_trap) { - r_core_cmd0 (core, core->esil.cmd_trap); + if (core->cesil.cmd_trap) { + r_core_cmd0 (core, core->cesil.cmd_trap); } r_anal_op_fini (&op); goto out; } - r_reg_setv (core->esil.reg, "PC", op.addr + op.size); + r_reg_setv (core->cesil.reg, "PC", op.addr + op.size); r_anal_op_fini (&op); continue; } @@ -7353,7 +7353,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ret = false; break; } - // addr = r_reg_getv (core->esil.reg, "PC"); + // addr = r_reg_getv (core->cesil.reg, "PC"); addr = r_reg_getv (core->anal->reg, "PC"); // ESIL TODO: use StepOptions with .amount if (until_addr == UT64_MAX) { @@ -7671,8 +7671,8 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, #if USE_NEW_ESIL R_API bool r_core_esil_step_back(RCore *core) { - R_RETURN_VAL_IF_FAIL (core && core->io && core->esil.reg && - r_list_length (&core->esil.stepback), false); + R_RETURN_VAL_IF_FAIL (core && core->io && core->cesil.reg && + r_list_length (&core->cesil.stepback), false); r_core_esil_stepback (core); return true; } diff --git a/libr/core/core.c b/libr/core/core.c index 64a1ad3776917..c6a3f96d8a677 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2850,7 +2850,7 @@ R_API void r_core_fini(RCore *c) { r_unref (c->anal->config); */ #if USE_NEW_ESIL - r_core_esil_fini (&c->esil); + r_core_esil_fini (&c->cesil); #endif if (c->anal->esil) { c->anal->esil->anal = NULL; diff --git a/libr/core/core_esil.c b/libr/core/core_esil.c index 3f2f710f68ac6..5afe1f51ba6dd 100644 --- a/libr/core/core_esil.c +++ b/libr/core/core_esil.c @@ -8,8 +8,8 @@ static bool core_esil_op_todo(REsil *esil) { RCore *core = esil->user; - if (R_STR_ISNOTEMPTY (core->esil.cmd_todo)) { - r_core_cmd0 (core, core->esil.cmd_todo); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_todo)) { + r_core_cmd0 (core, core->cesil.cmd_todo); } return true; } @@ -23,8 +23,8 @@ static bool core_esil_op_interrupt(REsil *esil) { } free (str); RCore *core = esil->user; - if (R_STR_ISNOTEMPTY (core->esil.cmd_intr)) { - r_core_cmd0 (core, core->esil.cmd_intr); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_intr)) { + r_core_cmd0 (core, core->cesil.cmd_intr); } return r_esil_fire_interrupt (esil, (ut32)interrupt); } @@ -50,8 +50,9 @@ static bool core_esil_reg_read(void *_core, const char *name, ut64 *val) { return false; } -static bool core_esil_reg_write (void *core, const char *name, ut64 val) { - return r_reg_setv (((RCore *)core)->esil.reg, name, val); +static bool core_esil_reg_write (void *_core, const char *name, ut64 val) { + RCore *core = _core; + return r_reg_setv (core->cesil.reg, name, val); } static ut32 core_esil_reg_size(void *_core, const char *name) { @@ -76,26 +77,27 @@ static bool core_esil_mem_switch (void *core, ut32 idx) { return r_io_bank_use (((RCore *)core)->io, idx); } -static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) { +static bool core_esil_mem_read (void *_core, ut64 addr, ut8 *buf, int len) { if ((UT64_MAX - len + 1) < addr) { - if (!core_esil_mem_read (core, 0ULL, buf + (UT64_MAX - addr + 1), + if (!core_esil_mem_read (_core, 0ULL, buf + (UT64_MAX - addr + 1), len - (UT64_MAX - addr + 1))) { return false; } len = UT64_MAX - addr + 1; } - RCore *c = core; - if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { + RCore *core = _core; + if (!addr && core->cesil.cfg & R_CORE_ESIL_NONULL) { return false; } - if (R_STR_ISNOTEMPTY (c->esil.cmd_mdev) && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { - r_core_cmdf (c, "%s %"PFMT64d" 0", c->esil.cmd_mdev, c->esil.old_pc); - return c->num->value; + if (R_STR_ISNOTEMPTY (core->cesil.cmd_mdev) && core->cesil.mdev_range && r_str_range_in (core->cesil.mdev_range, addr)) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->cesil.cmd_mdev, core->cesil.old_pc); + return core->num->value; } - return r_io_read_at (c->io, addr, buf, len); + return r_io_read_at (core->io, addr, buf, len); } -static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) { +static bool core_esil_mem_write (void *_core, ut64 addr, const ut8 *buf, int len) { + RCore *core = _core; if ((UT64_MAX - len + 1) < addr) { if (!core_esil_mem_write (core, 0ULL, buf + (UT64_MAX - addr + 1), len - (UT64_MAX - addr + 1))) { @@ -103,17 +105,16 @@ static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) } len = UT64_MAX - addr + 1; } - RCore *c = core; - if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) { + if (!addr && core->cesil.cfg & R_CORE_ESIL_NONULL) { return false; } - if (R_STR_ISNOTEMPTY (c->esil.cmd_mdev) && c->esil.mdev_range && r_str_range_in (c->esil.mdev_range, addr)) { - r_core_cmdf (c, "%s %"PFMT64d" 1", c->esil.cmd_mdev, c->esil.old_pc); - return c->num->value; + if (R_STR_ISNOTEMPTY (core->cesil.cmd_mdev) && core->cesil.mdev_range && r_str_range_in (core->cesil.mdev_range, addr)) { + r_core_cmdf (core, "%s %"PFMT64d" 1", core->cesil.cmd_mdev, core->cesil.old_pc); + return core->num->value; } - if (c->esil.cfg & R_CORE_ESIL_RO) { + if (core->cesil.cfg & R_CORE_ESIL_RO) { RIORegion region; - if (!r_io_get_region_at (c->io, ®ion, addr)) { + if (!r_io_get_region_at (core->io, ®ion, addr)) { //maybe check voidwrites config here return true; } @@ -126,7 +127,7 @@ static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) return core_esil_mem_write (core, r_itv_end (region.itv), NULL, addr + len - r_itv_end (region.itv)); //no need to pass buf, because this is RO mode } - return r_io_write_at (c->io, addr, buf, len); + return r_io_write_at (core->io, addr, buf, len); } static REsilMemInterface core_esil_mem_if = { @@ -170,38 +171,38 @@ static void core_esil_stepback_free(void *data) { R_API bool r_core_esil_init(RCore *core) { R_RETURN_VAL_IF_FAIL (core && core->io, false); - core->esil = (const RCoreEsil){0}; + core->cesil = (const RCoreEsil){0}; #if 0 // hack - core->esil.reg = core->anal->reg; + core->cesil.reg = core->anal->reg; #else - core->esil.reg = r_reg_new (); - if (!core->esil.reg) { + core->cesil.reg = r_reg_new (); + if (!core->cesil.reg) { return false; } #endif core_esil_reg_if.reg = core; core_esil_mem_if.mem = core; - if (!r_esil_init (&core->esil.esil, 4096, false, 64, + if (!r_esil_init (&core->cesil.esil, 4096, false, 64, &core_esil_reg_if, &core_esil_mem_if)) { goto init_fail; } - if (!r_esil_set_op (&core->esil.esil, "TODO", core_esil_op_todo, 0, 0, - R_ESIL_OP_TYPE_UNKNOWN, NULL) || !r_esil_set_op (&core->esil.esil, + if (!r_esil_set_op (&core->cesil.esil, "TODO", core_esil_op_todo, 0, 0, + R_ESIL_OP_TYPE_UNKNOWN, NULL) || !r_esil_set_op (&core->cesil.esil, "$", core_esil_op_interrupt, 0, 1, R_ESIL_OP_TYPE_UNKNOWN, NULL)) { 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, + r_strbuf_init (&core->cesil.trap_revert); + core->cesil.esil.user = core; + core->cesil.tr_reg = r_esil_add_voyeur (&core->cesil.esil, &core->cesil, 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->cesil.tr_mem = r_esil_add_voyeur (&core->cesil.esil, &core->cesil, core_esil_voyeur_trap_revert_mem_write, R_ESIL_VOYEUR_MEM_WRITE); - core->esil.stepback.free = core_esil_stepback_free; + core->cesil.stepback.free = core_esil_stepback_free; return true; op_fail: - r_esil_fini (&core->esil.esil); + r_esil_fini (&core->cesil.esil); init_fail: - r_reg_free (core->esil.reg); + r_reg_free (core->cesil.reg); return false; } @@ -215,7 +216,7 @@ R_API void r_core_esil_load_arch(RCore *core) { } //This is awful. TODO: massage r_arch api REsil *arch_esil = core->anal->arch->esil; - core->anal->arch->esil = &core->esil.esil; + core->anal->arch->esil = &core->cesil.esil; r_arch_esilcb (core->anal->arch, R_ARCH_ESIL_ACTION_INIT); core->anal->arch->esil = arch_esil; char *rp = core->anal->arch->session->plugin->regs (core->anal->arch->session); @@ -223,7 +224,7 @@ R_API void r_core_esil_load_arch(RCore *core) { R_LOG_WARN ("Couldn't set reg profile"); return; } - r_reg_set_profile_string (core->esil.reg, rp); + r_reg_set_profile_string (core->cesil.reg, rp); free (rp); } @@ -234,88 +235,88 @@ R_API void r_core_esil_unload_arch(RCore *core) { return; } REsil *arch_esil = core->anal->arch->esil; - core->anal->arch->esil = &core->esil.esil; + core->anal->arch->esil = &core->cesil.esil; r_arch_esilcb (core->anal->arch, R_ARCH_ESIL_ACTION_FINI); core->anal->arch->esil = arch_esil; } R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr) { - R_RETURN_VAL_IF_FAIL (expr && core && core->anal && core->anal->arch && core->io && core->esil.reg, false); - const char *pc_name = r_reg_alias_getname (core->esil.reg, R_REG_ALIAS_PC); + R_RETURN_VAL_IF_FAIL (expr && core && core->anal && core->anal->arch && core->io && core->cesil.reg, false); + const char *pc_name = r_reg_alias_getname (core->cesil.reg, R_REG_ALIAS_PC); if (!pc_name) { R_LOG_ERROR ("CoreEsil reg profile has no pc register"); return false; } ut64 pc; - if (!r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL)) { + if (!r_esil_reg_read_silent (&core->cesil.esil, pc_name, &pc, NULL)) { R_LOG_ERROR ("Couldn't read from PC register"); return false; } - if ((core->esil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->esil.max_stepback) { - core->esil.cfg |= R_CORE_ESIL_TRAP_REVERT; - r_strbuf_initf (&core->esil.trap_revert, + if ((core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->cesil.max_stepback) { + core->cesil.cfg |= R_CORE_ESIL_TRAP_REVERT; + r_strbuf_initf (&core->cesil.trap_revert, "0x%"PFMT64x",%s,:=", pc, pc_name); } else { - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; - } - core->esil.old_pc = pc; - r_esil_reg_write_silent (&core->esil.esil, pc_name, addr); - if (r_esil_parse (&core->esil.esil, expr)) { - if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { - if (core->esil.max_stepback) { - if (core->esil.max_stepback > r_list_length (&core->esil.stepback)) { + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + } + core->cesil.old_pc = pc; + r_esil_reg_write_silent (&core->cesil.esil, pc_name, addr); + if (r_esil_parse (&core->cesil.esil, expr)) { + if (core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT) { + if (core->cesil.max_stepback) { + if (core->cesil.max_stepback > r_list_length (&core->cesil.stepback)) { RCoreEsilStepBack *cesb = R_NEW (RCoreEsilStepBack); if (!cesb) { R_LOG_WARN ("RCoreEsilStepBack allocation failed"); - r_strbuf_fini (&core->esil.trap_revert); + r_strbuf_fini (&core->cesil.trap_revert); } else { - if (!r_list_push (&core->esil.stepback, cesb)) { + if (!r_list_push (&core->cesil.stepback, cesb)) { R_LOG_WARN ("Pushing RCoreEsilStepBack failed"); } else { - cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); - cesb->addr = core->esil.old_pc; + cesb->expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); + cesb->addr = core->cesil.old_pc; } } } else { //this is like r_list_pop_head + r_list_push, //but without expensive calls to malloc and free - RListIter *iter = core->esil.stepback.head; + RListIter *iter = core->cesil.stepback.head; iter->p->n = NULL; - core->esil.stepback.head = iter->p; + core->cesil.stepback.head = iter->p; iter->p = NULL; - iter->n = core->esil.stepback.tail; - core->esil.stepback.tail->p = iter; - core->esil.stepback.tail = iter; + iter->n = core->cesil.stepback.tail; + core->cesil.stepback.tail->p = iter; + core->cesil.stepback.tail = iter; RCoreEsilStepBack *cesb = iter->data; free (cesb->expr); - cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); - cesb->addr = core->esil.old_pc; + cesb->expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); + cesb->addr = core->cesil.old_pc; } } else { - r_strbuf_fini (&core->esil.trap_revert); + r_strbuf_fini (&core->cesil.trap_revert); } } return true; } - if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { + if (core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT) { //disable trap_revert voyeurs - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; - char *expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + char *expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); //revert all changes - r_esil_parse (&core->esil.esil, expr); + r_esil_parse (&core->cesil.esil, expr); free (expr); } else { - r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); + r_esil_reg_write_silent (&core->cesil.esil, pc_name, core->cesil.old_pc); } - if (R_STR_ISNOTEMPTY (core->esil.cmd_trap)) { - r_core_cmd0 (core, core->esil.cmd_trap); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_trap)) { + r_core_cmd0 (core, core->cesil.cmd_trap); } - switch (core->esil.esil.trap_code) { + switch (core->cesil.esil.trap_code) { case R_ANAL_TRAP_WRITE_ERR: case R_ANAL_TRAP_READ_ERR: - if (R_STR_ISNOTEMPTY (core->esil.cmd_ioer)) { - r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, - core->esil.old_pc); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_ioer)) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->cesil.cmd_ioer, + core->cesil.old_pc); } break; } @@ -323,15 +324,15 @@ R_API bool r_core_esil_run_expr_at(RCore *core, const char *expr, ut64 addr) { } R_API bool r_core_esil_single_step(RCore *core) { - R_RETURN_VAL_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->esil.reg, false); - RReg *reg = core->anal->reg; // core->esil.reg NO + R_RETURN_VAL_IF_FAIL (core && core->anal && core->anal->arch && core->io && core->cesil.reg, false); + RReg *reg = core->anal->reg; // core->cesil.reg NO const char *pc_name = r_reg_alias_getname (reg, R_REG_ALIAS_PC); if (!pc_name) { R_LOG_ERROR ("CoreEsil reg profile has no pc register"); return false; } ut64 pc; - if (!r_esil_reg_read_silent (&core->esil.esil, pc_name, &pc, NULL)) { + if (!r_esil_reg_read_silent (&core->cesil.esil, pc_name, &pc, NULL)) { R_LOG_ERROR ("Couldn't read from PC register"); return false; } @@ -401,21 +402,21 @@ R_API bool r_core_esil_single_step(RCore *core) { if (!r_itv_contain (region.itv, pc + op.size)) { goto op_trap; } - if ((core->esil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->esil.max_stepback) { - core->esil.cfg |= R_CORE_ESIL_TRAP_REVERT; - r_strbuf_initf (&core->esil.trap_revert, + if ((core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT_CONFIG) || core->cesil.max_stepback) { + core->cesil.cfg |= R_CORE_ESIL_TRAP_REVERT; + r_strbuf_initf (&core->cesil.trap_revert, "0x%"PFMT64x",%s,:=", pc, pc_name); } else { - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; } - core->esil.old_pc = pc; + core->cesil.old_pc = pc; pc += op.size; char *expr = r_strbuf_drain_nofree (&op.esil); - r_esil_reg_write_silent (&core->esil.esil, pc_name, pc); + r_esil_reg_write_silent (&core->cesil.esil, pc_name, pc); r_reg_setv (core->anal->reg, pc_name, pc); // XXX r_anal_op_fini (&op); - if (R_STR_ISNOTEMPTY (core->esil.cmd_step)) { - r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step, core->esil.old_pc); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_step)) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->cesil.cmd_step, core->cesil.old_pc); if (core->num->value) { free (expr); goto skip; @@ -426,80 +427,80 @@ R_API bool r_core_esil_single_step(RCore *core) { goto skip; } const bool suc = r_esil_parse (core->anal->esil, expr); - //const bool suc = r_esil_parse (&core->esil.esil, expr); + //const bool suc = r_esil_parse (&core->cesil.esil, expr); free (expr); if (suc) { skip: - if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { - if (core->esil.max_stepback) { - if (core->esil.max_stepback > r_list_length (&core->esil.stepback)) { - RCoreEsilStepBack *cesb = R_NEW (RCoreEsilStepBack); + if (core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT) { + if (core->cesil.max_stepback) { + if (core->cesil.max_stepback > r_list_length (&core->cesil.stepback)) { + RCoreEsilStepBack *cesb = R_NEW0 (RCoreEsilStepBack); if (!cesb) { R_LOG_WARN ("RCoreEsilStepBack allocation failed"); - r_strbuf_fini (&core->esil.trap_revert); + r_strbuf_fini (&core->cesil.trap_revert); } else { - if (!r_list_push (&core->esil.stepback, cesb)) { + if (!r_list_push (&core->cesil.stepback, cesb)) { R_LOG_WARN ("Pushing RCoreEsilStepBack failed"); } else { - cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); - cesb->addr = core->esil.old_pc; + cesb->expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); + cesb->addr = core->cesil.old_pc; } } } else { //this is like r_list_pop_head + r_list_push, //but without expensive calls to malloc and free - RListIter *iter = core->esil.stepback.head; + RListIter *iter = core->cesil.stepback.head; if (iter->p) { iter->p->n = NULL; } else { R_LOG_ERROR ("iter->p shouldnt be null"); } - core->esil.stepback.head = iter->p; + core->cesil.stepback.head = iter->p; iter->p = NULL; - iter->n = core->esil.stepback.tail; - core->esil.stepback.tail->p = iter; - core->esil.stepback.tail = iter; + iter->n = core->cesil.stepback.tail; + core->cesil.stepback.tail->p = iter; + core->cesil.stepback.tail = iter; RCoreEsilStepBack *cesb = iter->data; free (cesb->expr); - cesb->expr = r_strbuf_drain_nofree (&core->esil.trap_revert); - cesb->addr = core->esil.old_pc; + cesb->expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); + cesb->addr = core->cesil.old_pc; } } else { - r_strbuf_fini (&core->esil.trap_revert); + r_strbuf_fini (&core->cesil.trap_revert); } } - if (R_STR_ISNOTEMPTY (core->esil.cmd_step_out)) { - r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_step_out, core->esil.old_pc); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_step_out)) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->cesil.cmd_step_out, core->cesil.old_pc); } return true; } - trap_code = core->esil.esil.trap_code; - if (core->esil.cfg & R_CORE_ESIL_TRAP_REVERT) { + trap_code = core->cesil.esil.trap_code; + if (core->cesil.cfg & R_CORE_ESIL_TRAP_REVERT) { //disable trap_revert voyeurs - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; - char *expr = r_strbuf_drain_nofree (&core->esil.trap_revert); + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + char *expr = r_strbuf_drain_nofree (&core->cesil.trap_revert); //revert all changes - // r_esil_parse (&core->esil.esil, expr); + // r_esil_parse (&core->cesil.esil, expr); r_esil_parse (core->anal->esil, expr); free (expr); goto trap; } //restore pc - // eprintf ("PC WRITE %llx\n", core->esil.old_pc); - r_esil_reg_write_silent (&core->esil.esil, pc_name, core->esil.old_pc); + // eprintf ("PC WRITE %llx\n", core->cesil.old_pc); + r_esil_reg_write_silent (&core->cesil.esil, pc_name, core->cesil.old_pc); goto trap; op_trap: r_anal_op_fini (&op); trap: - if (R_STR_ISNOTEMPTY (core->esil.cmd_trap)) { - r_core_cmd0 (core, core->esil.cmd_trap); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_trap)) { + r_core_cmd0 (core, core->cesil.cmd_trap); } switch (trap_code) { case R_ANAL_TRAP_WRITE_ERR: case R_ANAL_TRAP_READ_ERR: - if (R_STR_ISNOTEMPTY (core->esil.cmd_ioer)) { - r_core_cmdf (core, "%s %"PFMT64d" 0", core->esil.cmd_ioer, - core->esil.old_pc); + if (R_STR_ISNOTEMPTY (core->cesil.cmd_ioer)) { + r_core_cmdf (core, "%s %"PFMT64d" 0", core->cesil.cmd_ioer, + core->cesil.old_pc); } break; } @@ -507,22 +508,22 @@ R_API bool r_core_esil_single_step(RCore *core) { } R_API void r_core_esil_stepback(RCore *core) { - R_RETURN_IF_FAIL (core && core->io && core->esil.reg); - if (!r_list_length (&core->esil.stepback)) { + R_RETURN_IF_FAIL (core && core->io && core->cesil.reg); + if (!r_list_length (&core->cesil.stepback)) { //not an error return; } - RCoreEsilStepBack *cesb = r_list_pop (&core->esil.stepback); - core->esil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; - r_esil_parse (&core->esil.esil, cesb->expr); + RCoreEsilStepBack *cesb = r_list_pop (&core->cesil.stepback); + core->cesil.cfg &= ~R_CORE_ESIL_TRAP_REVERT; + r_esil_parse (&core->cesil.esil, cesb->expr); core_esil_stepback_free (cesb); } R_API void r_core_esil_set_max_stepback(RCore *core, ut32 max_stepback) { - R_RETURN_IF_FAIL (core && core->esil.stepback.free); - core->esil.max_stepback = max_stepback; - while (r_list_length (&core->esil.stepback) > max_stepback) { - core_esil_stepback_free (r_list_pop_head (&core->esil.stepback)); + R_RETURN_IF_FAIL (core && core->cesil.stepback.free); + core->cesil.max_stepback = max_stepback; + while (r_list_length (&core->cesil.stepback) > max_stepback) { + core_esil_stepback_free (r_list_pop_head (&core->cesil.stepback)); } } diff --git a/libr/include/r_core.h b/libr/include/r_core.h index b308abf23302e..d2b3f73e4f50c 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -364,7 +364,7 @@ struct r_core_t { RList/**/ *cmd_descriptors; RAnal *anal; RAsm *rasm; - RCoreEsil esil; + RCoreEsil cesil; /* ^^ */ RCoreTimes *times; // RParse *parser; diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 23b29ef6b555d..13f950a26bdf7 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -256,7 +256,9 @@ typedef struct r_esil_t { bool ocb_set; // DEPRECATED // this is so cursed, can we please remove external commands from esil internals. // Function pointers are fine, but not commands +#if 0 char *cmd_step; // r2 (external) command to run before a step is performed +#endif char *cmd_step_out; // r2 (external) command to run after a step is performed char *cmd_intr; // r2 (external) command to run when an interrupt occurs char *cmd_trap; // r2 (external) command to run when a trap occurs From e9b8649897e7af58758e2a64e169c7a4d1fdf037 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 15 Jul 2025 02:02:18 +0200 Subject: [PATCH 61/61] fb --- libr/include/r_esil.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 13f950a26bdf7..23b29ef6b555d 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -256,9 +256,7 @@ typedef struct r_esil_t { bool ocb_set; // DEPRECATED // this is so cursed, can we please remove external commands from esil internals. // Function pointers are fine, but not commands -#if 0 char *cmd_step; // r2 (external) command to run before a step is performed -#endif char *cmd_step_out; // r2 (external) command to run after a step is performed char *cmd_intr; // r2 (external) command to run when an interrupt occurs char *cmd_trap; // r2 (external) command to run when a trap occurs