libr/parse: add another view for function variable/arguments (#7048)

This commit is contained in:
Riccardo Schirone 2017-03-17 11:54:34 +01:00 committed by radare
parent 56aeb2a6e3
commit 084d5c1217
6 changed files with 36 additions and 24 deletions

View File

@ -1854,6 +1854,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("asm.vars", "true", "Show local function variables in disassembly");
SETPREF("asm.varxs", "false", "Show accesses of local variables");
SETPREF("asm.varsub", "true", "Substitute variables in disassembly");
SETPREF("asm.varsub_only", "true", "Substitute the entire variable expression with the local variable name (e.g. [local10h] instead of [ebp+local10h])");
SETPREF("asm.relsub", "true", "Substitute pc relative expressions in disasm");
SETPREF("asm.cmtfold", "false", "Fold comments, toggle with Vz");
SETPREF("asm.family", "false", "Show family name in disasm");

View File

@ -3980,6 +3980,7 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
} else if (input[1] == 'j') { // "axtj"
bool asm_varsub = r_config_get_i (core->config, "asm.varsub");
core->parser->relsub = r_config_get_i (core->config, "asm.relsub");
core->parser->localvar_only = r_config_get_i (core->config, "asm.varsub_only");
r_cons_printf ("[");
r_list_foreach (list, iter, ref) {
r_core_read_at (core, ref->addr, buf, size);
@ -4011,6 +4012,7 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
char *comment;
bool asm_varsub = r_config_get_i (core->config, "asm.varsub");
core->parser->relsub = r_config_get_i (core->config, "asm.relsub");
core->parser->localvar_only = r_config_get_i (core->config, "asm.varsub_only");
if (core->parser->relsub) {
core->parser->relsub_addr = addr;
}

View File

@ -445,6 +445,7 @@ static RDisasmState * ds_init(RCore *core) {
ds->interactive = r_config_get_i (core->config, "scr.interactive");
ds->varsub = r_config_get_i (core->config, "asm.varsub");
core->parser->relsub = r_config_get_i (core->config, "asm.relsub");
core->parser->localvar_only = r_config_get_i (core->config, "asm.varsub_only");
ds->show_vars = r_config_get_i (core->config, "asm.vars");
ds->show_varxs = r_config_get_i (core->config, "asm.varxs");
ds->maxrefs = r_config_get_i (core->config, "asm.maxrefs");
@ -1081,6 +1082,13 @@ static ut32 tmp_get_realsize (RAnalFunction *f) {
return (size > 0) ? size : r_anal_fcn_size (f);
}
static void ds_show_functions_argvar(RDisasmState *ds, RAnalVar *var, const char *base, bool is_var, char sign) {
int delta = sign == '+' ? var->delta : -var->delta;
const char *arg_or_var = is_var ? "var" : "arg";
r_cons_printf ("%s %s %s @ %s%c0x%x", arg_or_var, var->type, var->name,
base, sign, delta);
}
static void ds_show_functions(RDisasmState *ds) {
RAnalFunction *f;
RCore *core = ds->core;
@ -1241,17 +1249,11 @@ static void ds_show_functions(RDisasmState *ds) {
}
r_cons_printf ("%s; ", COLOR (ds, color_other));
switch (var->kind) {
case 'b':
if (var->delta > 0) {
r_cons_printf ("arg %s %s @ %s+0x%x",
var->type, var->name,
anal->reg->name[R_REG_NAME_BP],
var->delta);
} else {
r_cons_printf ("var %s %s @ %s-0x%x",
var->type, var->name,
anal->reg->name[R_REG_NAME_BP],
-var->delta);
case 'b': {
char sign = var->delta > 0 ? '+' : '-';
bool is_var = var->delta <= 0;
ds_show_functions_argvar (ds, var,
anal->reg->name[R_REG_NAME_BP], is_var, sign);
}
break;
case 'r': {
@ -1264,17 +1266,11 @@ static void ds_show_functions(RDisasmState *ds) {
var->type, var->name, i->name);
}
break;
case 's':
if ( var->delta < f->maxstack) {
r_cons_printf ("var %s %s @ %s+0x%x",
var->type, var->name,
anal->reg->name[R_REG_NAME_SP],
var->delta);
} else {
r_cons_printf ("arg %s %s @ %s+0x%x",
var->type, var->name,
anal->reg->name[R_REG_NAME_SP],
var->delta);
case 's': {
bool is_var = var->delta < f->maxstack;
ds_show_functions_argvar (ds, var,
anal->reg->name[R_REG_NAME_SP],
is_var, '+');
}
break;
}

View File

@ -23,6 +23,7 @@ typedef struct r_parse_t {
int flagspace;
int notin_flagspace;
bool relsub; // replace rip relative expressions in instruction
bool localvar_only; // if true use only the local variable name (e.g. [local_10h] instead of [ebp + local10h])
int relsub_addr;
struct r_parse_plugin_t *cur;
RAnal *anal; // weak anal ref

View File

@ -210,6 +210,14 @@ static inline int issegoff (const char *w) {
}
#endif
static void parse_localvar(RParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign) {
if (p->localvar_only) {
snprintf (newstr, newstr_len - 1, "[%s]", var);
} else {
snprintf (newstr, newstr_len - 1, "[%s %c %s]", reg, sign, var);
}
}
static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) {
RAnalVar *reg, *bparg, *sparg;
RListIter *regiter, *bpargiter, *spiter;
@ -265,7 +273,8 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat
if (ucase) {
r_str_case (oldstr, true);
}
snprintf (newstr, sizeof (newstr) - 1, "[%s]", sparg->name);
parse_localvar (p, newstr, sizeof (newstr), sparg->name,
p->anal->reg->name[R_REG_NAME_SP], '+');
if (ucase) {
char *plus = strchr (newstr, '+');
if (plus) {
@ -308,7 +317,8 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat
if (ucase) {
r_str_case (oldstr, true);
}
snprintf (newstr, sizeof (newstr) - 1, "[%s]", bparg->name);
parse_localvar (p, newstr, sizeof (newstr), bparg->name,
p->anal->reg->name[R_REG_NAME_BP], sign);
if (ucase) {
char *plus = strchr (newstr, sign);
if (plus) {

View File

@ -25,6 +25,8 @@ R_API RParse *r_parse_new() {
p->parsers->free = NULL; // memleak
p->notin_flagspace = -1;
p->flagspace = -1;
p->relsub = false;
p->localvar_only = false;
for (i = 0; parse_static_plugins[i]; i++) {
r_parse_add (p, parse_static_plugins[i]);
}