mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-03 02:41:08 +00:00
Add new command 'aesb' step back for ESIL (#8052)
* Add new command aets * Add new command aesb, step back for ESIL * Add session key
This commit is contained in:
parent
e7a2f2cc8c
commit
0e4aa83d16
@ -32,7 +32,7 @@ OBJLIBS+=cond.o value.o cc.o diff.o types.o fcnstore.o
|
||||
OBJLIBS+=hint.o anal.o data.o xrefs.o esil.o sign.o
|
||||
OBJLIBS+=anal_ex.o switch.o state.o cycles.o
|
||||
OBJLIBS+=esil_stats.o esil_trace.o flirt.o labels.o
|
||||
OBJLIBS+=esil2reil.o pin.o
|
||||
OBJLIBS+=esil2reil.o pin.o session.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-modules.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-isa.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/elf32-xtensa.o
|
||||
|
@ -89,6 +89,7 @@ R_API RAnalEsil *r_anal_esil_new(int stacksize, int iotrap) {
|
||||
esil->ops = sdb_new0 ();
|
||||
esil->iotrap = iotrap;
|
||||
esil->interrupts = sdb_new0 ();
|
||||
esil->sessions = r_list_newf (r_anal_esil_session_free);
|
||||
return esil;
|
||||
}
|
||||
|
||||
@ -204,6 +205,7 @@ R_API void r_anal_esil_free(RAnalEsil *esil) {
|
||||
if (esil->anal && esil->anal->cur && esil->anal->cur->esil_fini) {
|
||||
esil->anal->cur->esil_fini (esil);
|
||||
}
|
||||
r_list_free (esil->sessions);
|
||||
free (esil->cmd_intr);
|
||||
free (esil->cmd_trap);
|
||||
free (esil->cmd_mdev);
|
||||
|
@ -70,6 +70,7 @@ files=[
|
||||
'pin.c',
|
||||
'ref.c',
|
||||
'reflines.c',
|
||||
'session.c',
|
||||
'sign.c',
|
||||
'state.c',
|
||||
'switch.c',
|
||||
|
79
libr/anal/session.c
Normal file
79
libr/anal/session.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* radare - LGPL - Copyright 2017 - rkx1209 */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_bind.h>
|
||||
|
||||
R_API void r_anal_esil_session_free(RAnalEsilSession *session) {
|
||||
free (session->data);
|
||||
free (session);
|
||||
}
|
||||
|
||||
R_API void r_anal_esil_session_list(RAnalEsil *esil) {
|
||||
if (!esil || !esil->sessions) {
|
||||
return;
|
||||
}
|
||||
RListIter *iter;
|
||||
RAnalEsilSession *session;
|
||||
ut64 idx = 0;
|
||||
r_list_foreach (esil->sessions, iter, session) {
|
||||
esil->anal->cb_printf ("[%d] 0x%08"PFMT64x "\n", idx++, session->key);
|
||||
}
|
||||
}
|
||||
|
||||
R_API RAnalEsilSession *r_anal_esil_session_add(RAnalEsil *esil) {
|
||||
if (!esil) {
|
||||
return NULL;
|
||||
}
|
||||
RAnalEsilSession *session = R_NEW0 (RAnalEsilSession);
|
||||
const char *name = r_reg_get_name (esil->anal->reg, R_REG_NAME_PC);
|
||||
ut32 i;
|
||||
if (!session) {
|
||||
return NULL;
|
||||
}
|
||||
if (!esil->stack_addr || !esil->stack_size) {
|
||||
R_FREE (session);
|
||||
return NULL;
|
||||
}
|
||||
session->key = r_reg_getv (esil->anal->reg, name);
|
||||
session->addr = esil->stack_addr;
|
||||
session->size = esil->stack_size;
|
||||
session->data = (ut8 *) R_NEWS0 (ut8 *, session->size);
|
||||
if (!session->data) {
|
||||
R_FREE (session);
|
||||
return NULL;
|
||||
}
|
||||
/* Save current register */
|
||||
for (i = 0; i < R_REG_TYPE_LAST; i++) {
|
||||
session->reg[i] = r_list_tail (esil->anal->reg->regset[i].pool);
|
||||
}
|
||||
r_reg_arena_push (esil->anal->reg);
|
||||
|
||||
/* Save current memory dump */
|
||||
esil->anal->iob.read_at (esil->anal->iob.io, session->addr, session->data, session->size);
|
||||
|
||||
r_list_append (esil->sessions, session);
|
||||
return session;
|
||||
}
|
||||
|
||||
R_API void r_anal_esil_session_set(RAnalEsil *esil, RAnalEsilSession *session) {
|
||||
if (!esil || !session) {
|
||||
return;
|
||||
}
|
||||
ut32 i;
|
||||
RListIter *iter;
|
||||
/* Restore registers */
|
||||
for (i = 0; i < R_REG_TYPE_LAST; i++) {
|
||||
iter = session->reg[i];
|
||||
RRegArena *arena = iter->data;
|
||||
if (esil->anal->reg->regset[i].arena->bytes) {
|
||||
if (esil->anal->reg->regset[i].arena->size >= arena->size) {
|
||||
memcpy (esil->anal->reg->regset[i].arena->bytes, arena->bytes, arena->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore memory dump */
|
||||
esil->anal->iob.write_at (esil->anal->iob.io, session->addr, session->data, session->size);
|
||||
}
|
@ -212,7 +212,7 @@ static int stack_clean (RCore *core, ut64 addr, RAnalFunction *fcn) {
|
||||
const char *esil = sdb_fmt (-1, "%d,%s,-=", offset, sp);
|
||||
r_anal_esil_parse (core->anal->esil, esil);
|
||||
r_anal_esil_stack_free (core->anal->esil);
|
||||
r_core_esil_step (core, UT64_MAX, NULL);
|
||||
r_core_esil_step (core, UT64_MAX, NULL, NULL);
|
||||
ret = op->size;
|
||||
}
|
||||
r_anal_op_free (op);
|
||||
@ -265,7 +265,7 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) {
|
||||
r_debug_reg_sync (core->dbg, R_REG_TYPE_ALL, true);
|
||||
r_anal_esil_set_pc (core->anal->esil, addr);
|
||||
} else {
|
||||
r_core_esil_step (core, UT64_MAX, NULL);
|
||||
r_core_esil_step (core, UT64_MAX, NULL, NULL);
|
||||
r_anal_op_free (op);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
addr = r_reg_getv (core->anal->reg, pc);
|
||||
|
@ -6,8 +6,6 @@
|
||||
/* hacky inclusion */
|
||||
#include "anal_vt.c"
|
||||
|
||||
#define ESIL_STACK_NAME "esil.ram"
|
||||
|
||||
static const char *help_msg_a[] = {
|
||||
"Usage:", "a", "[abdefFghoprxstc] [...]",
|
||||
"aa", "[?]", "analyze all (fcns + bbs) (aa0 to avoid sub renaming)",
|
||||
@ -92,7 +90,9 @@ static const char *help_msg_ae[] = {
|
||||
"aep", "[?] [addr]", "manage esil pin hooks",
|
||||
"aepc", " [addr]", "change esil PC to this address",
|
||||
"aer", " [..]", "handle ESIL registers like 'ar' or 'dr' does",
|
||||
"aets", "[?]", "ESIL Trace session",
|
||||
"aes", "", "perform emulated debugger step",
|
||||
"aesb", "", "step back",
|
||||
"aeso", " ", "step over",
|
||||
"aesu", " [addr]", "step until given address",
|
||||
"aesue", " [esil]", "step until esil expression match",
|
||||
@ -181,6 +181,13 @@ static const char *help_msg_aep[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_aets[] = {
|
||||
"Usage:", "aets ", " [...]",
|
||||
"aets", "", "List all ESIL trace sessions",
|
||||
"aets+", "", "Add ESIL trace session",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_af[] = {
|
||||
"Usage:", "af", "",
|
||||
"af", " ([name]) ([addr])", "analyze functions (start at addr or $$)",
|
||||
@ -2662,7 +2669,7 @@ void cmd_anal_reg(RCore *core, const char *str) {
|
||||
|
||||
R_API bool r_core_esil_cmd(RAnalEsil *esil, const char *cmd, ut64 a1, ut64 a2);
|
||||
|
||||
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
|
||||
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr) {
|
||||
// Stepping
|
||||
int ret;
|
||||
ut8 code[256];
|
||||
@ -2714,6 +2721,9 @@ repeat:
|
||||
addr = r_reg_getv (core->anal->reg, name);
|
||||
//eprintf ("PC=0x%"PFMT64x"\n", (ut64)addr);
|
||||
}
|
||||
if (prev_addr) {
|
||||
*prev_addr = addr;
|
||||
}
|
||||
if (esil->exectrap) {
|
||||
if (!(r_io_section_get_rwx (core->io, addr) & R_IO_EXEC)) {
|
||||
esil->trap = R_ANAL_TRAP_EXEC_ERR;
|
||||
@ -2853,6 +2863,30 @@ out_return_zero:
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_core_esil_step_back(RCore *core) {
|
||||
RAnalEsil *esil = core->anal->esil;
|
||||
RListIter *tail;
|
||||
const char *name = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
||||
ut64 prev = 0;
|
||||
ut64 end = r_reg_getv (core->anal->reg, name);
|
||||
|
||||
if (!esil || !(tail = r_list_tail (esil->sessions))) {
|
||||
return 0;
|
||||
}
|
||||
RAnalEsilSession *before = (RAnalEsilSession *) tail->data;
|
||||
|
||||
//eprintf ("Execute until 0x%08"PFMT64x"\n", end);
|
||||
|
||||
r_anal_esil_session_set (esil, before);
|
||||
|
||||
r_core_esil_step (core, end, NULL, &prev);
|
||||
//eprintf ("Before 0x%08"PFMT64x"\n", prev);
|
||||
|
||||
r_anal_esil_session_set (esil, before);
|
||||
r_core_esil_step (core, prev, NULL, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_address_info(RCore *core, const char *addrstr, int fmt) {
|
||||
ut64 addr, type;
|
||||
if (!addrstr || !*addrstr) {
|
||||
@ -2967,6 +3001,7 @@ static void initialize_stack (RCore *core, ut64 addr, ut64 size) {
|
||||
}
|
||||
|
||||
static void cmd_esil_mem(RCore *core, const char *input) {
|
||||
RAnalEsil *esil = core->anal->esil;
|
||||
ut64 curoff = core->offset;
|
||||
const char *patt = "";
|
||||
ut64 addr = 0x100000;
|
||||
@ -2993,6 +3028,10 @@ static void cmd_esil_mem(RCore *core, const char *input) {
|
||||
} else {
|
||||
cmd_esil_mem (core, "");
|
||||
}
|
||||
if (esil) {
|
||||
esil->stack_addr = addr;
|
||||
esil->stack_size = size;
|
||||
}
|
||||
initialize_stack (core, addr, size);
|
||||
return;
|
||||
}
|
||||
@ -3089,6 +3128,10 @@ static void cmd_esil_mem(RCore *core, const char *input) {
|
||||
r_core_cmdf (core, "S 0x%"PFMT64x" 0x%"PFMT64x" %d %d "
|
||||
ESIL_STACK_NAME, addr, addr, size, size);
|
||||
}
|
||||
if (esil) {
|
||||
esil->stack_addr = addr;
|
||||
esil->stack_size = size;
|
||||
}
|
||||
initialize_stack (core, addr, size);
|
||||
// r_core_cmdf (core, "wopD 0x%"PFMT64x" @ 0x%"PFMT64x, size, addr);
|
||||
r_core_seek (core, curoff, 0);
|
||||
@ -3465,6 +3508,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
case 's': // "aes"
|
||||
// "aes" "aeso" "aesu" "aesue"
|
||||
// aes -> single step
|
||||
// aesb -> single step back
|
||||
// aeso -> single step over
|
||||
// aesu -> until address
|
||||
// aesue -> until esil expression
|
||||
@ -3480,18 +3524,24 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
if (!op) {
|
||||
break;
|
||||
}
|
||||
r_core_esil_step (core, UT64_MAX, NULL);
|
||||
r_core_esil_step (core, UT64_MAX, NULL, NULL);
|
||||
r_debug_reg_set (core->dbg, "PC", pc + op->size);
|
||||
r_anal_esil_set_pc (esil, pc + op->size);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
} break;
|
||||
case 'b': // "aesb"
|
||||
if (!r_core_esil_step_back (core)) {
|
||||
eprintf ("cannnot step back\n");
|
||||
}
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
break;
|
||||
case 'u': // "aesu"
|
||||
if (input[2] == 'e') {
|
||||
until_expr = input + 3;
|
||||
} else {
|
||||
until_addr = r_num_math (core->num, input + 2);
|
||||
}
|
||||
r_core_esil_step (core, until_addr, until_expr);
|
||||
r_core_esil_step (core, until_addr, until_expr, NULL);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
break;
|
||||
case 'o': // "aeso"
|
||||
@ -3501,12 +3551,12 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
if (op && op->type == R_ANAL_OP_TYPE_CALL) {
|
||||
until_addr = op->addr + op->size;
|
||||
}
|
||||
r_core_esil_step (core, until_addr, until_expr);
|
||||
r_core_esil_step (core, until_addr, until_expr, NULL);
|
||||
r_anal_op_free (op);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
break;
|
||||
default:
|
||||
r_core_esil_step (core, until_addr, until_expr);
|
||||
r_core_esil_step (core, until_addr, until_expr, NULL);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
break;
|
||||
}
|
||||
@ -3531,7 +3581,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
eprintf ("trap at 0x%08" PFMT64x "\n", addr);
|
||||
break;
|
||||
}
|
||||
ret = r_core_esil_step (core, UT64_MAX, NULL);
|
||||
ret = r_core_esil_step (core, UT64_MAX, NULL, NULL);
|
||||
r_anal_op_free (op);
|
||||
if (core->anal->esil->trap || core->anal->esil->trap_code) {
|
||||
break;
|
||||
@ -3556,7 +3606,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
else if (input[1] == 'u')
|
||||
until_addr = r_num_math (core->num, input + 2);
|
||||
else until_expr = "0";
|
||||
r_core_esil_step (core, until_addr, until_expr);
|
||||
r_core_esil_step (core, until_addr, until_expr, NULL);
|
||||
}
|
||||
break;
|
||||
case 'i': // "aei"
|
||||
@ -3678,6 +3728,19 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
r_anal_esil_free (esil);
|
||||
break;
|
||||
}
|
||||
case 's': // "aets"
|
||||
switch (input[2]) {
|
||||
case 0:
|
||||
r_anal_esil_session_list (esil);
|
||||
break;
|
||||
case '+':
|
||||
r_anal_esil_session_add (esil);
|
||||
break;
|
||||
default:
|
||||
r_core_cmd_help (core, help_msg_aets);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
eprintf ("Unknown command. Use `aetr`.\n");
|
||||
break;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* radare - LGPL - Copyright 2017 - rkx1209 */
|
||||
|
||||
#include <r_debug.h>
|
||||
|
||||
R_API void r_debug_session_free(RDebugSession *session) {
|
||||
|
@ -965,8 +965,17 @@ typedef struct r_anal_reil {
|
||||
|
||||
// must be a char
|
||||
#define ESIL_INTERNAL_PREFIX '$'
|
||||
#define ESIL_STACK_NAME "esil.ram"
|
||||
#define ESIL struct r_anal_esil_t
|
||||
|
||||
typedef struct r_anal_esil_session_t {
|
||||
ut64 key;
|
||||
ut64 addr;
|
||||
ut64 size;
|
||||
ut8 *data;
|
||||
RListIter *reg[R_REG_TYPE_LAST];
|
||||
} RAnalEsilSession;
|
||||
|
||||
typedef struct r_anal_esil_callbacks_t {
|
||||
void *user;
|
||||
/* callbacks */
|
||||
@ -998,6 +1007,8 @@ typedef struct r_anal_esil_t {
|
||||
int verbose;
|
||||
ut64 flags;
|
||||
ut64 address;
|
||||
ut64 stack_addr;
|
||||
ut32 stack_size;
|
||||
int delay; // mapped to $ds in ESIL
|
||||
ut64 jump_target; // mapped to $jt in ESIL
|
||||
int jump_target_set; // mapped to $js in ESIL
|
||||
@ -1024,6 +1035,7 @@ typedef struct r_anal_esil_t {
|
||||
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;
|
||||
RList *sessions; // <RAnalEsilSession*>
|
||||
} RAnalEsil;
|
||||
|
||||
#undef ESIL
|
||||
@ -1267,6 +1279,12 @@ R_API int r_anal_esil_fire_interrupt (RAnalEsil *esil, int interrupt);
|
||||
R_API void r_anal_esil_mem_ro(RAnalEsil *esil, int mem_readonly);
|
||||
R_API void r_anal_esil_stats(RAnalEsil *esil, int enable);
|
||||
|
||||
/* session */
|
||||
R_API void r_anal_esil_session_list(RAnalEsil *esil);
|
||||
R_API RAnalEsilSession *r_anal_esil_session_add(RAnalEsil *esil);
|
||||
R_API void r_anal_esil_session_set(RAnalEsil *esil, RAnalEsilSession *session);
|
||||
R_API void r_anal_esil_session_free(RAnalEsilSession *session);
|
||||
|
||||
/* pin */
|
||||
R_API void r_anal_pin_init(RAnal *a);
|
||||
R_API void r_anal_pin_fini(RAnal *a);
|
||||
|
@ -370,7 +370,8 @@ R_API int r_core_anal_search_xrefs(RCore *core, ut64 from, ut64 to, int rad);
|
||||
R_API int r_core_anal_data (RCore *core, ut64 addr, int count, int depth, int wordsize);
|
||||
R_API void r_core_anal_coderefs(RCore *core, ut64 addr, int gv);
|
||||
R_API int r_core_anal_refs(RCore *core, const char *input);
|
||||
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr);
|
||||
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr);
|
||||
R_API int r_core_esil_step_back(RCore *core);
|
||||
R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head);
|
||||
R_API ut64 r_core_anal_get_bbaddr(RCore *core, ut64 addr);
|
||||
R_API int r_core_anal_bb_seek(RCore *core, ut64 addr);
|
||||
|
Loading…
Reference in New Issue
Block a user