mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-20 22:34:39 +00:00
Proposed fix to printing function disassembly with rewrite of the function handling reflines.
This commit is contained in:
parent
666ab166d1
commit
2e20adb68d
@ -321,8 +321,8 @@ R_API void r_anal_ex_op_to_bb(RAnal *anal, RAnalState *state, RAnalBlock *bb, RA
|
||||
r_anal_ex_clone_op_switch_to_bb (bb, op);
|
||||
}
|
||||
|
||||
R_API ut32 r_anal_ex_map_anal_ex_to_anal_bb_type (ut64 ranal2_op_type) {
|
||||
ut32 bb_type = 0;
|
||||
R_API ut64 r_anal_ex_map_anal_ex_to_anal_bb_type (ut64 ranal2_op_type) {
|
||||
ut64 bb_type = 0;
|
||||
ut64 conditional = R_ANAL_EX_COND_OP & ranal2_op_type ? R_ANAL_OP_TYPE_COND : 0;
|
||||
ut64 code_op_val = ranal2_op_type & (R_ANAL_EX_CODE_OP | 0x1FF);
|
||||
|
||||
|
@ -172,7 +172,7 @@ static int handle_bb_cf_recursive_descent (RAnal *anal, RAnalState *state) {
|
||||
state->current_depth++;
|
||||
addr = bb->addr;
|
||||
IFDBG eprintf ("Handling a control flow change @ 0x%04"PFMT64x".\n", addr);
|
||||
ut32 control_type = r_anal_ex_map_anal_ex_to_anal_op_type (bb->type2);
|
||||
ut64 control_type = r_anal_ex_map_anal_ex_to_anal_op_type (bb->type2);
|
||||
|
||||
// XXX - transition to type2 control flow condtions
|
||||
switch (control_type) {
|
||||
|
@ -87,6 +87,79 @@ R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
|
||||
return list;
|
||||
}
|
||||
|
||||
R_API struct r_anal_refline_t *r_anal_reflines_fcn_get( struct r_anal_t *anal, RAnalFunction *fcn,
|
||||
int nlines, int linesout, int linescall) {
|
||||
RAnalRefline *list2, *list = R_NEW (RAnalRefline);
|
||||
RAnalBlock *bb;
|
||||
RListIter *bb_iter;
|
||||
|
||||
int index = 0;
|
||||
ut64 opc = fcn->addr, addr = 0;
|
||||
ut32 len;
|
||||
|
||||
INIT_LIST_HEAD (&(list->list));
|
||||
|
||||
/* analyze code block */
|
||||
r_list_foreach (fcn->bbs, bb_iter, bb) {
|
||||
if (!bb || bb->size == 0) continue;
|
||||
if (nlines != -1 && --nlines == 0) break;
|
||||
len = bb->size;
|
||||
addr = bb->addr;
|
||||
|
||||
/* store data */
|
||||
ut64 control_type = bb->type;
|
||||
control_type &= R_ANAL_BB_TYPE_SWITCH | R_ANAL_BB_TYPE_JMP | R_ANAL_BB_TYPE_COND | R_ANAL_BB_TYPE_CALL;
|
||||
|
||||
// handle call
|
||||
if ( (control_type & R_ANAL_BB_TYPE_CALL) == R_ANAL_BB_TYPE_CALL && !linescall) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handles conditonal + unconditional jump
|
||||
if ( (control_type & R_ANAL_BB_TYPE_CJMP) == R_ANAL_BB_TYPE_CJMP) {
|
||||
// dont need to continue here is opc+len exceed function scope
|
||||
if (linesout && bb->fail > 0LL && bb->fail != bb->addr + len) {
|
||||
list2 = R_NEW (RAnalRefline);
|
||||
list2->from = bb->addr;
|
||||
list2->to = bb->fail;
|
||||
list2->index = index++;
|
||||
list_add_tail (&(list2->list), &(list->list));
|
||||
}
|
||||
}
|
||||
if ( (control_type & R_ANAL_BB_TYPE_JMP) == R_ANAL_BB_TYPE_JMP) {
|
||||
if (!linesout || bb->jump == 0LL || bb->jump == bb->addr + len)
|
||||
continue;
|
||||
|
||||
list2 = R_NEW (RAnalRefline);
|
||||
list2->from = bb->addr;
|
||||
list2->to = bb->jump;
|
||||
list2->index = index++;
|
||||
list_add_tail (&(list2->list), &(list->list));
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX - Todo test handle swith op
|
||||
if ( control_type & R_ANAL_BB_TYPE_SWITCH) {
|
||||
if (bb->switch_op) {
|
||||
RAnalCaseOp *caseop;
|
||||
RListIter *iter;
|
||||
r_list_foreach (bb->switch_op->cases, iter, caseop) {
|
||||
if (caseop) {
|
||||
if (!linesout)// && (op.jump > opc+len || op.jump < pc))
|
||||
continue;
|
||||
list2 = R_NEW (RAnalRefline);
|
||||
list2->from = bb->switch_op->addr;
|
||||
list2->to = caseop->jump;
|
||||
list2->index = index++;
|
||||
list_add_tail (&(list2->list), &(list->list));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
R_API int r_anal_reflines_middle(RAnal *a, RAnalRefline *list, ut64 addr, int len) {
|
||||
struct list_head *pos;
|
||||
if (list)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
||||
|
||||
//#include <r_anal_ex.h>
|
||||
|
||||
static int is_valid_input_num_value(RCore *core, char *input_value){
|
||||
ut64 value = input_value ? r_num_math (core->num, input_value) : 0;
|
||||
@ -839,7 +839,7 @@ static int cmd_print(void *data, const char *input) {
|
||||
}
|
||||
|
||||
switch (input[1]) {
|
||||
case 'i':
|
||||
case 'i':
|
||||
processed_cmd = R_TRUE;
|
||||
pdi (core, l, len, (*input=='D')? len: core->blocksize);
|
||||
pd_result = 0;
|
||||
@ -973,8 +973,18 @@ static int cmd_print(void *data, const char *input) {
|
||||
if (b->size > f->size) b->size = f->size;
|
||||
}
|
||||
// TODO: sort by addr
|
||||
//r_list_sort (f->bbs, &r_anal_ex_bb_address_comparator);
|
||||
r_list_foreach (f->bbs, iter, b) {
|
||||
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
/*switch (control_type) {
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_SWITCH:
|
||||
}*/
|
||||
if (b->jump != UT64_MAX)
|
||||
r_cons_printf ("-[true]-> 0x%08"PFMT64x"\n", b->jump);
|
||||
if (b->fail != UT64_MAX)
|
||||
@ -1008,6 +1018,9 @@ static int cmd_print(void *data, const char *input) {
|
||||
RAnalFunction *f = r_anal_fcn_find (core->anal, core->offset,
|
||||
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
|
||||
if (f) {
|
||||
//RPrint *p, RCore *core, ut64 addr, int l, int invbreak, int cbytes
|
||||
core->num->value = r_core_print_fcn_disasm (core->print, core, f->addr, 9999, 0, 2);
|
||||
/*
|
||||
ut8 *block = malloc (f->size+1);
|
||||
if (block) {
|
||||
r_core_read_at (core, f->addr, block, f->size);
|
||||
@ -1016,7 +1029,7 @@ static int cmd_print(void *data, const char *input) {
|
||||
f->size, 9999, 0, 2);
|
||||
free (block);
|
||||
pd_result = 0;
|
||||
}
|
||||
}*/
|
||||
} else eprintf ("Cannot find function at 0x%08"PFMT64x"\n", core->offset);
|
||||
}
|
||||
l = 0;
|
||||
|
@ -170,6 +170,10 @@ static void handle_print_ptr (RCore *core, RDisasmState *ds, int len, int idx);
|
||||
|
||||
|
||||
|
||||
static int cmpaddr (void *_a, void *_b) {
|
||||
RAnalBlock *a = _a, *b = _b;
|
||||
return (a->addr > b->addr);
|
||||
}
|
||||
|
||||
static void handle_add_show_color ( RCore *core, RDisasmState *ds) {
|
||||
if (ds->show_color) {
|
||||
@ -348,6 +352,18 @@ void handle_reflines_init (RCore *core, RDisasmState *ds) {
|
||||
ds->addr, ds->buf, ds->len, -1,
|
||||
ds->linesout, 1);
|
||||
} else core->reflines = core->reflines2 = NULL;
|
||||
}
|
||||
|
||||
void handle_reflines_fcn_init (RCore *core, RDisasmState *ds, RAnalFunction *fcn, ut8* buf) {
|
||||
if (ds->show_lines) {
|
||||
// TODO: make anal->reflines implicit
|
||||
free (core->reflines); // TODO: leak
|
||||
free (core->reflines2); // TODO: leak
|
||||
core->reflines = r_anal_reflines_fcn_get (core->anal,
|
||||
fcn, -1, ds->linesout, ds->show_linescall);
|
||||
core->reflines2 = r_anal_reflines_fcn_get (core->anal,
|
||||
fcn, -1, ds->linesout, 1);
|
||||
} else core->reflines = core->reflines2 = NULL;
|
||||
|
||||
}
|
||||
|
||||
@ -1849,3 +1865,178 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len) {
|
||||
r_cons_printf ("]");
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int invbreak, int cbytes) {
|
||||
/* other */
|
||||
//void *old_user = core->anal->user;
|
||||
RAnalFunction *fcn = r_anal_fcn_find (core->anal, addr, R_ANAL_FCN_TYPE_NULL),
|
||||
*f = fcn;
|
||||
ut32 cur_buf_sz = fcn->size+1;
|
||||
ut8 *buf = malloc (cur_buf_sz);
|
||||
ut32 len = fcn->size;
|
||||
int ret, idx = 0, i;
|
||||
int continueoninvbreak = (fcn->size == l) && invbreak;
|
||||
RListIter *bb_iter;
|
||||
RAnalBlock *bb = NULL;
|
||||
RDisasmState *ds;
|
||||
RList *bb_list = r_list_new();
|
||||
//r_cons_printf ("len =%d l=%d ib=%d limit=%d\n", len, l, invbreak, p->limit);
|
||||
// TODO: import values from debugger is possible
|
||||
// TODO: allow to get those register snapshots from traces
|
||||
// TODO: per-function register state trace
|
||||
idx = 0;
|
||||
memset (buf, 0, cur_buf_sz);
|
||||
|
||||
// TODO: All those ds must be print flags
|
||||
ds = handle_init_ds (core);
|
||||
ds->cbytes = cbytes;
|
||||
ds->p = p;
|
||||
ds->l = l;
|
||||
ds->buf = buf;
|
||||
ds->len = fcn->size;
|
||||
ds->addr = fcn->addr;
|
||||
|
||||
r_list_foreach (fcn->bbs, bb_iter, bb) {
|
||||
r_list_add_sorted (bb_list, bb, cmpaddr);
|
||||
}
|
||||
// Premptively read the bb data locs for ref lines
|
||||
r_list_foreach (bb_list, bb_iter, bb) {
|
||||
if (idx >= cur_buf_sz) break;
|
||||
r_core_read_at (core, bb->addr, buf+idx, bb->size);
|
||||
//ret = r_asm_disassemble (core->assembler, &ds->asmop, buf+idx, bb->size);
|
||||
//if (ret > 0) eprintf ("%s\n",ds->asmop.buf_asm);
|
||||
idx += bb->size;
|
||||
}
|
||||
|
||||
handle_reflines_fcn_init (core, ds, fcn, buf);
|
||||
core->inc = 0;
|
||||
|
||||
core->cons->vline = r_config_get_i (core->config, "scr.utf8")?
|
||||
r_vline_u: r_vline_a;
|
||||
|
||||
r_cons_break (NULL, NULL);
|
||||
i = 0;
|
||||
idx = 0;
|
||||
|
||||
r_list_foreach (bb_list, bb_iter, bb) {
|
||||
ut32 bb_size_consumed = 0;
|
||||
// internal loop to consume bb that contain case-like operations
|
||||
ds->at = bb->addr;
|
||||
ds->addr = bb->addr;
|
||||
len = bb->size;
|
||||
|
||||
if (len > cur_buf_sz) {
|
||||
free(buf);
|
||||
cur_buf_sz = len;
|
||||
buf = malloc (cur_buf_sz);
|
||||
ds->buf = buf;
|
||||
}
|
||||
do {
|
||||
// XXX - why is it necessary to set this everytime?
|
||||
r_asm_set_pc (core->assembler, ds->at);
|
||||
if (ds->lines >= ds->l) break;
|
||||
if (r_cons_singleton ()->breaked) break;
|
||||
|
||||
handle_update_ref_lines (core, ds);
|
||||
/* show type links */
|
||||
r_core_cmdf (core, "tf 0x%08"PFMT64x, ds->at);
|
||||
|
||||
handle_show_xrefs (core, ds);
|
||||
handle_show_comments_right (core, ds);
|
||||
ret = perform_disassembly (core, ds, buf+idx, len - bb_size_consumed);
|
||||
handle_atabs_option (core, ds);
|
||||
handle_colorize_opcode (core, ds);
|
||||
// TODO: store previous oplen in core->dec
|
||||
if (core->inc == 0) core->inc = ds->oplen;
|
||||
|
||||
r_anal_op_fini (&ds->analop);
|
||||
|
||||
if (!ds->lastfail)
|
||||
r_anal_op (core->anal, &ds->analop, ds->at+bb_size_consumed, buf+idx, len-bb_size_consumed);
|
||||
|
||||
if (ret<1) {
|
||||
r_strbuf_init (&ds->analop.esil);
|
||||
ds->analop.type = R_ANAL_OP_TYPE_ILL;
|
||||
}
|
||||
|
||||
handle_instruction_mov_lea (core, ds, idx);
|
||||
handle_control_flow_comments (core, ds);
|
||||
handle_adistrick_comments (core, ds);
|
||||
/* XXX: This is really cpu consuming.. need to be fixed */
|
||||
handle_show_functions (core, ds);
|
||||
handle_show_flags_option (core, ds);
|
||||
handle_print_lines_left (core, ds);
|
||||
handle_print_offset (core, ds);
|
||||
handle_print_op_size (core, ds);
|
||||
handle_print_trace (core, ds);
|
||||
handle_print_stackptr (core, ds);
|
||||
ret = handle_print_meta_infos (core, ds, buf,len, idx);
|
||||
if (ds->mi_found) {
|
||||
ds->mi_found = 0;
|
||||
continue;
|
||||
}
|
||||
/* show cursor */
|
||||
handle_print_show_cursor (core, ds);
|
||||
handle_print_show_bytes (core, ds);
|
||||
handle_print_lines_right (core, ds);
|
||||
handle_add_show_color (core, ds);
|
||||
handle_build_op_str (core, ds);
|
||||
handle_print_opstr (core, ds);
|
||||
handle_print_fcn_name (core, ds);
|
||||
handle_print_color_reset( core, ds);
|
||||
handle_print_dwarf (core, ds);
|
||||
ret = handle_print_middle (core, ds, ret );
|
||||
handle_print_asmop_payload (core, ds);
|
||||
if (core->assembler->syntax != R_ASM_SYNTAX_INTEL) {
|
||||
RAsmOp ao; /* disassemble for the vm .. */
|
||||
int os = core->assembler->syntax;
|
||||
r_asm_set_syntax (core->assembler, R_ASM_SYNTAX_INTEL);
|
||||
r_asm_disassemble (core->assembler, &ao, buf+idx, len-bb_size_consumed);
|
||||
r_asm_set_syntax (core->assembler, os);
|
||||
}
|
||||
handle_print_core_vmode (core, ds);
|
||||
handle_print_cc_update (core, ds);
|
||||
handle_print_op_push_info (core, ds);
|
||||
/*if (ds->analop.refptr) {
|
||||
handle_print_refptr (core, ds);
|
||||
} else {
|
||||
handle_print_ptr (core, ds, len, idx);
|
||||
}*/
|
||||
handle_print_comments_right (core, ds);
|
||||
if ( !(ds->show_comments &&
|
||||
ds->show_comment_right &&
|
||||
ds->show_comment_right &&
|
||||
ds->comment))
|
||||
r_cons_newline ();
|
||||
|
||||
if (ds->line) {
|
||||
free (ds->line);
|
||||
free (ds->refline);
|
||||
free (ds->refline2);
|
||||
ds->line = ds->refline = ds->refline2 = NULL;
|
||||
}
|
||||
bb_size_consumed += ds->oplen;
|
||||
ds->index += ds->oplen;
|
||||
idx += ds->oplen;
|
||||
ds->at += ds->oplen;
|
||||
ds->addr += ds->oplen;
|
||||
ds->lines++;
|
||||
|
||||
free (ds->opstr);
|
||||
ds->opstr = NULL;
|
||||
} while (bb_size_consumed < len);
|
||||
i++;
|
||||
}
|
||||
free (buf);
|
||||
r_cons_break_end ();
|
||||
|
||||
|
||||
if (ds->oldbits) {
|
||||
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
||||
ds->oldbits = 0;
|
||||
}
|
||||
r_anal_op_fini (&ds->analop);
|
||||
handle_deinit_ds (core, ds);
|
||||
r_list_free (bb_list);
|
||||
return idx; //-ds->lastfail;
|
||||
}
|
||||
|
@ -474,6 +474,7 @@ typedef enum {
|
||||
R_ANAL_BB_TYPE_RET = 0x0020, /* return bb */
|
||||
R_ANAL_BB_TYPE_JMP = 0x0040, /* jmp bb */
|
||||
R_ANAL_BB_TYPE_COND = 0x0100, /* conditional bb */
|
||||
R_ANAL_BB_TYPE_CJMP = R_ANAL_BB_TYPE_COND | R_ANAL_BB_TYPE_JMP,
|
||||
R_ANAL_BB_TYPE_CALL = 0x0200,
|
||||
R_ANAL_BB_TYPE_CMP = 0x0400,
|
||||
R_ANAL_BB_TYPE_LD = 0x0800,
|
||||
@ -583,7 +584,7 @@ typedef struct r_anal_op_t {
|
||||
char *mnemonic; /* mnemonic */
|
||||
ut64 addr; /* address */
|
||||
ut64 type; /* type of opcode */
|
||||
ut64 type2;
|
||||
ut64 type2;
|
||||
int stackop; /* operation on stack? */
|
||||
int cond; /* condition type */
|
||||
int size; /* size in bytes of opcode */
|
||||
@ -997,7 +998,8 @@ R_API RAnalRefline *r_anal_reflines_get(RAnal *anal,
|
||||
ut64 addr, const ut8 *buf, ut64 len, int nlines, int linesout, int linescall);
|
||||
R_API int r_anal_reflines_middle(RAnal *anal, RAnalRefline *list, ut64 addr, int len);
|
||||
R_API char* r_anal_reflines_str(void *core, ut64 addr, int opts);
|
||||
|
||||
R_API struct r_anal_refline_t *r_anal_reflines_fcn_get( struct r_anal_t *anal, RAnalFunction *fcn,
|
||||
int nlines, int linesout, int linescall);
|
||||
/* TODO move to r_core */
|
||||
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, ut64 addr);
|
||||
R_API void r_anal_var_list(RAnal *anal, RAnalFunction *fcn, ut64 addr, int delta);
|
||||
|
@ -18,7 +18,7 @@ typedef struct r_anal_ex_op_to_str_t {
|
||||
enum {
|
||||
R_ANAL_EX_ILL_OP =-1, /* illegal instruction // trap */
|
||||
R_ANAL_EX_NULL_OP = 0,
|
||||
R_ANAL_EX_NOP = 1, /* does nothing */
|
||||
R_ANAL_EX_NOP = 1, /* does nothing */
|
||||
R_ANAL_EX_STORE_OP = 1 << 20, // Load or Store memory operation
|
||||
R_ANAL_EX_LOAD_OP = 1 << 21, // Load or Store memory operation
|
||||
R_ANAL_EX_REG_OP = 1 << 22, // register operation
|
||||
@ -294,7 +294,7 @@ R_API ut64 r_anal_ex_map_anal_ex_to_anal_op_type(ut64 ranal2_op_type);
|
||||
R_API void r_anal_ex_op_to_bb(RAnal *anal, RAnalState *state, RAnalBlock *bb, RAnalOp *op);
|
||||
R_API int r_anal_ex_is_op_type_eop(ut64 x);
|
||||
|
||||
R_API ut32 r_anal_ex_map_anal_ex_to_anal_bb_type (ut64 ranal2_op_type);
|
||||
R_API ut64 r_anal_ex_map_anal_ex_to_anal_bb_type (ut64 ranal2_op_type);
|
||||
|
||||
/* by default performs recursive descent, but is anal->analysis_algorithm
|
||||
* is present, then that will be the algorithm used for analyzing the code
|
||||
|
@ -278,6 +278,7 @@ R_API RList *r_core_asm_back_disassemble_byte (RCore *core, ut64 addr, int len,
|
||||
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int lines, int invbreak, int nbytes);
|
||||
R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len);
|
||||
R_API int r_core_print_disasm_instructions (RCore *core, int len, int l);
|
||||
R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int invbreak, int cbytes);
|
||||
|
||||
R_API void r_core_bin_bind(RCore *core);
|
||||
R_API void r_core_bin_set_by_fd (RCore *core, ut64 bin_fd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user