mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 13:49:50 +00:00
local labels inside functions - initial support
This commit is contained in:
parent
ac4cedae53
commit
0711e60667
@ -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;
|
||||
|
@ -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) },
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user