R_API int r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) { char *fmt = r_anal_type_format (anal, type); RRegItem *i; if (!fmt) { eprintf ("type:%s doesn't exist\n", type); return false; } switch (kind) { case R_ANAL_VAR_KIND_REG: i = r_reg_index_get (anal->reg, delta); if (i) { anal->cb_printf ("pf r (%s)\n", i->name); } else { eprintf ("register not found\n"); } break; case R_ANAL_VAR_KIND_BPV: if (delta > 0) { anal->cb_printf ("pf %s @%s+0x%x\n", fmt, anal->reg->name[R_REG_NAME_BP], delta); } else { anal->cb_printf ("pf %s @%s-0x%x\n", fmt, anal->reg->name[R_REG_NAME_BP], -delta); } break; case R_ANAL_VAR_KIND_SPV: anal->cb_printf ("pf %s @ %s+0x%x\n", fmt, anal->reg->name[R_REG_NAME_SP], delta); break; } free (fmt); }
R_API bool r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) { char *fmt = r_type_format (anal->sdb_types, type); RRegItem *i; if (!fmt) { eprintf ("type:%s doesn't exist\n", type); return false; } bool usePxr = !strcmp (type, "int"); // hacky but useful switch (kind) { case R_ANAL_VAR_KIND_REG: i = r_reg_index_get (anal->reg, delta); if (i) { if (usePxr) { anal->cb_printf ("pxr $w @r:%s\n", i->name); } else { anal->cb_printf ("pf r (%s)\n", i->name); } } else { eprintf ("register not found\n"); } break; case R_ANAL_VAR_KIND_BPV: if (delta > 0) { if (usePxr) { anal->cb_printf ("pxr $w @%s+0x%x\n", anal->reg->name[R_REG_NAME_BP], delta); } else { anal->cb_printf ("pf %s @%s+0x%x\n", fmt, anal->reg->name[R_REG_NAME_BP], delta); } } else { if (usePxr) { anal->cb_printf ("pxr $w @%s-0x%x\n", anal->reg->name[R_REG_NAME_BP], -delta); } else { anal->cb_printf ("pf %s @%s-0x%x\n", fmt, anal->reg->name[R_REG_NAME_BP], -delta); } } break; case R_ANAL_VAR_KIND_SPV: if (usePxr) { anal->cb_printf ("pxr $w @%s+0x%x\n", anal->reg->name[R_REG_NAME_SP], delta); } else { anal->cb_printf ("pf %s @ %s+0x%x\n", fmt, anal->reg->name[R_REG_NAME_SP], delta); } break; } free (fmt); return true; }
static bool varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RList *spargs, *bpargs, *regargs; RAnalVar *var; RListIter *iter; char *oldstr, *newstr; char *tstr = strdup (data); if (!tstr) { return false; } if (!p->varlist) { free (tstr); return false; } if (p->relsub) { char *rip = (char *)r_str_casestr (tstr, "[pc, "); if (rip) { rip += 4; char *tstr_new, *ripend = strchr (rip, ']'); const char *neg = strchr (rip, '-'); ut64 off = (oplen == 2 || strstr (tstr, ".w")) ? 4 : 8; ut64 repl_num = (addr + off) & ~3; if (!ripend) { ripend = "]"; } if (neg) { repl_num -= r_num_get (NULL, neg + 1); } else { repl_num += r_num_get (NULL, rip); } rip -= 3; *rip = 0; tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend); free (tstr); tstr = tstr_new; } } regargs = p->varlist (p->anal, f, 'r'); bpargs = p->varlist (p->anal, f, 'b'); spargs = p->varlist (p->anal, f, 's'); bool ucase = IS_UPPER (*tstr); r_list_foreach (bpargs, iter, var) { if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[%s, %d]", p->anal->reg->name[R_REG_NAME_BP], var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[%s, 0x%x]", p->anal->reg->name[R_REG_NAME_BP], var->delta); } else { oldstr = r_str_newf ("[%s, -0x%x]", p->anal->reg->name[R_REG_NAME_BP], -var->delta); } if (ucase) { char *comma = strchr (oldstr, ','); if (comma) { *comma = 0; r_str_case (oldstr, true); *comma = ','; } } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[%s %c %s]", p->anal->reg->name[R_REG_NAME_BP], var->delta > 0 ? '+' : '-', var->name); if (ucase) { char *comma = strchr (newstr, ' '); if (comma) { *comma = 0; r_str_case (newstr, true); *comma = ' '; } } tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); } r_list_foreach (spargs, iter, var) { if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[sp, %d]", var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[sp, 0x%x]", var->delta); } else { oldstr = r_str_newf ("[sp, -0x%x]", -var->delta); } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[sp %c %s]", var->delta > 0 ? '+' : '-', var->name); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[%s, %d]", p->anal->reg->name[R_REG_NAME_SP], var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[%s, 0x%x]", p->anal->reg->name[R_REG_NAME_SP], var->delta); } else { oldstr = r_str_newf ("[%s, -0x%x]", p->anal->reg->name[R_REG_NAME_SP], -var->delta); } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[%s %c %s]", p->anal->reg->name[R_REG_NAME_BP], var->delta > 0 ? '+' : '-', var->name); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); } r_list_foreach (regargs, iter, var) { RRegItem *r = r_reg_index_get (p->anal->reg, var->delta); if (r && r->name && strstr (tstr, r->name)) { tstr = r_str_replace (tstr, r->name, var->name, 1); } }