* More work in var analysis
* Put RAnalVar->type and RAnalVar->dir together
This commit is contained in:
parent
b955a66459
commit
fc11acc128
|
@ -63,7 +63,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
|||
fcn->ninstr++;
|
||||
idx += oplen;
|
||||
fcn->size += oplen;
|
||||
/* TODO: Parse fastargs (R_ANAL_VAR_ARGREG), check negative ref meaning */
|
||||
/* TODO: Parse fastargs (R_ANAL_VAR_ARGREG) */
|
||||
switch (aop.stackop) {
|
||||
case R_ANAL_STACK_INCSTACK:
|
||||
fcn->stack += aop.value;
|
||||
|
@ -71,24 +71,24 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
|||
case R_ANAL_STACK_SET:
|
||||
if (aop.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||
R_ANAL_VAR_DIR_IN, NULL, varname, 1);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref,
|
||||
R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 1);
|
||||
} else {
|
||||
varname = r_str_dup_printf ("local_%x", -aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
||||
R_ANAL_VAR_DIR_NONE, NULL, varname, 1);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref,
|
||||
R_ANAL_VAR_TYPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 1);
|
||||
}
|
||||
free (varname);
|
||||
break;
|
||||
case R_ANAL_STACK_GET:
|
||||
if (aop.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||
R_ANAL_VAR_DIR_IN, NULL, varname, 0);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref,
|
||||
R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 0);
|
||||
} else {
|
||||
varname = r_str_dup_printf ("local_%x", -aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
||||
R_ANAL_VAR_DIR_NONE, NULL, varname, 0);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref,
|
||||
R_ANAL_VAR_TYPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 0);
|
||||
}
|
||||
free (varname);
|
||||
break;
|
||||
|
@ -176,13 +176,13 @@ R_API RAnalFcn *r_anal_fcn_find(RAnal *anal, ut64 addr, int type) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
R_API RAnalVar *r_anal_fcn_get_var(RAnalFcn *fs, int num, int dir) {
|
||||
R_API RAnalVar *r_anal_fcn_get_var(RAnalFcn *fs, int num, int type) {
|
||||
RAnalVar *var;
|
||||
RListIter *iter;
|
||||
int count = 0;
|
||||
// vars are sorted by delta in r_anal_var_add()
|
||||
r_list_foreach (fs->vars, iter, var) {
|
||||
if (dir & var->dir)
|
||||
if (type & var->type)
|
||||
if (count++ == num)
|
||||
return var;
|
||||
}
|
||||
|
@ -194,27 +194,29 @@ R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFcn* fs) {
|
|||
char *sign;
|
||||
if (fs->type != R_ANAL_FCN_TYPE_FCN)
|
||||
return NULL;
|
||||
RAnalVar *arg, *ret = r_anal_fcn_get_var (fs, 0, R_ANAL_VAR_DIR_OUT);
|
||||
RAnalVar *arg, *ret = r_anal_fcn_get_var (fs, 0, R_ANAL_VAR_TYPE_RET);
|
||||
if (ret) sign = r_str_newf ("%s %s (", ret->name, fs->name);
|
||||
else sign = r_str_newf ("void %s (", fs->name);
|
||||
for (i=0;;i++) {
|
||||
if (!(arg = r_anal_fcn_get_var (fs, i, R_ANAL_VAR_DIR_IN)))
|
||||
if (!(arg = r_anal_fcn_get_var (fs, i,
|
||||
R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_TYPE_ARGREG)))
|
||||
break;
|
||||
if (arg->array>1) {
|
||||
if (i) sign = r_str_concatf (sign, ", %s %s[%d]", arg->vartype, arg->name, arg->array);
|
||||
else sign = r_str_concatf (sign, "%s %s[%d]", arg->vartype, arg->name, arg->array);
|
||||
if (i) sign = r_str_concatf (sign, ", %s %s:%02x[%d]", arg->vartype, arg->name, arg->delta, arg->array);
|
||||
else sign = r_str_concatf (sign, "%s %s:%02x[%d]", arg->vartype, arg->name, arg->delta, arg->array);
|
||||
} else {
|
||||
if (i) sign = r_str_concatf (sign, ", %s %s", arg->vartype, arg->name);
|
||||
else sign = r_str_concatf (sign, "%s %s", arg->vartype, arg->name);
|
||||
if (i) sign = r_str_concatf (sign, ", %s %s:%02x", arg->vartype, arg->name, arg->delta);
|
||||
else sign = r_str_concatf (sign, "%s %s:%02x", arg->vartype, arg->name, arg->delta);
|
||||
}
|
||||
}
|
||||
return (sign = r_str_concatf (sign, ");"));
|
||||
}
|
||||
|
||||
R_API int r_anal_fcn_from_string(RAnal *a, RAnalFcn *f, const char *_str) {
|
||||
RAnalVar *var;
|
||||
char *str = strdup (_str);
|
||||
char *p, *q, *r;
|
||||
int arg;
|
||||
int i, arg;
|
||||
// TODO: This function is not fully implemented
|
||||
if (!a || !f) {
|
||||
eprintf ("r_anal_fcn_from_string: No function received\n");
|
||||
|
@ -238,11 +240,11 @@ R_API int r_anal_fcn_from_string(RAnal *a, RAnalFcn *f, const char *_str) {
|
|||
f->name = strdup (q+1);
|
||||
/* set return value */
|
||||
// TODO: simplify this complex api usage
|
||||
r_anal_var_add (a, f, 0LL, 0, R_ANAL_VAR_TYPE_RET,
|
||||
R_ANAL_VAR_DIR_OUT, str, "ret", 1);
|
||||
r_anal_var_add (a, f, 0LL, 0,
|
||||
R_ANAL_VAR_TYPE_RET|R_ANAL_VAR_DIR_OUT, str, "ret", 1);
|
||||
|
||||
/* parse arguments */
|
||||
for (arg=0,p++;;) {
|
||||
for (i=arg=0,p++;;p=q+1,i++) {
|
||||
q = strchr (p, ',');
|
||||
if (!q) {
|
||||
q = strchr (p, ')');
|
||||
|
@ -256,10 +258,11 @@ R_API int r_anal_fcn_from_string(RAnal *a, RAnalFcn *f, const char *_str) {
|
|||
r = r_str_chop (r+1);
|
||||
printf ("VAR %d=(%s)(%s)\n", arg, p, r);
|
||||
// TODO : increment arg by var size
|
||||
r_anal_var_add (a, f, 0LL, arg, R_ANAL_VAR_TYPE_ARG,
|
||||
R_ANAL_VAR_DIR_IN, p, r, 1);
|
||||
if ((var = r_anal_fcn_get_var (f, i, R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_TYPE_ARGREG))) {
|
||||
free (var->name); var->name = strdup (r);
|
||||
free (var->vartype); var->vartype = strdup (p);
|
||||
} else r_anal_var_add (a, f, 0LL, arg, R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN, p, r, 0);
|
||||
arg++;
|
||||
p=q+1;
|
||||
}
|
||||
// r_anal_fcn_set_var (fs, 0, R_ANAL_VAR_DIR_OUT, );
|
||||
free (str);
|
||||
|
|
|
@ -111,7 +111,7 @@ static int cmpdelta(RAnalVar *a, RAnalVar *b) {
|
|||
return (a->delta - b->delta);
|
||||
}
|
||||
|
||||
R_API int r_anal_var_add(RAnal *anal, RAnalFcn *fcn, ut64 from, int delta, int type, int dir, const char *vartype, const char *name, int set) {
|
||||
R_API int r_anal_var_add(RAnal *anal, RAnalFcn *fcn, ut64 from, int delta, int type, const char *vartype, const char *name, int set) {
|
||||
RAnalVar *var, *vari;
|
||||
RListIter *iter;
|
||||
if (from != 0LL)
|
||||
|
@ -125,7 +125,8 @@ R_API int r_anal_var_add(RAnal *anal, RAnalFcn *fcn, ut64 from, int delta, int t
|
|||
if (vartype)
|
||||
var->vartype = strdup (vartype);
|
||||
var->type = type;
|
||||
var->dir = dir;
|
||||
if ((type & R_ANAL_VAR_TYPE_ARG) || (type & R_ANAL_VAR_TYPE_ARGREG))
|
||||
fcn->nargs++;
|
||||
var->delta = delta;
|
||||
if (from != 0LL)
|
||||
r_anal_var_access_add (anal, var, from, set);
|
||||
|
@ -155,12 +156,16 @@ R_API RAnalVar *r_anal_var_get(RAnal *anal, RAnalFcn *fcn, int delta, int type)
|
|||
|
||||
// XXX: rename function type? i think this is 'scope'
|
||||
R_API const char *r_anal_var_type_to_str (RAnal *anal, int type) {
|
||||
switch(type) {
|
||||
case R_ANAL_VAR_TYPE_GLOBAL: return "global";
|
||||
case R_ANAL_VAR_TYPE_LOCAL: return "local";
|
||||
case R_ANAL_VAR_TYPE_ARG: return "arg";
|
||||
case R_ANAL_VAR_TYPE_ARGREG: return "fastarg";
|
||||
}
|
||||
if (type & R_ANAL_VAR_TYPE_GLOBAL)
|
||||
return "global";
|
||||
else if (type & R_ANAL_VAR_TYPE_LOCAL)
|
||||
return "local";
|
||||
else if (type & R_ANAL_VAR_TYPE_ARG)
|
||||
return "arg";
|
||||
else if (type & R_ANAL_VAR_TYPE_ARGREG)
|
||||
return "fastarg";
|
||||
else if (type & R_ANAL_VAR_TYPE_RET)
|
||||
return "ret";
|
||||
return "(?)";
|
||||
}
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
|
|||
r_cons_printf("\n ");
|
||||
if(fcn&&fcn->name) r_cons_printf ("; %s(", fcn->name);
|
||||
else r_cons_printf ("; 0x%08"PFMT64x"(", analop.jump);
|
||||
if(fcn) nargs = (fcn->nargs>nargs?nargs:fcn->nargs);
|
||||
for(i=0;i<nargs;i++) {
|
||||
if (args[i]>1024) r_cons_printf("%d", args[nargs-i]);
|
||||
else r_cons_printf("0x%x", args[nargs-i]);
|
||||
|
@ -1786,7 +1787,7 @@ static void var_help() {
|
|||
static int var_cmd(RCore *core, const char *str) {
|
||||
RAnalFcn *fcn = r_anal_fcn_find (core->anal, core->offset, R_ANAL_FCN_TYPE_FCN);
|
||||
char *p,*p2,*p3;
|
||||
int type, dir, delta, len = strlen(str)+1;
|
||||
int type, delta, len = strlen(str)+1;
|
||||
|
||||
p = alloca(len);
|
||||
memcpy(p, str, len);
|
||||
|
@ -1803,9 +1804,9 @@ static int var_cmd(RCore *core, const char *str) {
|
|||
case 'A': // fastcall arg
|
||||
// XXX nested dup
|
||||
switch (*str) {
|
||||
case 'v': type = R_ANAL_VAR_TYPE_LOCAL; dir = R_ANAL_VAR_DIR_NONE; break;
|
||||
case 'a': type = R_ANAL_VAR_TYPE_ARG; dir = R_ANAL_VAR_DIR_IN; break;
|
||||
case 'A': type = R_ANAL_VAR_TYPE_ARGREG; dir = R_ANAL_VAR_DIR_IN; break;
|
||||
case 'v': type = R_ANAL_VAR_TYPE_LOCAL|R_ANAL_VAR_DIR_NONE; break;
|
||||
case 'a': type = R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN; break;
|
||||
case 'A': type = R_ANAL_VAR_TYPE_ARGREG|R_ANAL_VAR_DIR_IN; break;
|
||||
default:
|
||||
eprintf ("Unknown type\n");
|
||||
return 0;
|
||||
|
@ -1841,7 +1842,7 @@ static int var_cmd(RCore *core, const char *str) {
|
|||
p3[0]='\0';
|
||||
p3=p3+1;
|
||||
}
|
||||
r_anal_var_add (core->anal, fcn, core->offset, delta, type, dir, p, p2, p3?atoi(p3):0);
|
||||
r_anal_var_add (core->anal, fcn, core->offset, delta, type, p, p2, p3?atoi(p3):0);
|
||||
} else var_help();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -74,13 +74,18 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
R_ANAL_VAR_TYPE_NULL = 0,
|
||||
R_ANAL_VAR_TYPE_GLOBAL,
|
||||
R_ANAL_VAR_TYPE_LOCAL,
|
||||
R_ANAL_VAR_TYPE_ARG,
|
||||
R_ANAL_VAR_TYPE_ARGREG,
|
||||
R_ANAL_VAR_TYPE_RET,
|
||||
R_ANAL_VAR_TYPE_NULL = 0,
|
||||
R_ANAL_VAR_TYPE_GLOBAL = 0x01,
|
||||
R_ANAL_VAR_TYPE_LOCAL = 0x02,
|
||||
R_ANAL_VAR_TYPE_ARG = 0x04,
|
||||
R_ANAL_VAR_TYPE_ARGREG = 0x08,
|
||||
R_ANAL_VAR_TYPE_RET = 0x10,
|
||||
};
|
||||
typedef enum {
|
||||
R_ANAL_VAR_DIR_NONE = 0,
|
||||
R_ANAL_VAR_DIR_IN = 0x100,
|
||||
R_ANAL_VAR_DIR_OUT = 0x200
|
||||
} _RAnalVarDir;
|
||||
|
||||
typedef enum {
|
||||
R_ANAL_DATA_NULL = 0,
|
||||
|
@ -221,6 +226,7 @@ typedef struct r_anal_fcn_t {
|
|||
int stack;
|
||||
int diff;
|
||||
int ninstr;
|
||||
int nargs;
|
||||
RNumBig *fingerprint;
|
||||
RList *vars;
|
||||
RList *refs;
|
||||
|
@ -232,19 +238,12 @@ typedef struct r_anal_var_access_t {
|
|||
int set;
|
||||
} RAnalVarAccess;
|
||||
|
||||
typedef enum {
|
||||
R_ANAL_VAR_DIR_NONE = 0,
|
||||
R_ANAL_VAR_DIR_IN = 1,
|
||||
R_ANAL_VAR_DIR_OUT = 2
|
||||
} _RAnalVarDir;
|
||||
|
||||
typedef struct r_anal_var_t {
|
||||
char *name; /* name of the variable */
|
||||
ut64 addr; // not used correctly?
|
||||
ut64 eaddr; // not used correctly?
|
||||
int delta; /* delta offset inside stack frame */
|
||||
int dir; /* direction (in, out) */
|
||||
int type; /* global, local... */
|
||||
int type; /* global, local... | in, out... */
|
||||
int array; /* array size */
|
||||
char *vartype; /* float, int... */
|
||||
/* probably dupped or so */
|
||||
|
@ -360,7 +359,7 @@ R_API int r_anal_var_type_add(RAnal *anal, const char *name, int size, const cha
|
|||
R_API int r_anal_var_type_del(RAnal *anal, const char *name);
|
||||
R_API RAnalVarType *r_anal_var_type_get(RAnal *anal, const char *name);
|
||||
R_API int r_anal_var_add(RAnal *anal, RAnalFcn *fcn, ut64 from, int delta, int type,
|
||||
int dir, const char *vartype, const char *name, int set);
|
||||
const char *vartype, const char *name, int set);
|
||||
R_API int r_anal_var_del(RAnal *anal, RAnalFcn *fcn, int delta, int type);
|
||||
R_API RAnalVar *r_anal_var_get(RAnal *anal, RAnalFcn *fcn, int delta, int type);
|
||||
R_API const char *r_anal_var_type_to_str (RAnal *anal, int type);
|
||||
|
|
Loading…
Reference in New Issue