Improve array indexing in disassembly ##anal

This commit is contained in:
sivaramaaa 2018-11-02 22:57:45 +05:30 committed by radare
parent b4e2ebd031
commit bc4b5933d2
3 changed files with 51 additions and 14 deletions

View File

@ -911,6 +911,17 @@ static void ds_highlight_word(RDisasmState * ds, char *word, char *color) {
ds->opstr = asm_str? asm_str: source;
}
static char *get_op_ireg (void *user, ut64 addr) {
RCore *core = (RCore *)user;
char *res = NULL;
RAnalOp *op = r_core_anal_op (core, addr, R_ANAL_OP_MASK_ESIL);
if (op && op->ireg) {
res = strdup (op->ireg);
}
r_anal_op_free (op);
return res;
}
static void ds_build_op_str(RDisasmState *ds, bool print_color) {
RCore *core = ds->core;
if (!ds->opstr) {
@ -925,6 +936,7 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
ut64 at = ds->vat;
RAnalFunction *f = fcnIn (ds, at, R_ANAL_FCN_TYPE_NULL);
core->parser->varlist = r_anal_var_list_dynamic;
core->parser->get_op_ireg = get_op_ireg;
r_parse_varsub (core->parser, f, at, ds->analop.size,
ds->opstr, ds->strsub, sizeof (ds->strsub));
if (*ds->strsub) {

View File

@ -34,6 +34,7 @@ typedef struct r_parse_t {
RAnalHint *hint; // weak anal ref
RList *parsers;
RAnalVarList varlist;
char* (*get_op_ireg)(void *user, ut64 addr);
RAnalBind analb;
} RParse;

View File

@ -300,36 +300,55 @@ 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, bool att) {
static void parse_localvar (RParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, char *ireg, bool att) {
RStrBuf *sb = r_strbuf_new ("");
if (att) {
if (p->localvar_only) {
snprintf (newstr, newstr_len - 1, "%s", var);
if (ireg) {
r_strbuf_setf (sb, "(%%%s)", ireg);
}
snprintf (newstr, newstr_len - 1, "%s%s", var, r_strbuf_get (sb));
} else {
snprintf (newstr, newstr_len - 1, "%s(%%%s)", var, reg);
if (ireg) {
r_strbuf_setf (sb, ", %%%s", ireg);
}
snprintf (newstr, newstr_len - 1, "%s(%%%s%s)", var, reg, r_strbuf_get (sb));
}
} else {
if (ireg) {
r_strbuf_setf (sb, " + %s", ireg);
}
if (p->localvar_only) {
snprintf (newstr, newstr_len - 1, "[%s]", var);
snprintf (newstr, newstr_len - 1, "[%s%s]", var, r_strbuf_get (sb));
} else {
snprintf (newstr, newstr_len - 1, "[%s %c %s]", reg, sign, var);
snprintf (newstr, newstr_len - 1, "[%s%s %c %s]", reg, r_strbuf_get (sb), sign, var);
}
}
r_strbuf_free (sb);
}
static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, char *dest, int len) {
static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, char *ireg, char *dest, int len) {
RStrBuf *sb = r_strbuf_new ("");
if (att) {
if (ireg) {
r_strbuf_setf (sb, ", %%%s", ireg);
}
if (delta < 10) {
snprintf (dest, len - 1, "%s%d(%%%s)", sign ? "" : "-", delta, regname);
snprintf (dest, len - 1, "%s%d(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb));
} else {
snprintf (dest, len - 1, "%s0x%x(%%%s)", sign ? "" : "-", delta, regname);
snprintf (dest, len - 1, "%s0x%x(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb));
}
} else {
if (ireg) {
r_strbuf_setf (sb, " + %s", ireg);
}
if (delta < 10) {
snprintf (dest, len - 1, "[%s %c %d]", regname, sign ? '+':'-', delta);
snprintf (dest, len - 1, "[%s%s %c %d]", regname, r_strbuf_get (sb), sign ? '+':'-', delta);
} else {
snprintf (dest, len - 1, "[%s %c 0x%x]", regname, sign ? '+':'-', delta);
snprintf (dest, len - 1, "[%s%s %c 0x%x]", regname, r_strbuf_get (sb), sign ? '+':'-', delta);
}
}
r_strbuf_free (sb);
}
static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) {
@ -405,14 +424,18 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat
if (ucase && tstr[1]) {
ucase = tstr[1] >= 'A' && tstr[1] <= 'Z';
}
char *ireg = NULL;
if (p->get_op_ireg) {
ireg = p->get_op_ireg(p->user, addr);
}
r_list_foreach (spargs, spiter, sparg) {
// assuming delta always positive?
mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, oldstr, sizeof (oldstr));
mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, ireg, oldstr, sizeof (oldstr));
if (ucase) {
r_str_case (oldstr, true);
}
parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', att);
parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', ireg, att);
if (ucase) {
char *plus = strchr (newstr, '+');
if (plus) {
@ -443,11 +466,11 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat
sign = '-';
bparg->delta = -bparg->delta;
}
mk_reg_str (p->anal->reg->name[R_REG_NAME_BP], bparg->delta, sign=='+', att, oldstr, sizeof (oldstr));
mk_reg_str (p->anal->reg->name[R_REG_NAME_BP], bparg->delta, sign=='+', att, ireg, oldstr, sizeof (oldstr));
if (ucase) {
r_str_case (oldstr, true);
}
parse_localvar (p, newstr, sizeof (newstr), bparg->name, p->anal->reg->name[R_REG_NAME_BP], sign, att);
parse_localvar (p, newstr, sizeof (newstr), bparg->name, p->anal->reg->name[R_REG_NAME_BP], sign, ireg, att);
if (ucase) {
char *plus = strchr (newstr, sign);
if (plus) {
@ -498,6 +521,7 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat
ret = false;
}
free (tstr);
free (ireg);
r_list_free (spargs);
r_list_free (bpargs);
return ret;