diff --git a/libr/anal/anal.c b/libr/anal/anal.c index bd2b1643a7..5a85e056bc 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -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 diff --git a/libr/anal/rpnesil.c b/libr/anal/rpnesil.c index bae4c7ef52..4428d9a9f6 100644 --- a/libr/anal/rpnesil.c +++ b/libr/anal/rpnesil.c @@ -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; diff --git a/libr/core/config.c b/libr/core/config.c index 7c4b547bc5..5f19beb432 100644 --- a/libr/core/config.c +++ b/libr/core/config.c @@ -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 diff --git a/libr/core/graph.c b/libr/core/graph.c index d05f5c283f..18c1ba7998 100644 --- a/libr/core/graph.c +++ b/libr/core/graph.c @@ -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