local labels inside functions - initial support

This commit is contained in:
Anton Kochkov 2013-06-26 01:44:21 +04:00
parent ac4cedae53
commit 0711e60667
9 changed files with 144 additions and 5 deletions

View File

@ -30,6 +30,7 @@ R_API RAnalFunction *r_anal_fcn_new() {
fcn->diff = r_anal_diff_new ();
fcn->args = NULL;
fcn->locs = NULL;
fcn->locals = NULL;
return fcn;
}
@ -51,6 +52,7 @@ R_API void r_anal_fcn_free(void *_fcn) {
r_list_free (fcn->vars);
r_list_free (fcn->locs);
r_list_free (fcn->bbs);
r_list_free (fcn->locals);
free (fcn->fingerprint);
r_anal_diff_free (fcn->diff);
free (fcn->args);
@ -61,10 +63,10 @@ R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 ad
RAnalRef *ref;
if (!fcn || !anal || !(ref = r_anal_ref_new ()))
return R_FALSE;
ref->at = at; // from
ref->at = at; // from
ref->addr = addr; // to
ref->type = type;
r_anal_xrefs_set (anal, type=='d'?"data":"code", addr, at);
r_anal_xrefs_set (anal, type=='d'?"data":"code", addr, at);
// TODO: ensure we are not dupping xrefs
r_list_append (fcn->refs, ref);
return R_TRUE;
@ -85,6 +87,47 @@ R_API int r_anal_fcn_xref_del (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 ad
return R_FALSE;
}
R_API int r_anal_fcn_local_add (RAnal *anal, RAnalFunction *fcn, ut64 addr, const char *name) {
RAnalFcnLocal *l = R_NEW0 (RAnalFcnLocal);
if (!fcn || !anal) {
return R_FALSE;
}
l->addr = addr;
l->name = strdup (name);
// TODO: do not allow duplicate locals!
if (!fcn->locals)
fcn->locals = r_list_new();
r_list_append (fcn->locals, l);
return R_TRUE;
}
R_API int r_anal_fcn_local_del_name (RAnal *anal, RAnalFunction *fcn, const char *name) {
RAnalFcnLocal *l;
RListIter *iter;
/* No need for _safe loop coz we return immediately after the delete. */
r_list_foreach (fcn->locals, iter, l) {
if (!strcmp(l->name, name)) {
r_list_delete (fcn->locals, iter);
return R_TRUE;
}
}
return R_FALSE;
}
R_API int r_anal_fcn_local_del_addr (RAnal *anal, RAnalFunction *fcn, ut64 addr) {
RAnalFcnLocal *l;
RListIter *iter;
/* No need for _safe loop coz we return immediately after the delete. */
r_list_foreach (fcn->locals, iter, l) {
if (addr == 0UL || addr == l->addr) {
r_list_delete (fcn->locals, iter);
return R_TRUE;
}
}
return R_FALSE;
}
R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int reftype) {
RAnalOp op = {0};
char *varname;
@ -284,6 +327,17 @@ R_API RAnalFunction *r_anal_fcn_find(RAnal *anal, ut64 addr, int type) {
#endif
}
R_API RAnalFunction *r_anal_fcn_find_name(RAnal *anal, const char *name) {
RAnalFunction *fcn = NULL;
RListIter *iter;
r_list_foreach (anal->fcns, iter, fcn) {
if (!strcmp(name, fcn->name))
return fcn;
}
return NULL;
}
/* rename RAnalFunctionBB.add() */
R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff) {
RAnalBlock *bb = NULL, *bbi;

View File

@ -10,6 +10,8 @@ R_API void r_cons_pal_init(const char *foo) {
cons->pal.input = Color_WHITE;
cons->pal.comment = Color_CYAN;
cons->pal.fname = Color_CYAN;
cons->pal.flag = Color_CYAN;
cons->pal.label = Color_CYAN;
cons->pal.flow = Color_CYAN;
cons->pal.b0x00 = Color_GREEN;
cons->pal.b0x7f = Color_YELLOW;
@ -87,6 +89,8 @@ struct {
} keys[] = {
{ "comment", r_offsetof (RConsPalette, comment) },
{ "fname", r_offsetof (RConsPalette, fname) },
{ "flag", r_offsetof (RConsPalette, flag) },
{ "label", r_offsetof (RConsPalette, label) },
{ "flow", r_offsetof (RConsPalette, flow) },
{ "prompt", r_offsetof (RConsPalette, prompt) },
{ "offset", r_offsetof (RConsPalette, offset) },

View File

@ -586,6 +586,18 @@ static void fcn_list_bbs(RAnalFunction *fcn) {
}
}
R_API void r_core_anal_fcn_local_list(RAnalFunction *fcn) {
if (fcn && fcn->locals) {
RAnalFcnLocal *loc;
RListIter *iter;
r_list_foreach (fcn->locals, iter, loc) {
if ((loc != NULL) && (loc->name != NULL))
r_cons_printf (" %s at [%s + %lld] (0x%08llx)\n", loc->name,
fcn->name, loc->addr - fcn->addr, loc->addr);
}
}
}
R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
ut64 addr = r_num_math (core->num, input+1);
RListIter *iter, *iter2;

View File

@ -870,7 +870,7 @@ static int cmd_anal(void *data, const char *input) {
}
break;
case 'k':
{
{
const char *r = r_anal_data_kind (core->anal,
core->offset, core->block, core->blocksize);
r_cons_printf ("%s\n", r);

View File

@ -40,7 +40,28 @@ static int cmd_flag(void *data, const char *input) {
break;
case '+':
case ' ': {
char *s = NULL, *s2 = NULL, *eq = strchr (str, '=');
char *s = strchr (str, ' '), *s2 = NULL, *eq = strchr (str, '=');
if (s[1] == '.') { // local label, e.g. '.return'
RAnalFunction *fcn;
*s = '\0';
s2 = strchr (s+1, ' ');
if (s2) {
*s2 = '\0';
if (s2[1]&&s2[2])
off = r_num_math (core->num, s2+1);
}
char *name = s + 1;
if (*name) {
fcn = r_anal_fcn_find (core->anal, off,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
if (fcn) {
eprintf ("Adding %s to fcn %s at 0x%08llx\n", name, fcn->name, off);
r_anal_fcn_local_add (core->anal, fcn, off, name);
} else eprintf ("Cannot find function at 0x%08llx\n", off);
} else eprintf ("Usage: f+ [.name] [addr]\n");
break;
}
ut32 bsze = 1; //core->blocksize;
if (eq) {
// TODO: add support for '=' char in flag comments
@ -70,6 +91,18 @@ static int cmd_flag(void *data, const char *input) {
else r_flag_unset (core->flags, flagname, NULL);
} else r_flag_unset_i (core->flags, off, NULL);
break;
case '.':
{
RAnalFunction *fcn;
char *name = strdup (input+2);
if (*name) {
fcn = r_anal_fcn_find_name (core->anal, name);
if (fcn) {
r_core_anal_fcn_local_list (fcn);
} else eprintf ("Cannot find function %s\n", name);
} else eprintf ("Usage: f. [fname]\n");
}
break;
case 'l':
if (input[1] == ' ') {
RFlagItem *item = r_flag_get_i (core->flags,
@ -248,8 +281,10 @@ static int cmd_flag(void *data, const char *input) {
" f name 12 33 ; same as above\n"
" f name 12 33 cmt ; same as above + set flag comment\n"
" f+name 12 @ 33 ; like above but creates new one if doesnt exist\n"
" f+ .name 12 ; add local label at 12 offset, if it is inside function\n"
" f-name ; remove flag 'name'\n"
" f-@addr ; remove flag at address expression\n"
" f. fname ; list all local labels for the given function\n"
" fd addr ; return flag+delta\n"
//" fc [name] [cmt] ; set execution command for a specific flag\n"
" fC [name] [cmt] ; set comment for given flag\n"

View File

@ -139,6 +139,8 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
const char *color_comment = P(comment): Color_CYAN;
const char *color_fname = P(fname): Color_CYAN;
//const char *color_flow = P(flow): Color_CYAN;
const char *color_flag = P(flag): Color_CYAN;
const char *color_label = P(label): Color_CYAN;
const char *color_nop = P(nop): Color_BLUE;
const char *color_bin = P(bin): Color_YELLOW;
const char *color_math = P(math): Color_YELLOW;
@ -467,6 +469,23 @@ toro:
pre = "__"; // ignored?
if (f) {
//eprintf ("fun 0x%llx 0x%llx\n", at, f->addr+f->size-analop.length);
if (f->locals != NULL) {
RAnalFcnLocal *f_loc;
RListIter *l_iter;
r_list_foreach (f->locals, l_iter, f_loc) {
if (f_loc && f_loc->addr == at) {
if (show_lines && refline)
r_cons_strcat (refline);
if (show_offset)
r_cons_printf ("; -------- ");
if (show_color)
r_cons_printf ("%s %s\n", color_label, f_loc->name?f_loc->name:"unk");
else
r_cons_printf (" %s\n", f_loc->name?f_loc->name:"unk");
}
}
}
if (f->addr == at) {
char *sign = r_anal_fcn_to_string (core->anal, f);
if (f->type == R_ANAL_FCN_TYPE_LOC) {
@ -504,6 +523,8 @@ toro:
if (show_flags) {
flag = r_flag_get_i (core->flags, at);
if (flag) {
if (show_color)
r_cons_printf("%s", color_flag);
if (show_lines && refline)
r_cons_strcat (refline);
if (show_offset)

View File

@ -287,6 +287,11 @@ typedef struct r_anal_locals_t {
RAnalType *items;
} RAnalLocals;
typedef struct r_anal_fcn_local_t {
ut64 addr;
char* name;
} RAnalFcnLocal;
typedef struct r_anal_attr_t RAnalAttr;
struct r_anal_attr_t {
char *key;
@ -321,9 +326,10 @@ typedef struct r_anal_type_function_t {
int depth;
RAnalType *args; // list of arguments
RAnalVarSub varsubs[R_ANAL_VARSUBS];
RList *locs; // list of local variables
ut8 *fingerprint; // TODO: make is fuzzy and smarter
RAnalDiff *diff;
RList *locs; // list of local variables
RList *locals; // list of local labels
RList *bbs;
RList *vars;
RList *refs;
@ -720,6 +726,7 @@ R_API const char *r_anal_op_to_esil_string(RAnal *anal, RAnalOp *op);
R_API RAnalFunction *r_anal_fcn_new();
R_API int r_anal_fcn_is_in_offset (RAnalFunction *fcn, ut64 addr);
R_API RAnalFunction *r_anal_fcn_find(RAnal *anal, ut64 addr, int type);
R_API RAnalFunction *r_anal_fcn_find_name(RAnal *anal, const char *name);
R_API RList *r_anal_fcn_list_new();
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn);
R_API void r_anal_fcn_free(void *fcn);
@ -731,6 +738,9 @@ R_API int r_anal_fcn_del(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size,
ut64 jump, ut64 fail, int type, RAnalDiff *diff);
R_API int r_anal_fcn_local_add(RAnal *anal, RAnalFunction *fcn, ut64 addr, const char *name);
R_API int r_anal_fcn_local_del_name(RAnal *anal, RAnalFunction *fcn, const char *name);
R_API int r_anal_fcn_local_del_addr(RAnal *anal, RAnalFunction *fcn, ut64 addr);
R_API int r_anal_fcn_cc(RAnalFunction *fcn);
R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr);
R_API int r_anal_fcn_overlap_bb(RAnalFunction *fcn, RAnalBlock *bb);

View File

@ -60,6 +60,8 @@ typedef struct r_cons_palette_t {
char *offset;
char *comment;
char *fname;
char *flag;
char *label;
char *flow;
char *input;
char *reset;

View File

@ -232,6 +232,7 @@ R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head);
R_API int r_core_anal_bb_seek(RCore *core, ut64 addr);
R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth);
R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad);
R_API void r_core_anal_fcn_local_list(RAnalFunction *fcn);
R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts);
R_API int r_core_anal_graph_fcn(RCore *core, char *input, int opts);
R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n);