Add esil.gotolimit to restrict the number of words to run after an esil goto

This commit is contained in:
pancake 2015-04-01 00:38:24 +02:00
parent 48b6d41a55
commit eb42823a51
5 changed files with 31 additions and 11 deletions

View File

@ -62,6 +62,7 @@ R_API RAnal *r_anal_new() {
RAnalPlugin *static_plugin;
RAnal *anal = R_NEW0 (RAnal);
if (!anal) return NULL;
anal->esil_goto_limit = R_ANAL_ESIL_GOTO_LIMIT;
anal->limit = NULL;
anal->nopskip = R_TRUE; // skip nops in code analysis
anal->decode = R_TRUE; // slow slow if not used

View File

@ -14,14 +14,12 @@ static inline ut64 mask (int bits) {
}
/* magic limit */
#define R_ANAL_ESIL_GOTO_LIMIT 457
// TODO: this must be configurable from 'e' somehow
R_API RAnalEsil *r_anal_esil_new() {
RAnalEsil *esil = R_NEW0 (RAnalEsil);
if (!esil) return NULL;
esil->parse_goto_limit = R_ANAL_ESIL_GOTO_LIMIT;
esil->parse_goto_count = esil->parse_goto_limit;
esil->parse_goto_count = R_ANAL_ESIL_GOTO_LIMIT;
esil->ops = sdb_new0 ();
return esil;
}
@ -2247,7 +2245,6 @@ static int iscommand (RAnalEsil *esil, const char *word, RAnalEsilOp *op) {
static int runword (RAnalEsil *esil, const char *word) {
RAnalEsilOp op = NULL;
esil->parse_goto_count--;
if (esil->parse_goto_count<1) {
eprintf ("ESIL infinite loop detected\n");
esil->trap = 1; // INTERNAL ERROR
@ -2348,7 +2345,11 @@ loop:
esil->skip = 0;
esil->parse_goto = -1;
esil->parse_stop = 0;
esil->parse_goto_count = esil->parse_goto_limit;
if (esil->anal) {
esil->parse_goto_count = esil->anal->esil_goto_limit;
} else {
esil->parse_goto_count = R_ANAL_ESIL_GOTO_LIMIT;
}
str = ostr;
repeat:
wordi = 0;
@ -2435,6 +2436,7 @@ R_API int r_anal_esil_setup (RAnalEsil *esil, RAnal *anal, int romem, int stats)
// this is: set
esil->debug = 1;
esil->anal = anal;
esil->parse_goto_count = anal->esil_goto_limit;
esil->trap = 0;
esil->trap_code = 0;
//esil->user = NULL;

View File

@ -492,6 +492,18 @@ static int cb_dbgbackend(void *user, void *data) {
return R_TRUE;
}
static int cb_gotolimit(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode*) data;
if (r_sandbox_enable (0)) {
eprintf ("Cannot change gotolimit\n");
return R_FALSE;
}
if (core->anal->esil)
core->anal->esil_goto_limit = node->i_value;
return R_TRUE;
}
static int cb_esildebug (void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode*) data;
@ -973,6 +985,7 @@ R_API int r_core_config_init(RCore *core) {
SETICB("anal.maxreflines", 0, &cb_analmaxrefs, "Maximum number of reflines to be analyzed and displayed in asm.lines with pd");
SETCB("esil.debug", "false", &cb_esildebug, "Show esil debug info");
SETICB("esil.gotolimit", core->anal->esil_goto_limit, &cb_gotolimit, "Maximum number of gotos per esil expression");
/* asm */
//asm.os needs to be first, since other asm.* depend on it

View File

@ -654,10 +654,12 @@ repeat:
goto beach;
break;
case 9: // tab
curnode++;
if (!nodes[curnode].text)
curnode = 0;
updateSeek (can, &N, w, h, 0);
if (curnode+1<n_nodes) {
curnode++;
if (!nodes[curnode].text)
curnode = 0;
updateSeek (can, &N, w, h, 0);
}
break;
case '?':
r_cons_clear00 ();

View File

@ -546,6 +546,8 @@ typedef struct r_anal_callbacks_t {
int (*on_fcn_bb_new) (RANAL, void *user, RAnalFunction *fcn, RANAL_BLOCK bb);
} RAnalCallbacks;
#define R_ANAL_ESIL_GOTO_LIMIT 4096
typedef struct r_anal_t {
char *cpu;
int bits;
@ -576,6 +578,7 @@ typedef struct r_anal_t {
int recont; // continue on recurse analysis mode
int maxreflines;
int trace;
int esil_goto_limit;
RList *types;
//struct r_anal_ctx_t *ctx;
struct r_anal_esil_t *esil;
@ -846,7 +849,6 @@ typedef struct r_anal_esil_t {
int repeat;
int parse_stop;
int parse_goto;
int parse_goto_limit;
int parse_goto_count;
int debug;
ut64 flags;
@ -1044,7 +1046,7 @@ R_API RAnalOp *r_anal_op_hexstr(RAnal *anal, ut64 addr,
const char *hexstr);
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op);
R_API RAnalEsil *r_anal_esil_new (void);
R_API RAnalEsil *r_anal_esil_new ();
R_API void r_anal_esil_trace (RAnalEsil *esil, RAnalOp *op);
R_API void r_anal_esil_trace_list (RAnalEsil *esil);
R_API void r_anal_esil_trace_show (RAnalEsil *esil, int idx);