mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-13 07:57:35 +00:00
pdf/pdr/anal fix (#5709)
This commit is contained in:
parent
a76977a895
commit
10db9ed827
@ -114,6 +114,7 @@ R_API RAnalFunction *r_anal_fcn_new() {
|
||||
fcn->refs = r_anal_ref_list_new ();
|
||||
fcn->xrefs = r_anal_ref_list_new ();
|
||||
#endif
|
||||
fcn->fcn_locs = NULL;
|
||||
fcn->bbs = r_anal_bb_list_new ();
|
||||
fcn->fingerprint = NULL;
|
||||
fcn->diff = r_anal_diff_new ();
|
||||
@ -141,7 +142,8 @@ R_API void r_anal_fcn_free(void *_fcn) {
|
||||
r_list_free (fcn->refs);
|
||||
r_list_free (fcn->xrefs);
|
||||
#endif
|
||||
r_list_free (fcn->locs);
|
||||
//all functions are freed in anal->fcns
|
||||
fcn->fcn_locs = NULL;
|
||||
if (fcn->bbs) {
|
||||
fcn->bbs->free = (RListFree)r_anal_bb_free;
|
||||
r_list_free (fcn->bbs);
|
||||
@ -1076,6 +1078,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
|
||||
RAnalBlock *bb;
|
||||
ut64 endaddr = fcn->addr;
|
||||
ut64 overlapped = -1;
|
||||
ut64 prev_jump = UT64_MAX;
|
||||
RAnalFunction *fcn1 = NULL;
|
||||
|
||||
// set function size as length of continuous sequence of bbs
|
||||
@ -1632,11 +1635,35 @@ R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn) {
|
||||
* basicblocks this function is composed of.
|
||||
* IMPORTANT: this will become, one day, the only size of a function */
|
||||
R_API ut32 r_anal_fcn_realsize(const RAnalFunction *fcn) {
|
||||
RListIter *iter;
|
||||
RListIter *iter, *fiter;
|
||||
RAnalBlock *bb;
|
||||
RAnalFunction *f;
|
||||
ut32 sz = 0;
|
||||
r_list_foreach (fcn->bbs, iter, bb) {
|
||||
sz += bb->size;
|
||||
}
|
||||
r_list_foreach (fcn->fcn_locs, fiter, f) {
|
||||
r_list_foreach (f->bbs, iter, bb) {
|
||||
sz += bb->size;
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
//continious function size without loc.*
|
||||
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
|
||||
RListIter *iter, *fiter;
|
||||
RAnalBlock *bb;
|
||||
RAnalFunction *f;
|
||||
ut32 sz = 0;
|
||||
r_list_foreach (fcn->bbs, iter, bb) {
|
||||
/* TODO: this if is an ugly hack and should be removed when r2 will be
|
||||
* able to handle BBs that comes before the function emtry point.
|
||||
* Another way to remove this is to throw away BBs before the function
|
||||
* entry point at the analysis time in the r_anal_fcn. */
|
||||
if(bb->addr >= fcn->addr) {
|
||||
sz += bb->size;
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ typedef struct {
|
||||
} HintListState;
|
||||
|
||||
static void add_string_ref (RCore *core, ut64 xref_to);
|
||||
static int cmpfcn (const void *_a, const void *_b);
|
||||
|
||||
static void loganal(ut64 from, ut64 to, int depth) {
|
||||
r_cons_clear_line (1);
|
||||
@ -534,6 +535,16 @@ static int core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth
|
||||
eprintf ("Error: new (xref)\n");
|
||||
goto error;
|
||||
}
|
||||
if (fcn->type == R_ANAL_FCN_TYPE_LOC) {
|
||||
RAnalFunction *f = r_anal_get_fcn_in (core->anal, from, -1);
|
||||
if (f) {
|
||||
if (!f->fcn_locs) {
|
||||
f->fcn_locs = r_anal_fcn_list_new ();
|
||||
}
|
||||
r_list_append (f->fcn_locs, fcn);
|
||||
r_list_sort (f->fcn_locs, &cmpfcn);
|
||||
}
|
||||
}
|
||||
ref->addr = from;
|
||||
ref->at = fcn->addr;
|
||||
ref->type = reftype;
|
||||
|
@ -1137,7 +1137,7 @@ static int pdi(RCore *core, int nb_opcodes, int nb_bytes, int fmt) {
|
||||
core->block+i, core->blocksize-i);
|
||||
r_cons_printf ("%s%s"Color_RESET"\n",
|
||||
r_print_color_op_type (core->print, aop.type),
|
||||
asmop.buf_asm);
|
||||
asmop.buf_asm);
|
||||
} else {
|
||||
r_cons_println (asmop.buf_asm);
|
||||
}
|
||||
@ -1999,6 +1999,14 @@ static void _pointer_table (RCore *core, ut64 origin, ut64 offset, const ut8 *bu
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: this function is a temporary fix. All analysis should be based on realsize. However, now for same architectures realisze is not used
|
||||
static ut32 tmp_get_contsize (RAnalFunction *f)
|
||||
{
|
||||
ut32 size = r_anal_fcn_contsize (f);
|
||||
size = (size > 0) ? size : r_anal_fcn_size (f);
|
||||
return (size < 0) ? 0 : size;
|
||||
}
|
||||
|
||||
static int cmd_print(void *data, const char *input) {
|
||||
int mode, w, p, i, l, len, total[10];
|
||||
ut64 off, from, to, at, ate, piece;
|
||||
@ -2564,6 +2572,11 @@ static int cmd_print(void *data, const char *input) {
|
||||
if (f) {
|
||||
RListIter *iter;
|
||||
RAnalBlock *b;
|
||||
RAnalFunction *tmp_func;
|
||||
RListIter *locs_it = NULL;
|
||||
if (f->fcn_locs) {
|
||||
locs_it = f->fcn_locs->head;
|
||||
}
|
||||
// XXX: hack must be reviewed/fixed in code analysis
|
||||
if (r_list_length (f->bbs) == 1) {
|
||||
ut32 fcn_size = r_anal_fcn_size (f);
|
||||
@ -2574,22 +2587,59 @@ static int cmd_print(void *data, const char *input) {
|
||||
}
|
||||
r_list_sort (f->bbs, (RListComparator)bbcmp);
|
||||
if (input[2] == 'j') {
|
||||
r_cons_printf ("[");
|
||||
r_cons_print ("[");
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
if (tmp_func->addr > f->addr) {
|
||||
break;
|
||||
}
|
||||
r_list_foreach (f->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pDj %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
if (iter->n) {
|
||||
r_cons_print (",");
|
||||
}
|
||||
}
|
||||
}
|
||||
r_list_foreach (f->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pDj %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
if (iter->n) {
|
||||
r_cons_printf (",");
|
||||
r_cons_print (",");
|
||||
}
|
||||
}
|
||||
r_cons_printf ("]");
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
r_list_foreach (tmp_func->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pDj %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
if (iter->n) {
|
||||
r_cons_print (",");
|
||||
}
|
||||
}
|
||||
}
|
||||
r_cons_print ("]");
|
||||
} else {
|
||||
// TODO: sort by addr
|
||||
bool asm_lines = r_config_get_i (core->config, "asm.lines");
|
||||
r_config_set_i (core->config, "asm.lines", 0);
|
||||
//r_list_sort (f->bbs, &r_anal_ex_bb_address_comparator);
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
if (tmp_func->addr < f->addr) {
|
||||
r_list_foreach (tmp_func->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
#if 1
|
||||
if (b->jump != UT64_MAX) {
|
||||
r_cons_printf ("| ----------- true: 0x%08"PFMT64x, b->jump);
|
||||
//r_cons_printf ("-[true]-> 0x%08"PFMT64x"\n", b->jump);
|
||||
}
|
||||
if (b->fail != UT64_MAX) {
|
||||
r_cons_printf (" false: 0x%08"PFMT64x, b->fail);
|
||||
}
|
||||
r_cons_newline ();
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
r_list_foreach (f->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
#if 1
|
||||
#if 1
|
||||
if (b->jump != UT64_MAX) {
|
||||
r_cons_printf ("| ----------- true: 0x%08"PFMT64x, b->jump);
|
||||
//r_cons_printf ("-[true]-> 0x%08"PFMT64x"\n", b->jump);
|
||||
@ -2598,8 +2648,26 @@ static int cmd_print(void *data, const char *input) {
|
||||
r_cons_printf (" false: 0x%08"PFMT64x, b->fail);
|
||||
}
|
||||
r_cons_newline ();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
//this should be more advanced
|
||||
r_list_foreach (tmp_func->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
#if 1
|
||||
if (b->jump != UT64_MAX) {
|
||||
r_cons_printf ("| ----------- true: 0x%08"PFMT64x, b->jump);
|
||||
//r_cons_printf ("-[true]-> 0x%08"PFMT64x"\n", b->jump);
|
||||
}
|
||||
if (b->fail != UT64_MAX) {
|
||||
r_cons_printf (" false: 0x%08"PFMT64x, b->fail);
|
||||
}
|
||||
r_cons_newline ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
r_config_set_i (core->config, "asm.lines", asm_lines);
|
||||
}
|
||||
} else {
|
||||
@ -2658,27 +2726,67 @@ static int cmd_print(void *data, const char *input) {
|
||||
ut32 bsz = core->blocksize;
|
||||
RAnalFunction *f = r_anal_get_fcn_in (core->anal, core->offset,
|
||||
R_ANAL_FCN_TYPE_FCN | R_ANAL_FCN_TYPE_SYM);
|
||||
RListIter *iter;
|
||||
RAnalBlock *bb;
|
||||
RAnalFunction *tmp_func;
|
||||
ut32 cont_size = 0;
|
||||
RListIter *locs_it = NULL;
|
||||
if (f && f->fcn_locs) {
|
||||
locs_it = f->fcn_locs->head;
|
||||
cont_size = tmp_get_contsize (f);
|
||||
}
|
||||
if (f && input[2] == 'j') { // "pdfj"
|
||||
ut8 *buf;
|
||||
ut32 fcn_size = r_anal_fcn_size (f);
|
||||
ut8 *func_buf = NULL, *loc_buf = NULL;
|
||||
ut32 fcn_size = r_anal_fcn_realsize (f);
|
||||
r_cons_printf ("{");
|
||||
r_cons_printf ("\"name\":\"%s\"", f->name);
|
||||
r_cons_printf (",\"size\":%d", fcn_size);
|
||||
r_cons_printf (",\"addr\":%"PFMT64d, f->addr);
|
||||
r_cons_printf (",\"ops\":");
|
||||
// instructions are all outputted as a json list
|
||||
buf = malloc (fcn_size);
|
||||
if (buf) {
|
||||
r_io_read_at (core->io, f->addr, buf, fcn_size);
|
||||
r_core_print_disasm_json (core, f->addr, buf, fcn_size, 0);
|
||||
free (buf);
|
||||
func_buf = calloc (cont_size, 1);
|
||||
if (func_buf) {
|
||||
//TODO: can loc jump to another locs?
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
if (tmp_func->addr > f->addr) {
|
||||
break;
|
||||
}
|
||||
cont_size = tmp_get_contsize (tmp_func);
|
||||
loc_buf = calloc (cont_size, 1);;
|
||||
r_io_read_at (core->io, tmp_func->addr, loc_buf, cont_size);
|
||||
r_core_print_disasm_json (core, tmp_func->addr, loc_buf, cont_size, 0);
|
||||
free (loc_buf);
|
||||
}
|
||||
cont_size = tmp_get_contsize (f);
|
||||
r_io_read_at (core->io, f->addr, func_buf, cont_size);
|
||||
r_core_print_disasm_json (core, f->addr, func_buf, cont_size, 0);
|
||||
free (func_buf);
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
cont_size = tmp_get_contsize (tmp_func);
|
||||
loc_buf = calloc (cont_size, 1);;
|
||||
r_io_read_at (core->io, tmp_func->addr, loc_buf, cont_size);
|
||||
r_core_print_disasm_json (core, tmp_func->addr, loc_buf, cont_size, 0);
|
||||
free (loc_buf);
|
||||
}
|
||||
} else {
|
||||
eprintf ("cannot allocate %d bytes\n", fcn_size);
|
||||
}
|
||||
r_cons_printf ("}\n");
|
||||
pd_result = 0;
|
||||
} else if (f) {
|
||||
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, r_anal_fcn_size (f), f->addr);
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
if (tmp_func->addr > f->addr) {
|
||||
break;
|
||||
}
|
||||
cont_size = tmp_get_contsize (tmp_func);
|
||||
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, cont_size, tmp_func->addr);
|
||||
}
|
||||
cont_size = tmp_get_contsize (f);
|
||||
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, cont_size, f->addr);
|
||||
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
|
||||
cont_size = tmp_get_contsize (tmp_func);
|
||||
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, cont_size, tmp_func->addr);
|
||||
}
|
||||
pd_result = 0;
|
||||
} else {
|
||||
eprintf ("Cannot find function at 0x%08"PFMT64x"\n", core->offset);
|
||||
@ -3540,7 +3648,7 @@ static int cmd_print(void *data, const char *input) {
|
||||
len = core->print->cols*len;
|
||||
default:
|
||||
if (l != 0) {
|
||||
int restore_block_size = 0;
|
||||
int restore_block_size = 0;
|
||||
ut64 from = r_config_get_i (core->config, "diff.from");
|
||||
ut64 to = r_config_get_i (core->config, "diff.to");
|
||||
ut64 obsz = core->blocksize;
|
||||
|
@ -923,6 +923,14 @@ static int var_comparator(const RAnalVar *a, const RAnalVar *b){
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: this function is a temporary fix. All analysis should be based on realsize. However, now for same architectures realisze is not used
|
||||
static ut32 tmp_get_realsize (RAnalFunction *f)
|
||||
{
|
||||
ut32 size = r_anal_fcn_realsize (f);
|
||||
size = (size > 0) ? size : r_anal_fcn_size (f);
|
||||
return (size < 0) ? 0 : size;
|
||||
}
|
||||
|
||||
static void ds_show_functions(RDisasmState *ds) {
|
||||
RAnalFunction *f;
|
||||
RCore *core = ds->core;
|
||||
@ -988,12 +996,12 @@ static void ds_show_functions(RDisasmState *ds) {
|
||||
ds_print_offset (ds);
|
||||
r_cons_printf ("%s%s%s(%s) %s%s%s %d\n",
|
||||
space, COLOR_RESET (ds), COLOR (ds, color_fname),
|
||||
fcntype, fcn_name, cmt, COLOR_RESET (ds), r_anal_fcn_size (f));
|
||||
fcntype, fcn_name, cmt, COLOR_RESET (ds), tmp_get_realsize (f));
|
||||
} else {
|
||||
r_cons_printf ("%s%s%s%s%s(%s) %s%s%s %d\n",
|
||||
COLOR (ds, color_fline), ds->pre,
|
||||
space, COLOR_RESET (ds), COLOR (ds, color_fname),
|
||||
fcntype, fcn_name, cmt, COLOR_RESET (ds), r_anal_fcn_size (f));
|
||||
fcntype, fcn_name, cmt, COLOR_RESET (ds), tmp_get_realsize (f));
|
||||
}
|
||||
}
|
||||
if (sign)
|
||||
|
@ -276,6 +276,7 @@ typedef struct r_anal_type_function_t {
|
||||
ut8 *fingerprint; // TODO: make is fuzzy and smarter
|
||||
RAnalDiff *diff;
|
||||
RList *locs; // list of local variables
|
||||
RList *fcn_locs; //sorted list of a function *.loc refs
|
||||
//RList *locals; // list of local labels -> moved to anal->sdb_fcns
|
||||
RList *bbs;
|
||||
RList *vars;
|
||||
@ -1273,6 +1274,7 @@ R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type);
|
||||
|
||||
R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn);
|
||||
R_API void r_anal_fcn_set_size(RAnalFunction *fcn, ut32 size);
|
||||
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn);
|
||||
R_API ut32 r_anal_fcn_realsize(const RAnalFunction *fcn);
|
||||
R_API int r_anal_fcn_cc(RAnalFunction *fcn);
|
||||
R_API int r_anal_fcn_split_bb(RAnal *anal, RAnalFunction *fcn, RAnalBlock *bb, ut64 addr);
|
||||
|
Loading…
Reference in New Issue
Block a user