fix a memleak and implement esil.stacksize for @crowell

This commit is contained in:
condret 2016-01-19 23:36:21 +00:00
parent 438071e8e1
commit ccab168cb5
7 changed files with 40 additions and 23 deletions

View File

@ -53,9 +53,14 @@ static bool popRN(RAnalEsil *esil, ut64 *n) {
/* R_ANAL_ESIL API */
R_API RAnalEsil *r_anal_esil_new(int iotrap) {
R_API RAnalEsil *r_anal_esil_new(int stacksize, int iotrap) {
RAnalEsil *esil = R_NEW0 (RAnalEsil);
if (!esil) return NULL;
if (!esil || stacksize < 3) return NULL;
if (!(esil->stack = malloc (sizeof(char *) * stacksize))) {
free (esil);
return NULL;
}
esil->stacksize = stacksize;
esil->parse_goto_count = R_ANAL_ESIL_GOTO_LIMIT;
esil->ops = sdb_new0 ();
esil->iotrap = iotrap;
@ -161,6 +166,7 @@ R_API void r_anal_esil_free(RAnalEsil *esil) {
sdb_free (esil->stats);
esil->stats = NULL;
r_anal_esil_stack_free (esil);
free (esil->stack);
if (esil->anal && esil->anal->cur && esil->anal->cur->esil_fini)
esil->anal->cur->esil_fini (esil);
free (esil);
@ -302,7 +308,7 @@ R_API int r_anal_esil_pushnum(RAnalEsil *esil, ut64 num) {
}
R_API bool r_anal_esil_push(RAnalEsil *esil, const char *str) {
if (!str || !esil || !*str || esil->stackptr > (ESIL_STACK_SIZE - 2))
if (!str || !esil || !*str || esil->stackptr > (esil->stacksize - 1))
return false;
esil->stack[esil->stackptr++] = strdup (str);
return true;
@ -1982,7 +1988,7 @@ static int esil_num(RAnalEsil *esil) {
/* duplicate the last element in the stack */
static int esil_dup(RAnalEsil *esil) {
if (!esil || !esil->stack || esil->stackptr < 1 || esil->stackptr > (ESIL_STACK_SIZE - 2))
if (!esil || !esil->stack || esil->stackptr < 1 || esil->stackptr > (esil->stacksize - 1))
return false;
return r_anal_esil_push (esil, esil->stack[esil->stackptr-1]);
}
@ -2251,6 +2257,7 @@ repeat:
return 1;
}
//frees all elements from the stack, not the stack itself
R_API void r_anal_esil_stack_free(RAnalEsil *esil) {
int i;
if (esil) {

View File

@ -1413,7 +1413,8 @@ repeat:
int stats = r_config_get_i (core->config, "esil.stats");
int iotrap = r_config_get_i (core->config, "esil.iotrap");
int exectrap = r_config_get_i (core->config, "esil.exectrap");
core->anal->esil = r_anal_esil_new (iotrap);
int stacksize = r_config_get_i (core->config, "esil.stacksize");
core->anal->esil = r_anal_esil_new (stacksize, iotrap);
esil = core->anal->esil;
r_anal_esil_setup (esil, core->anal, romem, stats); // setup io
esil->exectrap = exectrap;
@ -1688,7 +1689,8 @@ static void esil_init (RCore *core) {
if (!opc || opc==UT64_MAX) opc = core->offset;
if (!core->anal->esil) {
int iotrap = r_config_get_i (core->config, "esil.iotrap");
core->anal->esil = r_anal_esil_new (iotrap);
int stacksize = r_config_get_i (core->config, "esil.stacksize");
core->anal->esil = r_anal_esil_new (stacksize, iotrap);
r_anal_esil_setup (core->anal->esil, core->anal, 0, 0);
}
free (regstate);
@ -1892,6 +1894,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
NULL };
RAnalEsil *esil = core->anal->esil;
ut64 addr = core->offset;
int stacksize = r_config_get_i (core->config, "esil.stacksize");
int iotrap = r_config_get_i (core->config, "esil.iotrap");
int romem = r_config_get_i (core->config, "esil.romem");
int stats = r_config_get_i (core->config, "esil.stats");
@ -1945,7 +1948,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
case ' ':
//r_anal_esil_eval (core->anal, input+1);
if (!esil) {
core->anal->esil = esil = r_anal_esil_new (iotrap);
core->anal->esil = esil = r_anal_esil_new (stacksize, iotrap);
}
r_anal_esil_setup (esil, core->anal, romem, stats); // setup io
r_anal_esil_set_pc (esil, core->offset);
@ -2075,10 +2078,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
r_core_cmd0 (core, "ar PC=$$");
}
}
iotrap = r_config_get_i (core->config, "esil.iotrap");
esil = core->anal->esil = r_anal_esil_new (iotrap);
romem = r_config_get_i (core->config, "esil.romem");
stats = r_config_get_i (core->config, "esil.stats");
esil = core->anal->esil = r_anal_esil_new (stacksize, iotrap);
r_anal_esil_setup (esil, core->anal, romem, stats); // setup io
esil->debug = (int)r_config_get_i (core->config, "esil.debug");
/* restore user settings for interrupt handling */
@ -2149,14 +2149,12 @@ static void cmd_anal_esil(RCore *core, const char *input) {
case 'r': // "aetr"
{
// anal ESIL to REIL.
int romem = r_config_get_i (core->config, "esil.romem");
int stats = r_config_get_i (core->config, "esil.stats");
RAnalEsil *esil = r_anal_esil_new (iotrap);
RAnalEsil *esil = r_anal_esil_new (stacksize, iotrap);
r_anal_esil_to_reil_setup (esil, core->anal, romem, stats);
r_anal_esil_set_pc (esil, core->offset);
r_anal_esil_parse (esil, input + 2);
r_anal_esil_dumpstack (esil);
r_anal_esil_stack_free (esil);
r_anal_esil_free (esil);
break;
}
default:
@ -3215,10 +3213,11 @@ static void cmd_anal_trace(RCore *core, const char *input) {
break;
case 'e': // "ate"
if (!core->anal->esil) {
int stacksize = r_config_get_i (core->config, "esil.stacksize");
int romem = r_config_get_i (core->config, "esil.romem");
int stats = r_config_get_i (core->config, "esil.stats");
int iotrap = r_config_get_i (core->config, "esil.iotrap");
core->anal->esil = r_anal_esil_new (iotrap);
core->anal->esil = r_anal_esil_new (stacksize, iotrap);
r_anal_esil_setup (core->anal->esil,
core->anal, romem, stats);
}

View File

@ -1163,13 +1163,14 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c
if (input[1]==' ') {
const int kwidx = r_config_get_i (core->config, "search.kwidx");
const int iotrap = r_config_get_i (core->config, "esil.iotrap");
const int stacksize = r_config_get_i (core->config, "esil.stacksize");
int hit_happens = 0;
int hit_combo = 0;
char *res;
ut64 nres, addr = param->from;
r_cons_break (NULL, NULL);
if (!core->anal->esil)
core->anal->esil = r_anal_esil_new (iotrap);
core->anal->esil = r_anal_esil_new (stacksize, iotrap);
/* hook addrinfo */
core->anal->esil->cb.user = core;
r_anal_esil_set_op (core->anal->esil, "AddrInfo", esil_addrinfo);

View File

@ -720,6 +720,15 @@ static int cb_esildebug (void *user, void *data) {
return true;
}
static int cb_esilstacksize (void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (node->i_value < 3) {
eprintf ("esil.stacksize must be greater than 2\n");
node->i_value = 32;
}
return true;
}
static int cb_fixrows(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton ()->fix_rows = (int)node->i_value;
@ -1418,6 +1427,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("esil.prestep", "true", "Step before esil evaluation in `de` commands");
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");
SETICB("esil.stacksize", 32, &cb_esilstacksize, "Number of elements that can be pushed on the esilstack");
/* asm */
//asm.os needs to be first, since other asm.* depend on it

View File

@ -2108,7 +2108,8 @@ static void handle_print_esil_anal_init(RCore *core, RDisasmState *ds) {
}
if (!core->anal->esil) {
int iotrap = r_config_get_i (core->config, "esil.iotrap");
core->anal->esil = r_anal_esil_new (iotrap);
int stacksize = r_config_get_i (core->config, "esil.stacksize");
core->anal->esil = r_anal_esil_new (stacksize, iotrap);
r_anal_esil_setup (core->anal->esil, core->anal, 0, 0);
}
free (regstate);

View File

@ -208,7 +208,7 @@ R_API int r_debug_esil_stepi (RDebug *d) {
int ret = 1;
dbg = d;
if (!ESIL) {
ESIL = r_anal_esil_new (R_TRUE);
ESIL = r_anal_esil_new (32, R_TRUE);
// TODO setup something?
}

View File

@ -965,11 +965,10 @@ typedef struct r_anal_esil_callbacks_t {
int (*reg_write)(ESIL *esil, const char *name, ut64 val);
} RAnalEsilCallbacks;
#define ESIL_STACK_SIZE 32
typedef struct r_anal_esil_t {
RAnal *anal;
char *stack[ESIL_STACK_SIZE];
char **stack;
int stacksize;
int stackptr;
int skip;
int nowrite;
@ -1192,7 +1191,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 (int iotrap);
R_API RAnalEsil *r_anal_esil_new (int stacksize, int iotrap);
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);