2016-01-10 21:30:10 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2016 - nibble, pancake, dso */
|
2012-08-23 10:46:55 +00:00
|
|
|
|
2011-06-04 01:14:04 +00:00
|
|
|
#include "r_core.h"
|
2013-07-18 20:20:23 +00:00
|
|
|
#include "r_cons.h"
|
|
|
|
|
2013-11-06 01:10:53 +00:00
|
|
|
#define HASRETRY 1
|
2014-06-25 00:30:42 +00:00
|
|
|
#define HAVE_LOCALS 1
|
2015-10-29 22:37:51 +00:00
|
|
|
#define DEFAULT_NARGS 4
|
2013-10-27 01:20:36 +00:00
|
|
|
|
2015-12-17 19:18:50 +00:00
|
|
|
#define R_MIDFLAGS_SHOW 1
|
|
|
|
#define R_MIDFLAGS_REALIGN 2
|
|
|
|
|
2015-11-02 11:38:08 +00:00
|
|
|
#define COLOR(ds, field) (ds->show_color ? ds->field : "")
|
|
|
|
#define COLOR_CONST(ds, color) (ds->show_color ? Color_ ## color : "")
|
|
|
|
#define COLOR_RESET(ds) COLOR_CONST(ds, RESET)
|
|
|
|
|
2016-04-08 10:18:28 +00:00
|
|
|
|
2013-09-11 21:41:40 +00:00
|
|
|
static const char* r_vline_a[] = {
|
2013-07-18 20:20:23 +00:00
|
|
|
"|", // LINE_VERT
|
|
|
|
"|-", // LINE_CROSS
|
|
|
|
"/", // RUP_CORNER
|
|
|
|
"\\", // RDWN_CORNER
|
|
|
|
"->", // ARROW_RIGHT
|
|
|
|
"=<", // ARROW_LEFT
|
|
|
|
"-", // LINE_HORIZ
|
|
|
|
",", // LUP_CORNER
|
|
|
|
"`", // LDWN_CORNER
|
2014-03-08 01:36:33 +00:00
|
|
|
"!", // LINE_UP
|
2013-07-18 20:20:23 +00:00
|
|
|
};
|
|
|
|
|
2013-09-11 21:41:40 +00:00
|
|
|
static const char* r_vline_u[] = {
|
2013-07-18 20:20:23 +00:00
|
|
|
"│", // LINE_VERT
|
|
|
|
"├", // LINE_CROSS
|
|
|
|
"╒", // RUP_CORNER
|
|
|
|
"╘", // RDWN_CORNER
|
|
|
|
">", // ARROW_RIGHT
|
|
|
|
"<", // ARROW_LEFT
|
|
|
|
"─", // LINE_HORIZ
|
|
|
|
"┌", // LUP_CORNER
|
|
|
|
"└", // LDWN_CORNER
|
2014-03-08 01:36:33 +00:00
|
|
|
"↑", // LINE_UP
|
2013-07-18 20:20:23 +00:00
|
|
|
};
|
2011-06-04 01:14:04 +00:00
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
// TODO: what about using bit shifting and enum for keys? see libr/util/bitmap.c
|
|
|
|
// the problem of this is that the fields will be more opaque to bindings, but we will earn some bits
|
2014-01-16 17:04:42 +00:00
|
|
|
typedef struct r_disam_options_t {
|
2016-03-03 23:33:24 +00:00
|
|
|
RCore *core;
|
2015-02-07 23:30:25 +00:00
|
|
|
char str[1024], strsub[1024];
|
2014-01-16 17:04:42 +00:00
|
|
|
int use_esil;
|
|
|
|
int show_color;
|
|
|
|
int colorop;
|
|
|
|
int acase;
|
2016-03-03 23:33:24 +00:00
|
|
|
int show_flgoff;
|
2014-01-16 17:04:42 +00:00
|
|
|
int atabs;
|
2015-07-15 13:14:51 +00:00
|
|
|
int atabsonce;
|
2015-07-15 15:30:34 +00:00
|
|
|
int atabsoff;
|
2014-01-16 17:04:42 +00:00
|
|
|
int decode;
|
|
|
|
int pseudo;
|
|
|
|
int filter;
|
2014-12-10 22:54:35 +00:00
|
|
|
int interactive;
|
2014-01-16 17:04:42 +00:00
|
|
|
int varsub;
|
|
|
|
int show_lines;
|
2015-08-30 22:20:07 +00:00
|
|
|
int show_lines_ret;
|
|
|
|
int show_lines_call;
|
2014-01-16 17:04:42 +00:00
|
|
|
int linesright;
|
2014-11-02 01:19:31 +00:00
|
|
|
int tracespace;
|
2014-11-02 02:06:52 +00:00
|
|
|
int cyclespace;
|
2015-06-01 23:04:10 +00:00
|
|
|
int cmtfold;
|
2014-08-05 03:37:48 +00:00
|
|
|
int show_indent;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_dwarf;
|
|
|
|
int show_size;
|
|
|
|
int show_trace;
|
2015-10-03 11:52:52 +00:00
|
|
|
int show_family;
|
2015-03-08 01:27:39 +00:00
|
|
|
int asm_describe;
|
2014-01-16 17:04:42 +00:00
|
|
|
int linesout;
|
|
|
|
int adistrick;
|
2014-09-24 01:01:18 +00:00
|
|
|
int asm_demangle;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_offset;
|
2015-11-23 00:40:35 +00:00
|
|
|
int show_bbline;
|
2015-09-11 21:46:09 +00:00
|
|
|
int show_emu;
|
2016-01-14 23:17:15 +00:00
|
|
|
int show_emu_str;
|
2015-10-29 22:37:51 +00:00
|
|
|
int show_emu_write;
|
2014-11-22 04:39:52 +00:00
|
|
|
int show_section;
|
2016-04-08 00:56:42 +00:00
|
|
|
int show_section_col;
|
2016-03-29 00:03:17 +00:00
|
|
|
int show_symbols;
|
2016-04-08 00:56:42 +00:00
|
|
|
int show_symbols_col;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_offseg;
|
|
|
|
int show_flags;
|
|
|
|
int show_bytes;
|
2015-01-12 09:45:41 +00:00
|
|
|
int show_reloff;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_comments;
|
2016-01-27 01:25:25 +00:00
|
|
|
int show_jmphints;
|
2015-08-26 01:27:34 +00:00
|
|
|
int show_slow;
|
2014-11-13 02:36:48 +00:00
|
|
|
int cmtcol;
|
2014-07-21 02:18:27 +00:00
|
|
|
int show_fcnlines;
|
2014-11-23 23:16:36 +00:00
|
|
|
int show_calls;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_cmtflgrefs;
|
2014-02-10 22:01:19 +00:00
|
|
|
int show_cycles;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_stackptr;
|
2016-03-03 23:33:24 +00:00
|
|
|
int show_spacy;
|
2014-01-16 17:04:42 +00:00
|
|
|
int show_xrefs;
|
|
|
|
int show_functions;
|
2015-01-28 16:05:18 +00:00
|
|
|
int show_fcncalls;
|
2015-07-14 22:22:20 +00:00
|
|
|
int show_marks;
|
2014-01-16 17:04:42 +00:00
|
|
|
int cursor;
|
|
|
|
int show_comment_right_default;
|
|
|
|
int flagspace_ports;
|
2014-10-15 23:51:48 +00:00
|
|
|
int show_flag_in_bytes;
|
2014-01-16 17:04:42 +00:00
|
|
|
int lbytes;
|
|
|
|
int show_comment_right;
|
|
|
|
char *pre;
|
|
|
|
char *ocomment;
|
|
|
|
int linesopts;
|
|
|
|
int lastfail;
|
|
|
|
int oldbits;
|
|
|
|
int ocols;
|
|
|
|
int lcols;
|
|
|
|
int nb, nbytes;
|
|
|
|
int show_utf8;
|
|
|
|
int lines;
|
|
|
|
int oplen;
|
2015-01-11 03:29:15 +00:00
|
|
|
int varxs;
|
|
|
|
int vars;
|
2015-05-05 22:56:31 +00:00
|
|
|
int midflags;
|
2014-01-16 17:04:42 +00:00
|
|
|
const char *pal_comment;
|
|
|
|
const char *color_comment;
|
|
|
|
const char *color_fname;
|
|
|
|
const char *color_floc;
|
|
|
|
const char *color_fline;
|
|
|
|
const char *color_flow;
|
|
|
|
const char *color_flag;
|
|
|
|
const char *color_label;
|
|
|
|
const char *color_other;
|
|
|
|
const char *color_nop;
|
|
|
|
const char *color_bin;
|
|
|
|
const char *color_math;
|
|
|
|
const char *color_jmp;
|
|
|
|
const char *color_cjmp;
|
|
|
|
const char *color_call;
|
|
|
|
const char *color_cmp;
|
|
|
|
const char *color_swi;
|
|
|
|
const char *color_trap;
|
|
|
|
const char *color_ret;
|
|
|
|
const char *color_push;
|
|
|
|
const char *color_pop;
|
|
|
|
const char *color_reg;
|
|
|
|
const char *color_num;
|
2014-05-16 02:07:03 +00:00
|
|
|
const char *color_mov;
|
2014-01-16 17:04:42 +00:00
|
|
|
const char *color_invalid;
|
2014-12-06 11:25:02 +00:00
|
|
|
const char *color_gui_cflow;
|
|
|
|
const char *color_gui_dataoffset;
|
|
|
|
const char *color_gui_background;
|
|
|
|
const char *color_gui_alt_background;
|
|
|
|
const char *color_gui_border;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2015-01-12 09:45:41 +00:00
|
|
|
RFlagItem *lastflag;
|
2014-01-16 17:04:42 +00:00
|
|
|
RAnalHint *hint;
|
|
|
|
RPrint *p;
|
|
|
|
|
|
|
|
int l;
|
|
|
|
int middle;
|
2014-08-05 03:37:48 +00:00
|
|
|
int indent_level;
|
2015-08-12 08:40:24 +00:00
|
|
|
int indent_space;
|
2014-01-16 17:04:42 +00:00
|
|
|
char *line;
|
|
|
|
char *refline, *refline2;
|
|
|
|
char *comment;
|
|
|
|
char *opstr;
|
|
|
|
char *osl, *sl;
|
|
|
|
int stackptr, ostackptr;
|
|
|
|
int index;
|
|
|
|
ut64 at, addr, dest;
|
|
|
|
int tries, cbytes, idx;
|
|
|
|
ut8 mi_found, retry, toro;
|
|
|
|
RAsmOp asmop;
|
|
|
|
RAnalOp analop;
|
2016-02-23 17:30:32 +00:00
|
|
|
RAnalFunction *fcn;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
|
|
|
const ut8 *buf;
|
|
|
|
int len;
|
|
|
|
|
2014-09-23 08:15:19 +00:00
|
|
|
int maxrefs;
|
2016-01-10 21:30:10 +00:00
|
|
|
|
|
|
|
char *prev_ins;
|
|
|
|
bool prev_ins_eq;
|
2016-01-11 21:28:22 +00:00
|
|
|
int prev_ins_count;
|
2016-01-10 21:30:10 +00:00
|
|
|
bool show_nodup;
|
2016-03-03 23:33:24 +00:00
|
|
|
|
|
|
|
// caches
|
|
|
|
char *_tabsbuf;
|
|
|
|
int _tabsoff;
|
2014-01-16 17:04:42 +00:00
|
|
|
} RDisasmState;
|
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
// TODO: put RCore inside RDisasmState and rename all functions to be ds_XXX
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_setup_print_pre(RCore *core, RDisasmState *ds, bool tail);
|
|
|
|
static void handle_setup_pre(RCore *core, RDisasmState *ds, bool tail);
|
|
|
|
static void handle_print_pre(RCore *core, RDisasmState *ds);
|
|
|
|
static void beginline(RCore *core, RDisasmState *ds, RAnalFunction *f, bool nopre);
|
2016-01-27 01:35:45 +00:00
|
|
|
static void handle_print_esil_anal(RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_reflines_init(RAnal *anal, RDisasmState *ds);
|
|
|
|
static void handle_comment_align(RCore *core, RDisasmState *ds);
|
|
|
|
static RDisasmState * handle_init_ds(RCore * core);
|
|
|
|
static void handle_set_pre(RDisasmState *ds, const char * str);
|
|
|
|
static void handle_build_op_str(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_pre_xrefs(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_show_xrefs(RCore *core, RDisasmState *ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
static void handle_atabs_option(RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_show_functions(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_show_comments_right(RCore *core, RDisasmState *ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
static void handle_show_flags_option(RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_update_ref_lines(RCore *core, RDisasmState *ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
static int perform_disassembly(RCore *core, RDisasmState *ds, ut8 *buf, int len);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_control_flow_comments(RCore * core, RDisasmState *ds);
|
|
|
|
static void handle_print_lines_right(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_lines_left(RCore *core, RDisasmState *ds);
|
2014-02-10 22:01:19 +00:00
|
|
|
static void handle_print_cycles(RCore *core, RDisasmState *ds);
|
2015-10-03 11:52:52 +00:00
|
|
|
static void handle_print_family(RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_stackptr(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_offset(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_op_size(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_trace(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_adistrick_comments(RCore *core, RDisasmState *ds);
|
|
|
|
static int handle_print_meta_infos(RCore * core, RDisasmState *ds, ut8* buf, int len, int idx );
|
|
|
|
static void handle_print_opstr(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_color_reset(RCore *core, RDisasmState *ds);
|
|
|
|
static int handle_print_middle(RCore *core, RDisasmState *ds, int ret);
|
|
|
|
static bool handle_print_labels(RCore *core, RDisasmState *ds, RAnalFunction *f);
|
|
|
|
static void handle_print_import_name(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_fcn_name(RCore * core, RDisasmState *ds);
|
2014-05-07 00:51:04 +00:00
|
|
|
static void handle_print_as_string(RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_core_vmode(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_cc_update(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_dwarf(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_asmop_payload(RCore *core, RDisasmState *ds);
|
|
|
|
static void handle_print_op_push_info(RCore *core, RDisasmState *ds);
|
2014-11-10 12:26:03 +00:00
|
|
|
//static int handle_read_refptr (RCore *core, RDisasmState *ds, ut64 *word8, ut32 *word4);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_comments_right(RCore *core, RDisasmState *ds);
|
2014-11-10 12:26:03 +00:00
|
|
|
//static void handle_print_refptr_meta_infos (RCore *core, RDisasmState *ds, ut64 word8 );
|
|
|
|
//static void handle_print_refptr (RCore *core, RDisasmState *ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_ptr(RCore *core, RDisasmState *ds, int len, int idx);
|
2014-01-20 00:42:16 +00:00
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static int cmpaddr(const void *_a, const void *_b) {
|
2015-06-15 22:16:29 +00:00
|
|
|
const RAnalBlock *a = _a, *b = _b;
|
2014-01-23 04:55:48 +00:00
|
|
|
return (a->addr > b->addr);
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
|
2016-03-15 10:47:13 +00:00
|
|
|
static void get_bits_comment(RCore *core, RAnalFunction *f, char *cmt, int cmt_size) {
|
|
|
|
if (core && f && cmt && cmt_size>0 && f->bits) {
|
|
|
|
const char *asm_arch = r_config_get (core->config, "asm.arch");
|
|
|
|
if (strstr (asm_arch, "arm")) {
|
|
|
|
switch (f->bits) {
|
|
|
|
case 16: strcpy (cmt, " (thumb)"); break;
|
|
|
|
case 32: strcpy (cmt, " (arm)"); break;
|
|
|
|
case 64: strcpy (cmt, " (aarch64)"); break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
snprintf (cmt, cmt_size, " (%d bits)", f->bits);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (cmt) {
|
|
|
|
cmt[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static const char *getSectionName(RCore *core, ut64 addr) {
|
2015-07-04 23:44:45 +00:00
|
|
|
static char section[128] = "";
|
2014-11-23 23:16:36 +00:00
|
|
|
static ut64 oaddr = UT64_MAX;
|
|
|
|
RIOSection *s;
|
|
|
|
if (oaddr == addr)
|
|
|
|
return section;
|
|
|
|
s = r_io_section_vget (core->io, addr);
|
|
|
|
if (s) {
|
|
|
|
snprintf (section, sizeof (section)-1, "%10s ", s->name);
|
2015-06-01 13:22:03 +00:00
|
|
|
} else {
|
|
|
|
RListIter *iter;
|
|
|
|
RDebugMap *map;
|
|
|
|
*section = 0;
|
|
|
|
r_list_foreach (core->dbg->maps, iter, map) {
|
|
|
|
if (addr >= map->addr && addr < map->addr_end) {
|
2015-06-01 13:34:26 +00:00
|
|
|
const char *mn = r_str_lchr (map->name, '/');
|
|
|
|
if (mn) {
|
|
|
|
strncpy (section, mn+1, sizeof (section)-1);
|
|
|
|
} else {
|
|
|
|
strncpy (section, map->name, sizeof (section)-1);
|
|
|
|
}
|
2015-06-01 13:22:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-23 23:16:36 +00:00
|
|
|
oaddr = addr;
|
|
|
|
return section;
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void ds_print_spacy(RDisasmState *ds, int pre) {
|
2016-03-03 23:33:24 +00:00
|
|
|
RCore *core = ds->core;
|
|
|
|
RAnalFunction *f = NULL;
|
2016-03-09 08:53:53 +00:00
|
|
|
if (pre) r_cons_newline ();
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->show_functions) {
|
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (!f) {
|
|
|
|
r_cons_printf (" ");
|
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
}
|
|
|
|
}
|
2016-04-04 23:33:57 +00:00
|
|
|
if (f) beginline (core, ds, f, true);
|
2016-03-03 23:33:24 +00:00
|
|
|
handle_print_offset (core, ds);
|
2016-03-09 08:53:53 +00:00
|
|
|
if (!pre) r_cons_newline ();
|
2016-03-03 23:33:24 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static RDisasmState * handle_init_ds(RCore * core) {
|
2015-01-12 09:45:41 +00:00
|
|
|
RDisasmState *ds = R_NEW0 (RDisasmState);
|
2016-03-03 23:33:24 +00:00
|
|
|
ds->core = core;
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->pal_comment = core->cons->pal.comment;
|
2014-01-16 17:04:42 +00:00
|
|
|
#define P(x) (core->cons && core->cons->pal.x)? core->cons->pal.x
|
2014-04-01 21:22:29 +00:00
|
|
|
ds->color_comment = P(comment): Color_CYAN;
|
|
|
|
ds->color_fname = P(fname): Color_RED;
|
|
|
|
ds->color_floc = P(floc): Color_MAGENTA;
|
|
|
|
ds->color_fline = P(fline): Color_CYAN;
|
|
|
|
ds->color_flow = P(flow): Color_CYAN;
|
|
|
|
ds->color_flag = P(flag): Color_CYAN;
|
|
|
|
ds->color_label = P(label): Color_CYAN;
|
|
|
|
ds->color_other = P(other): Color_WHITE;
|
|
|
|
ds->color_nop = P(nop): Color_BLUE;
|
|
|
|
ds->color_bin = P(bin): Color_YELLOW;
|
|
|
|
ds->color_math = P(math): Color_YELLOW;
|
|
|
|
ds->color_jmp = P(jmp): Color_GREEN;
|
|
|
|
ds->color_cjmp = P(cjmp): Color_GREEN;
|
|
|
|
ds->color_call = P(call): Color_BGREEN;
|
|
|
|
ds->color_cmp = P(cmp): Color_MAGENTA;
|
|
|
|
ds->color_swi = P(swi): Color_MAGENTA;
|
|
|
|
ds->color_trap = P(trap): Color_BRED;
|
|
|
|
ds->color_ret = P(ret): Color_RED;
|
|
|
|
ds->color_push = P(push): Color_YELLOW;
|
|
|
|
ds->color_pop = P(pop): Color_BYELLOW;
|
|
|
|
ds->color_reg = P(reg): Color_YELLOW;
|
2015-06-14 00:42:39 +00:00
|
|
|
ds->color_num = P(num): Color_CYAN;
|
2014-10-27 10:55:52 +00:00
|
|
|
ds->color_mov = P(mov): Color_WHITE;
|
2014-04-01 21:22:29 +00:00
|
|
|
ds->color_invalid = P(invalid): Color_BRED;
|
2014-12-06 11:25:02 +00:00
|
|
|
ds->color_gui_cflow = P(gui_cflow): Color_YELLOW;
|
|
|
|
ds->color_gui_dataoffset = P(gui_dataoffset): Color_YELLOW;
|
|
|
|
ds->color_gui_background = P(gui_background): Color_BLACK;
|
|
|
|
ds->color_gui_alt_background = P(gui_alt_background): Color_GRAY;
|
|
|
|
ds->color_gui_border = P(gui_border): Color_BGGRAY;
|
2014-10-27 10:55:52 +00:00
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->use_esil = r_config_get_i (core->config, "asm.esil");
|
2016-03-03 23:33:24 +00:00
|
|
|
ds->show_flgoff = r_config_get_i (core->config, "asm.flgoff");
|
2016-01-10 21:30:10 +00:00
|
|
|
ds->show_nodup = r_config_get_i (core->config, "asm.nodup");
|
2016-03-03 23:33:24 +00:00
|
|
|
ds->show_spacy = r_config_get_i (core->config, "asm.spacy");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_color = r_config_get_i (core->config, "scr.color");
|
|
|
|
ds->colorop = r_config_get_i (core->config, "scr.colorops");
|
|
|
|
ds->show_utf8 = r_config_get_i (core->config, "scr.utf8");
|
|
|
|
ds->acase = r_config_get_i (core->config, "asm.ucase");
|
|
|
|
ds->atabs = r_config_get_i (core->config, "asm.tabs");
|
2015-07-15 13:14:51 +00:00
|
|
|
ds->atabsonce = r_config_get_i (core->config, "asm.tabsonce");
|
2015-07-15 15:30:34 +00:00
|
|
|
ds->atabsoff = r_config_get_i (core->config, "asm.tabsoff");
|
2015-05-05 22:56:31 +00:00
|
|
|
ds->midflags = r_config_get_i (core->config, "asm.midflags");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->decode = r_config_get_i (core->config, "asm.decode");
|
|
|
|
ds->pseudo = r_config_get_i (core->config, "asm.pseudo");
|
|
|
|
ds->filter = r_config_get_i (core->config, "asm.filter");
|
2014-12-10 22:54:35 +00:00
|
|
|
ds->interactive = r_config_get_i (core->config, "scr.interactive");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->varsub = r_config_get_i (core->config, "asm.varsub");
|
2015-11-19 22:12:08 +00:00
|
|
|
core->parser->relsub = r_config_get_i (core->config, "asm.relsub");
|
2015-01-11 03:29:15 +00:00
|
|
|
ds->vars = r_config_get_i (core->config, "asm.vars");
|
|
|
|
ds->varxs = r_config_get_i (core->config, "asm.varxs");
|
2014-09-23 08:15:19 +00:00
|
|
|
ds->maxrefs = r_config_get_i (core->config, "asm.maxrefs");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_lines = r_config_get_i (core->config, "asm.lines");
|
|
|
|
ds->linesright = r_config_get_i (core->config, "asm.linesright");
|
2014-08-05 03:37:48 +00:00
|
|
|
ds->show_indent = r_config_get_i (core->config, "asm.indent");
|
2015-08-12 08:40:24 +00:00
|
|
|
ds->indent_space = r_config_get_i (core->config, "asm.indentspace");
|
2014-11-02 01:19:31 +00:00
|
|
|
ds->tracespace = r_config_get_i (core->config, "asm.tracespace");
|
2014-11-02 02:06:52 +00:00
|
|
|
ds->cyclespace = r_config_get_i (core->config, "asm.cyclespace");
|
2014-04-21 15:19:15 +00:00
|
|
|
ds->show_dwarf = r_config_get_i (core->config, "asm.dwarf");
|
2015-08-30 22:20:07 +00:00
|
|
|
ds->show_lines_call = r_config_get_i (core->config, "asm.lines.call");
|
|
|
|
ds->show_lines_ret = r_config_get_i (core->config, "asm.lines.ret");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_size = r_config_get_i (core->config, "asm.size");
|
|
|
|
ds->show_trace = r_config_get_i (core->config, "asm.trace");
|
|
|
|
ds->linesout = r_config_get_i (core->config, "asm.linesout");
|
|
|
|
ds->adistrick = r_config_get_i (core->config, "asm.middle"); // TODO: find better name
|
2014-09-24 01:01:18 +00:00
|
|
|
ds->asm_demangle = r_config_get_i (core->config, "asm.demangle");
|
2015-03-08 01:27:39 +00:00
|
|
|
ds->asm_describe = r_config_get_i (core->config, "asm.describe");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_offset = r_config_get_i (core->config, "asm.offset");
|
2015-11-23 00:40:35 +00:00
|
|
|
ds->show_bbline = r_config_get_i (core->config, "asm.bbline");
|
2014-11-22 04:39:52 +00:00
|
|
|
ds->show_section = r_config_get_i (core->config, "asm.section");
|
2016-04-08 00:56:42 +00:00
|
|
|
ds->show_section_col = r_config_get_i (core->config, "asm.section.col");
|
2016-03-29 00:03:17 +00:00
|
|
|
ds->show_symbols = r_config_get_i (core->config, "asm.symbol");
|
2016-04-08 00:56:42 +00:00
|
|
|
ds->show_symbols_col = r_config_get_i (core->config, "asm.symbol.col");
|
2015-09-11 21:46:09 +00:00
|
|
|
ds->show_emu = r_config_get_i (core->config, "asm.emu");
|
2016-01-14 23:17:15 +00:00
|
|
|
ds->show_emu_str = r_config_get_i (core->config, "asm.emustr");
|
2015-10-29 22:37:51 +00:00
|
|
|
ds->show_emu_write = r_config_get_i (core->config, "asm.emuwrite");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_offseg = r_config_get_i (core->config, "asm.segoff");
|
|
|
|
ds->show_flags = r_config_get_i (core->config, "asm.flags");
|
|
|
|
ds->show_bytes = r_config_get_i (core->config, "asm.bytes");
|
2015-01-12 09:45:41 +00:00
|
|
|
ds->show_reloff = r_config_get_i (core->config, "asm.reloff");
|
2014-07-21 02:18:27 +00:00
|
|
|
ds->show_fcnlines = r_config_get_i (core->config, "asm.fcnlines");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_comments = r_config_get_i (core->config, "asm.comments");
|
2016-01-27 01:25:25 +00:00
|
|
|
ds->show_jmphints = r_config_get_i (core->config, "asm.jmphints");
|
2015-08-26 01:27:34 +00:00
|
|
|
ds->show_slow = r_config_get_i (core->config, "asm.slow");
|
2014-11-23 23:16:36 +00:00
|
|
|
ds->show_calls = r_config_get_i (core->config, "asm.calls");
|
2015-10-03 11:52:52 +00:00
|
|
|
ds->show_family = r_config_get_i (core->config, "asm.family");
|
2014-11-13 02:36:48 +00:00
|
|
|
ds->cmtcol = r_config_get_i (core->config, "asm.cmtcol");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_cmtflgrefs = r_config_get_i (core->config, "asm.cmtflgrefs");
|
2014-02-10 22:01:19 +00:00
|
|
|
ds->show_cycles = r_config_get_i (core->config, "asm.cycles");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_stackptr = r_config_get_i (core->config, "asm.stackptr");
|
|
|
|
ds->show_xrefs = r_config_get_i (core->config, "asm.xrefs");
|
2015-06-01 23:04:10 +00:00
|
|
|
ds->cmtfold = r_config_get_i (core->config, "asm.cmtfold");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->show_functions = r_config_get_i (core->config, "asm.functions");
|
2015-01-28 16:05:18 +00:00
|
|
|
ds->show_fcncalls = r_config_get_i (core->config, "asm.fcncalls");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->nbytes = r_config_get_i (core->config, "asm.nbytes");
|
2014-02-25 00:35:23 +00:00
|
|
|
core->print->bytespace = r_config_get_i (core->config, "asm.bytespace");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->cursor = 0;
|
|
|
|
ds->nb = 0;
|
|
|
|
ds->flagspace_ports = r_flag_space_get (core->flags, "ports");
|
|
|
|
ds->lbytes = r_config_get_i (core->config, "asm.lbytes");
|
2014-12-10 22:54:35 +00:00
|
|
|
ds->show_comment_right_default = r_config_get_i (core->config, "asm.cmtright");
|
2014-10-15 23:51:48 +00:00
|
|
|
ds->show_comment_right = r_config_get_i (core->config, "asm.cmtright"); // XX conflict with show_comment_right_default
|
2014-12-10 22:54:35 +00:00
|
|
|
ds->show_flag_in_bytes = r_config_get_i (core->config, "asm.flagsinbytes");
|
2015-07-14 22:22:20 +00:00
|
|
|
ds->show_marks = r_config_get_i (core->config, "asm.marks");
|
2014-04-23 02:19:21 +00:00
|
|
|
ds->pre = strdup (" ");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->ocomment = NULL;
|
|
|
|
ds->linesopts = 0;
|
|
|
|
ds->lastfail = 0;
|
|
|
|
ds->oldbits = 0;
|
|
|
|
ds->ocols = 0;
|
|
|
|
ds->lcols = 0;
|
2014-10-16 00:16:52 +00:00
|
|
|
if (ds->show_flag_in_bytes) {
|
|
|
|
ds->show_flags = 0;
|
|
|
|
}
|
2014-04-01 21:22:29 +00:00
|
|
|
|
2015-09-08 21:21:35 +00:00
|
|
|
if (r_config_get_i (core->config, "asm.lineswide")) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->linesopts |= R_ANAL_REFLINE_TYPE_WIDE;
|
2015-09-08 21:21:35 +00:00
|
|
|
}
|
|
|
|
if (core->cons->vline) {
|
2015-09-08 22:42:30 +00:00
|
|
|
if (ds->show_utf8)
|
2015-09-08 21:21:35 +00:00
|
|
|
ds->linesopts |= R_ANAL_REFLINE_TYPE_UTF8;
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
|
|
|
|
if (ds->show_lines) ds->ocols += 10; // XXX
|
|
|
|
if (ds->show_offset) ds->ocols += 14;
|
|
|
|
ds->lcols = ds->ocols+2;
|
|
|
|
if (ds->show_bytes) ds->ocols += 20;
|
|
|
|
if (ds->show_trace) ds->ocols += 8;
|
|
|
|
if (ds->show_stackptr) ds->ocols += 4;
|
|
|
|
/* disasm */ ds->ocols += 20;
|
2015-04-08 20:28:21 +00:00
|
|
|
ds->nb = ds->nbytes? (1+ds->nbytes*2): 0;
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->tries = 3;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
if (core->print->cur<0)
|
|
|
|
core->print->cur = 0;
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->cursor = core->print->cur;
|
|
|
|
} else ds->cursor = -1;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2015-09-08 21:21:35 +00:00
|
|
|
if (r_config_get_i (core->config, "asm.lineswide")) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->linesopts |= R_ANAL_REFLINE_TYPE_WIDE;
|
2015-09-08 21:21:35 +00:00
|
|
|
}
|
|
|
|
if (core->cons->vline) {
|
|
|
|
if (core->utf8)
|
|
|
|
ds->linesopts |= R_ANAL_REFLINE_TYPE_UTF8;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
return ds;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2015-09-08 21:21:35 +00:00
|
|
|
static ut64 lastaddr = UT64_MAX;
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_reflines_fini(RAnal *anal, RDisasmState *ds) {
|
2016-04-03 21:52:36 +00:00
|
|
|
r_list_free (anal->reflines);
|
|
|
|
r_list_free (anal->reflines2);
|
|
|
|
anal->reflines = NULL;
|
|
|
|
anal->reflines2 = NULL;
|
2016-04-03 22:17:57 +00:00
|
|
|
R_FREE (ds->refline);
|
|
|
|
R_FREE (ds->refline2);
|
2016-04-03 21:52:36 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_reflines_init(RAnal *anal, RDisasmState *ds) {
|
2015-09-08 21:21:35 +00:00
|
|
|
lastaddr = UT64_MAX;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_lines) {
|
2016-04-03 21:52:36 +00:00
|
|
|
handle_reflines_fini (anal, ds);
|
2015-09-08 21:21:35 +00:00
|
|
|
anal->reflines = r_anal_reflines_get (anal,
|
2014-02-14 19:40:22 +00:00
|
|
|
ds->addr, ds->buf, ds->len, ds->l,
|
2015-08-30 22:20:07 +00:00
|
|
|
ds->linesout, ds->show_lines_call);
|
2015-09-08 21:21:35 +00:00
|
|
|
anal->reflines2 = r_anal_reflines_get (anal,
|
2014-02-14 19:40:22 +00:00
|
|
|
ds->addr, ds->buf, ds->len, ds->l,
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->linesout, 1);
|
2016-04-03 22:52:45 +00:00
|
|
|
} else {
|
|
|
|
r_list_free (anal->reflines);
|
|
|
|
r_list_free (anal->reflines2);
|
|
|
|
anal->reflines = anal->reflines2 = NULL;
|
|
|
|
}
|
2015-09-08 21:21:35 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_reflines_fcn_init(RCore *core, RDisasmState *ds, RAnalFunction *fcn, const ut8* buf) {
|
2015-09-08 21:21:35 +00:00
|
|
|
RAnal *anal = core->anal;
|
2014-01-23 04:55:48 +00:00
|
|
|
if (ds->show_lines) {
|
2014-12-10 22:54:35 +00:00
|
|
|
// TODO: make anal->reflines implicit
|
2015-09-08 21:21:35 +00:00
|
|
|
free (anal->reflines); // TODO: leak
|
|
|
|
anal->reflines = r_anal_reflines_fcn_get (anal,
|
|
|
|
fcn, -1, ds->linesout, ds->show_lines_call);
|
|
|
|
free (anal->reflines2); // TODO: leak
|
|
|
|
anal->reflines2 = r_anal_reflines_fcn_get (anal,
|
|
|
|
fcn, -1, ds->linesout, 1);
|
2014-12-10 22:54:35 +00:00
|
|
|
} else {
|
2016-04-03 22:52:45 +00:00
|
|
|
r_list_free (anal->reflines);
|
|
|
|
r_list_free (anal->reflines2);
|
2015-09-08 21:21:35 +00:00
|
|
|
anal->reflines = anal->reflines2 = NULL;
|
2014-12-10 22:54:35 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
// TODO. rename to ds_free
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_deinit_ds(RCore *core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!ds) return;
|
|
|
|
if (core && ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
r_anal_op_fini (&ds->analop);
|
2015-09-28 09:21:23 +00:00
|
|
|
r_anal_hint_free (ds->hint);
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->comment);
|
|
|
|
free (ds->pre);
|
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
free (ds->opstr);
|
|
|
|
free (ds->osl);
|
|
|
|
free (ds->sl);
|
2016-03-03 23:33:24 +00:00
|
|
|
free (ds->_tabsbuf);
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_set_pre(RDisasmState *ds, const char * str) {
|
2014-07-21 02:18:27 +00:00
|
|
|
if (!ds->show_fcnlines) {
|
2016-05-04 15:13:44 +00:00
|
|
|
if (ds->pre && !*ds->pre) {
|
2014-07-21 02:18:27 +00:00
|
|
|
return;
|
2016-05-04 15:13:44 +00:00
|
|
|
}
|
|
|
|
str = "";
|
2014-07-21 02:18:27 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->pre);
|
|
|
|
ds->pre = strdup (str);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2014-09-03 08:25:29 +00:00
|
|
|
static char *colorize_asm_string(RCore *core, RDisasmState *ds) {
|
2014-08-04 21:09:28 +00:00
|
|
|
char *spacer = NULL;
|
|
|
|
char *source = ds->opstr? ds->opstr: ds->asmop.buf_asm;
|
|
|
|
|
2015-11-02 11:38:08 +00:00
|
|
|
if (!ds->show_color || !ds->colorop) {
|
2015-10-20 21:37:20 +00:00
|
|
|
return strdup (source);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-08-04 21:09:28 +00:00
|
|
|
|
|
|
|
r_cons_strcat (r_print_color_op_type (core->print, ds->analop.type));
|
|
|
|
|
|
|
|
// workaround dummy colorizer in case of paired commands (tms320 & friends)
|
|
|
|
|
2014-09-22 11:45:36 +00:00
|
|
|
spacer = strstr (source, "||");
|
2014-08-04 21:09:28 +00:00
|
|
|
if (spacer) {
|
2014-10-15 23:51:48 +00:00
|
|
|
char *scol1, *s1 = r_str_ndup (source, spacer - source);
|
2014-08-04 21:09:28 +00:00
|
|
|
char *scol2, *s2 = strdup (spacer + 2);
|
|
|
|
|
2015-10-20 21:37:20 +00:00
|
|
|
scol1 = r_print_colorize_opcode (s1, ds->color_reg, ds->color_num);
|
|
|
|
free (s1);
|
|
|
|
scol2 = r_print_colorize_opcode (s2, ds->color_reg, ds->color_num);
|
|
|
|
free (s2);
|
2015-02-16 01:48:32 +00:00
|
|
|
if (!scol1) scol1 = strdup ("");
|
2015-02-16 15:34:39 +00:00
|
|
|
if (!scol2) scol2 = strdup ("");
|
2014-08-04 21:09:28 +00:00
|
|
|
|
2014-09-22 11:45:36 +00:00
|
|
|
source = malloc (strlen(scol1) + strlen(scol2) + 2 + 1); // reuse source variable
|
|
|
|
sprintf (source, "%s||%s", scol1, scol2);
|
|
|
|
free (scol1);
|
|
|
|
free (scol2);
|
2014-08-04 21:09:28 +00:00
|
|
|
return source;
|
|
|
|
}
|
|
|
|
return r_print_colorize_opcode (source, ds->color_reg, ds->color_num);
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_build_op_str(RCore *core, RDisasmState *ds) {
|
2014-12-14 01:36:57 +00:00
|
|
|
char *asm_str;
|
|
|
|
if (!ds->opstr) {
|
2015-08-30 22:20:07 +00:00
|
|
|
ds->opstr = strdup (ds->asmop.buf_asm);
|
2014-12-14 01:36:57 +00:00
|
|
|
}
|
2015-09-27 23:00:06 +00:00
|
|
|
/* initialize */
|
|
|
|
core->parser->hint = ds->hint;
|
2014-12-13 17:06:01 +00:00
|
|
|
if (ds->varsub && ds->opstr) {
|
|
|
|
RAnalFunction *f = r_anal_get_fcn_in (core->anal,
|
|
|
|
ds->at, R_ANAL_FCN_TYPE_NULL);
|
2015-11-19 22:12:08 +00:00
|
|
|
//if (f) {
|
2014-12-14 01:36:57 +00:00
|
|
|
core->parser->varlist = r_anal_var_list;
|
2015-11-19 22:12:08 +00:00
|
|
|
r_parse_varsub (core->parser, f, ds->at, ds->analop.size,
|
2014-12-13 17:06:01 +00:00
|
|
|
ds->opstr, ds->strsub, sizeof (ds->strsub));
|
2015-02-07 23:30:25 +00:00
|
|
|
if (*ds->strsub) {
|
2015-02-06 17:24:17 +00:00
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (ds->strsub);
|
|
|
|
}
|
2015-11-19 22:12:08 +00:00
|
|
|
//}
|
2014-12-13 17:06:01 +00:00
|
|
|
}
|
2014-12-14 01:36:57 +00:00
|
|
|
asm_str = colorize_asm_string (core, ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->decode) {
|
|
|
|
char *tmpopstr = r_anal_op_to_string (core->anal, &ds->analop);
|
|
|
|
// TODO: Use data from code analysis..not raw ds->analop here
|
2014-01-16 17:04:42 +00:00
|
|
|
// if we want to get more information
|
2014-08-05 03:37:48 +00:00
|
|
|
ds->opstr = tmpopstr? tmpopstr: asm_str? strdup (asm_str): strdup ("");
|
2015-03-30 10:52:04 +00:00
|
|
|
} else {
|
|
|
|
if (ds->hint && ds->hint->opcode) {
|
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (ds->hint->opcode);
|
|
|
|
}
|
|
|
|
if (ds->filter) {
|
|
|
|
int ofs = core->parser->flagspace;
|
|
|
|
int fs = ds->flagspace_ports;
|
|
|
|
if (ds->analop.type == R_ANAL_OP_TYPE_IO) {
|
|
|
|
core->parser->notin_flagspace = -1;
|
2014-01-16 17:04:42 +00:00
|
|
|
core->parser->flagspace = fs;
|
|
|
|
} else {
|
2015-03-30 10:52:04 +00:00
|
|
|
if (fs != -1) {
|
|
|
|
core->parser->notin_flagspace = fs;
|
|
|
|
core->parser->flagspace = fs;
|
|
|
|
} else {
|
|
|
|
core->parser->notin_flagspace = -1;
|
|
|
|
core->parser->flagspace = -1;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-03-30 10:52:04 +00:00
|
|
|
r_parse_filter (core->parser, core->flags,
|
2016-04-26 09:09:15 +00:00
|
|
|
asm_str, ds->str, sizeof (ds->str), core->print->big_endian);
|
2015-03-30 10:52:04 +00:00
|
|
|
core->parser->flagspace = ofs;
|
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (ds->str);
|
|
|
|
core->parser->flagspace = ofs; // ???
|
|
|
|
} else {
|
|
|
|
if (!ds->opstr)
|
|
|
|
ds->opstr = strdup (asm_str?asm_str:"");
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->use_esil) {
|
|
|
|
if (*R_STRBUF_SAFEGET (&ds->analop.esil)) {
|
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (R_STRBUF_SAFEGET (&ds->analop.esil));
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-09-12 17:25:42 +00:00
|
|
|
char *p = malloc (strlen (ds->opstr)+6); /* What's up '\0' ? */
|
|
|
|
strcpy (p, "TODO,");
|
|
|
|
strcpy (p+5, ds->opstr);
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = p;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-04-01 21:22:29 +00:00
|
|
|
free (asm_str);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
R_API RAnalHint *r_core_hint_begin(RCore *core, RAnalHint* hint, ut64 at) {
|
2013-01-24 02:48:24 +00:00
|
|
|
static char *hint_arch = NULL;
|
2015-05-09 22:12:33 +00:00
|
|
|
static char *hint_syntax = NULL;
|
2013-01-24 02:48:24 +00:00
|
|
|
static int hint_bits = 0;
|
2015-09-28 09:21:23 +00:00
|
|
|
r_anal_hint_free (hint);
|
2013-01-24 02:48:24 +00:00
|
|
|
hint = r_anal_hint_get (core->anal, at);
|
|
|
|
if (hint_arch) {
|
|
|
|
r_config_set (core->config, "asm.arch", hint_arch);
|
|
|
|
hint_arch = NULL;
|
|
|
|
}
|
2015-05-09 22:12:33 +00:00
|
|
|
if (hint_syntax) {
|
|
|
|
r_config_set (core->config, "asm.syntax", hint_syntax);
|
|
|
|
hint_syntax = NULL;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
if (hint_bits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", hint_bits);
|
|
|
|
hint_bits = 0;
|
|
|
|
}
|
|
|
|
if (hint) {
|
|
|
|
/* arch */
|
|
|
|
if (hint->arch) {
|
|
|
|
if (!hint_arch) hint_arch = strdup (
|
|
|
|
r_config_get (core->config, "asm.arch"));
|
|
|
|
r_config_set (core->config, "asm.arch", hint->arch);
|
|
|
|
}
|
2015-05-09 22:12:33 +00:00
|
|
|
/* arch */
|
|
|
|
if (hint->syntax) {
|
|
|
|
if (!hint_syntax) hint_syntax = strdup (
|
|
|
|
r_config_get (core->config, "asm.syntax"));
|
|
|
|
r_config_set (core->config, "asm.syntax", hint->syntax);
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
/* bits */
|
|
|
|
if (hint->bits) {
|
|
|
|
if (!hint_bits) hint_bits =
|
|
|
|
r_config_get_i (core->config, "asm.bits");
|
|
|
|
r_config_set_i (core->config, "asm.bits", hint->bits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
|
2016-04-04 23:33:57 +00:00
|
|
|
static void beginline (RCore *core, RDisasmState *ds, RAnalFunction *f, bool nopre) {
|
2016-04-27 20:17:19 +00:00
|
|
|
const char *pre;
|
|
|
|
handle_setup_pre(core, ds, false);
|
|
|
|
pre = ds->pre;
|
2016-04-04 23:33:57 +00:00
|
|
|
if (nopre) {
|
|
|
|
if (*pre == '/' || *pre == '\\')
|
|
|
|
pre = " ";
|
|
|
|
}
|
2015-10-02 20:59:58 +00:00
|
|
|
if (ds->show_functions && ds->show_fcnlines) {
|
2016-05-04 15:13:44 +00:00
|
|
|
if (*pre == '\\') {
|
|
|
|
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
|
|
|
}
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_print_pre (core, ds);
|
2014-12-13 17:06:01 +00:00
|
|
|
}
|
2016-04-08 00:56:42 +00:00
|
|
|
char *tmp = ds->line;
|
|
|
|
ds->line = ds->refline2;
|
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
ds->line = tmp;
|
2014-09-23 08:15:19 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_pre_xrefs(RCore *core, RDisasmState *ds) {
|
2016-05-04 15:13:44 +00:00
|
|
|
if (ds->show_fcnlines) {
|
|
|
|
handle_setup_pre (core, ds, false);
|
|
|
|
if (*ds->pre != ' '){
|
|
|
|
handle_set_pre(ds, core->cons->vline[LINE_VERT]);
|
|
|
|
ds->pre = r_str_concat (ds->pre, " ");
|
|
|
|
}
|
2016-04-27 20:17:19 +00:00
|
|
|
}
|
|
|
|
handle_print_pre (core, ds);
|
|
|
|
char *tmp = ds->line;
|
|
|
|
ds->line = ds->refline2;
|
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
ds->line = tmp;
|
|
|
|
}
|
2016-05-04 15:13:44 +00:00
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_show_xrefs(RCore *core, RDisasmState *ds) {
|
2015-07-25 01:31:17 +00:00
|
|
|
RList *xrefs;
|
|
|
|
RAnalRef *refi;
|
|
|
|
RListIter *iter;
|
2016-02-07 20:44:35 +00:00
|
|
|
bool demangle = r_config_get_i (core->config, "bin.demangle");
|
|
|
|
const char *lang = demangle ? r_config_get (core->config, "bin.lang") : NULL;
|
|
|
|
char *name, *tmp;
|
2015-07-25 01:31:17 +00:00
|
|
|
int count = 0;
|
2016-02-07 20:44:35 +00:00
|
|
|
if (!ds->show_xrefs)
|
|
|
|
return;
|
|
|
|
if (!ds->show_comments)
|
|
|
|
return;
|
2015-07-25 01:31:17 +00:00
|
|
|
/* show xrefs */
|
|
|
|
xrefs = r_anal_xref_get (core->anal, ds->at);
|
2015-11-06 14:46:14 +00:00
|
|
|
if (!xrefs) return;
|
2015-07-25 01:31:17 +00:00
|
|
|
if (r_list_length (xrefs) > ds->maxrefs) {
|
2016-02-16 02:24:47 +00:00
|
|
|
int cols = r_cons_get_size (NULL);
|
|
|
|
cols -= 15;
|
|
|
|
cols /= 23;
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_pre_xrefs (core, ds);
|
2015-08-25 22:29:56 +00:00
|
|
|
r_cons_printf ("%s; XREFS: ", ds->show_color?
|
2016-02-07 20:44:35 +00:00
|
|
|
ds->pal_comment: "");
|
2014-09-23 08:15:19 +00:00
|
|
|
r_list_foreach (xrefs, iter, refi) {
|
2015-07-25 01:31:17 +00:00
|
|
|
r_cons_printf ("%s 0x%08"PFMT64x" ",
|
|
|
|
r_anal_xrefs_type_tostring (refi->type), refi->addr);
|
2016-02-16 02:24:47 +00:00
|
|
|
if (count == cols) {
|
2015-07-25 01:31:17 +00:00
|
|
|
if (iter->n) {
|
|
|
|
r_cons_newline ();
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_pre_xrefs (core, ds);
|
2015-07-25 01:31:17 +00:00
|
|
|
r_cons_printf ("%s; XREFS: ",
|
|
|
|
ds->show_color? ds->pal_comment: "");
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-07-25 01:31:17 +00:00
|
|
|
count = 0;
|
|
|
|
} else count++;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-07-25 01:31:17 +00:00
|
|
|
r_cons_newline ();
|
2014-09-23 08:15:19 +00:00
|
|
|
r_list_free (xrefs);
|
2015-07-25 01:31:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r_list_foreach (xrefs, iter, refi) {
|
|
|
|
if (refi->at == ds->at) {
|
|
|
|
RAnalFunction *fun = r_anal_get_fcn_in (
|
2016-04-22 12:00:15 +00:00
|
|
|
core->anal, refi->addr, -1);
|
2016-02-07 20:44:35 +00:00
|
|
|
name = strdup (fun ? fun->name : "unk");
|
|
|
|
if (demangle) {
|
|
|
|
tmp = r_bin_demangle (core->bin->cur, lang, name);
|
|
|
|
if (tmp) {
|
|
|
|
free (name);
|
|
|
|
name = tmp;
|
|
|
|
}
|
|
|
|
}
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_pre_xrefs (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("%s; %s XREF from 0x%08"PFMT64x" (%s)%s\n",
|
|
|
|
COLOR (ds, pal_comment),
|
|
|
|
r_anal_xrefs_type_tostring (refi->type),
|
|
|
|
refi->addr,
|
2016-02-07 20:44:35 +00:00
|
|
|
name,
|
2015-11-02 11:38:08 +00:00
|
|
|
COLOR_RESET (ds));
|
2016-02-07 20:44:35 +00:00
|
|
|
R_FREE (name);
|
2015-07-25 01:31:17 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-07-25 01:31:17 +00:00
|
|
|
r_list_free (xrefs);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
static void handle_atabs_option(RCore *core, RDisasmState *ds) {
|
2015-03-16 01:52:26 +00:00
|
|
|
int n, i = 0, comma = 0, word = 0;
|
|
|
|
int size, brackets = 0;
|
|
|
|
char *t, *b;
|
|
|
|
if (!ds || !ds->atabs)
|
|
|
|
return;
|
|
|
|
size = strlen (ds->asmop.buf_asm)* (ds->atabs+1)*4;
|
2016-03-03 23:33:24 +00:00
|
|
|
if (size < 1)
|
2015-03-16 01:52:26 +00:00
|
|
|
return;
|
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = b = malloc (size);
|
|
|
|
strcpy (b, ds->asmop.buf_asm);
|
|
|
|
for (; *b; b++, i++) {
|
|
|
|
if (*b=='(' || *b=='[') brackets++;
|
|
|
|
if (*b==')' || *b==']') brackets--;
|
|
|
|
if (*b==',') comma = 1;
|
|
|
|
if (*b!=' ') continue;
|
|
|
|
if (word>0 && !comma) continue; //&& b[1]=='[') continue;
|
|
|
|
if (brackets>0) continue;
|
|
|
|
comma = 0;
|
|
|
|
brackets = 0;
|
|
|
|
n = (ds->atabs-i);
|
|
|
|
t = strdup (b+1); //XXX slow!
|
|
|
|
if (n<1) n = 1;
|
|
|
|
memset (b, ' ', n);
|
|
|
|
b += n;
|
|
|
|
strcpy (b, t);
|
|
|
|
free (t);
|
|
|
|
i = 0;
|
|
|
|
word++;
|
2015-07-15 13:14:51 +00:00
|
|
|
if (ds->atabsonce) {
|
|
|
|
break;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-28 01:23:29 +00:00
|
|
|
static int handleMidFlags(RCore *core, RDisasmState *ds, bool print) {
|
|
|
|
RFlagItem *fi;
|
|
|
|
int i;
|
|
|
|
for (i = 1; i < ds->oplen; i++) {
|
|
|
|
fi = r_flag_get_i (core->flags, ds->at + i);
|
|
|
|
if (fi) {
|
|
|
|
if (!strncmp (fi->name, "reloc.", 6)) {
|
|
|
|
if (print) {
|
|
|
|
r_cons_printf ("(%s)\n", fi->name);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_show_cursor(RCore *core, RDisasmState *ds) {
|
2015-11-28 01:23:29 +00:00
|
|
|
char res[] = " ";
|
2015-07-25 01:31:17 +00:00
|
|
|
void *p;
|
2015-11-28 01:23:29 +00:00
|
|
|
int q, t;
|
2015-07-25 01:31:17 +00:00
|
|
|
if (!core || !ds || !ds->show_marks)
|
|
|
|
return;
|
|
|
|
q = core->print->cur_enabled &&
|
2014-05-04 15:21:05 +00:00
|
|
|
ds->cursor >= ds->index &&
|
2015-11-27 15:16:44 +00:00
|
|
|
ds->cursor < (ds->index + ds->asmop.size);
|
2015-07-25 01:31:17 +00:00
|
|
|
p = r_bp_get_at (core->dbg->bp, ds->at);
|
2015-11-28 01:23:29 +00:00
|
|
|
t = ds->midflags && handleMidFlags (core, ds, false) > 0;
|
2015-11-27 13:09:37 +00:00
|
|
|
if (p) res[0] = 'b';
|
2015-11-28 01:23:29 +00:00
|
|
|
if (t) res[1] = '~';
|
2015-11-27 15:16:44 +00:00
|
|
|
if (q) {
|
|
|
|
if (ds->cursor == ds->index) {
|
2015-11-28 01:23:29 +00:00
|
|
|
res[2] = '*';
|
2015-11-27 15:16:44 +00:00
|
|
|
} else {
|
2015-11-28 01:23:29 +00:00
|
|
|
int i = 2, diff = ds->cursor - ds->index;
|
2015-11-27 15:16:44 +00:00
|
|
|
if (diff > 9) res[i++] = '0' + (diff / 10);
|
|
|
|
res[i] = '0' + (diff % 10);
|
|
|
|
}
|
|
|
|
}
|
2015-11-27 13:09:37 +00:00
|
|
|
r_cons_strcat (res);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
static int var_comparator(const RAnalVar *a, const RAnalVar *b){
|
2015-07-25 01:31:17 +00:00
|
|
|
if (a && b) return a->delta > b->delta;
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2015-03-30 14:03:11 +00:00
|
|
|
}
|
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
static void handle_show_functions(RCore *core, RDisasmState *ds) {
|
2015-03-16 01:52:26 +00:00
|
|
|
RAnalFunction *f;
|
2016-02-16 01:08:09 +00:00
|
|
|
bool demangle;
|
|
|
|
const char *lang;
|
2016-02-07 20:44:35 +00:00
|
|
|
char *fcn_name;
|
2015-03-16 01:52:26 +00:00
|
|
|
char *sign;
|
2016-05-04 15:13:44 +00:00
|
|
|
|
|
|
|
if (!core || !ds || !ds->show_functions) {
|
2015-03-16 01:52:26 +00:00
|
|
|
return;
|
2016-05-04 15:13:44 +00:00
|
|
|
}
|
2016-02-16 01:08:09 +00:00
|
|
|
demangle = r_config_get_i (core->config, "bin.demangle");
|
|
|
|
lang = demangle ? r_config_get (core->config, "bin.lang") : NULL;
|
2015-03-16 01:52:26 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
2016-05-04 15:13:44 +00:00
|
|
|
if (!f || (f->addr != ds->at)) {
|
2015-03-16 01:52:26 +00:00
|
|
|
return;
|
2016-05-04 15:13:44 +00:00
|
|
|
}
|
2016-02-07 20:44:35 +00:00
|
|
|
if (demangle) {
|
|
|
|
fcn_name = r_bin_demangle (core->bin->cur, lang, f->name);
|
|
|
|
if (!fcn_name)
|
|
|
|
fcn_name = strdup (f->name);
|
|
|
|
} else {
|
|
|
|
fcn_name = f->name;
|
2015-03-16 01:52:26 +00:00
|
|
|
}
|
|
|
|
sign = r_anal_fcn_to_string (core->anal, f);
|
|
|
|
if (f->type == R_ANAL_FCN_TYPE_LOC) {
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("%s%s ", COLOR (ds, color_fline),
|
|
|
|
core->cons->vline[LINE_CROSS]); // |-
|
|
|
|
r_cons_printf ("%s%s%s %d\n", COLOR (ds, color_floc),
|
2016-02-07 20:44:35 +00:00
|
|
|
fcn_name, COLOR_RESET (ds), f->size);
|
2015-03-16 01:52:26 +00:00
|
|
|
} else {
|
2015-11-02 11:38:08 +00:00
|
|
|
const char *space = ds->show_fcnlines ? " " : "";
|
|
|
|
const char *fcntype;
|
2016-03-15 10:47:13 +00:00
|
|
|
char cmt[32];
|
|
|
|
get_bits_comment (core, f, cmt, sizeof (cmt));
|
2015-11-02 11:38:08 +00:00
|
|
|
|
|
|
|
switch (f->type) {
|
|
|
|
case R_ANAL_FCN_TYPE_FCN:
|
|
|
|
case R_ANAL_FCN_TYPE_SYM:
|
|
|
|
fcntype = "fcn"; break;
|
|
|
|
case R_ANAL_FCN_TYPE_IMP:
|
|
|
|
fcntype = "imp"; break;
|
|
|
|
default:
|
|
|
|
fcntype = "loc"; break;
|
|
|
|
}
|
2014-12-14 22:08:05 +00:00
|
|
|
#if SLOW_BUT_OK
|
2015-11-02 11:38:08 +00:00
|
|
|
int corner = (f->size <= ds->analop.size) ? RDWN_CORNER : LINE_VERT;
|
2015-03-16 01:52:26 +00:00
|
|
|
corner = LINE_VERT; // 99% of cases
|
|
|
|
RFlagItem *item = r_flag_get_i (core->flags, f->addr);
|
2015-11-02 11:38:08 +00:00
|
|
|
corner = item ? LINE_VERT : RDWN_CORNER;
|
|
|
|
if (item) {
|
2015-03-16 01:52:26 +00:00
|
|
|
corner = 0;
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
#endif
|
2015-03-16 01:52:26 +00:00
|
|
|
handle_set_pre (ds, core->cons->vline[RUP_CORNER]);
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->show_flgoff) {
|
|
|
|
r_cons_printf ("%s%s", COLOR (ds, color_fline), ds->pre);
|
2016-03-09 09:08:53 +00:00
|
|
|
if (ds->show_fcnlines) {
|
2016-03-03 23:33:24 +00:00
|
|
|
r_cons_printf (" ");
|
|
|
|
}
|
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
handle_print_offset (core, ds);
|
2016-03-15 10:47:13 +00:00
|
|
|
r_cons_printf ("%s%s%s(%s) %s%s%s %d\n",
|
2016-03-03 23:33:24 +00:00
|
|
|
space, COLOR_RESET (ds), COLOR (ds, color_fname),
|
2016-03-15 10:47:13 +00:00
|
|
|
fcntype, fcn_name, cmt, COLOR_RESET (ds), f->size);
|
2016-03-03 23:33:24 +00:00
|
|
|
} else {
|
2016-03-15 10:47:13 +00:00
|
|
|
r_cons_printf ("%s%s%s%s%s(%s) %s%s%s %d\n",
|
2016-03-03 23:33:24 +00:00
|
|
|
COLOR (ds, color_fline), ds->pre,
|
|
|
|
space, COLOR_RESET (ds), COLOR (ds, color_fname),
|
2016-03-15 10:47:13 +00:00
|
|
|
fcntype, fcn_name, cmt, COLOR_RESET (ds), f->size);
|
2016-03-03 23:33:24 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
}
|
2016-02-07 20:44:35 +00:00
|
|
|
if (sign)
|
|
|
|
r_cons_printf ("// %s\n", sign);
|
2015-07-25 01:31:17 +00:00
|
|
|
R_FREE (sign);
|
2015-03-16 01:52:26 +00:00
|
|
|
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
2016-05-04 15:13:44 +00:00
|
|
|
if (ds->show_fcnlines) {
|
2016-02-07 20:44:35 +00:00
|
|
|
ds->pre = r_str_concat (ds->pre, " ");
|
2016-05-04 15:13:44 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
ds->stackptr = 0;
|
|
|
|
if (ds->vars) {
|
|
|
|
char spaces[32];
|
2016-04-10 18:59:11 +00:00
|
|
|
RList *args = r_anal_var_list (core->anal, f,
|
|
|
|
(f->call == R_ANAL_CC_TYPE_FASTCALL) ? 'A' : 'a');
|
2015-03-16 01:52:26 +00:00
|
|
|
RList *vars = r_anal_var_list (core->anal, f, 'v');
|
2016-05-01 12:48:04 +00:00
|
|
|
RList *sp_vars = r_anal_var_list (core->anal, f, 'e');
|
2015-03-30 22:49:45 +00:00
|
|
|
r_list_sort (args, (RListComparator)var_comparator);
|
|
|
|
r_list_sort (vars, (RListComparator)var_comparator);
|
2016-05-01 12:48:04 +00:00
|
|
|
r_list_sort (sp_vars, (RListComparator)var_comparator);
|
2015-03-30 14:03:11 +00:00
|
|
|
r_list_join (args, vars);
|
2016-05-01 12:48:04 +00:00
|
|
|
r_list_join (args,sp_vars);
|
2015-03-16 01:52:26 +00:00
|
|
|
RAnalVar *var;
|
|
|
|
RListIter *iter;
|
2015-03-30 14:03:11 +00:00
|
|
|
r_list_foreach (args, iter, var) {
|
2015-03-16 01:52:26 +00:00
|
|
|
int idx;
|
2015-11-02 11:38:08 +00:00
|
|
|
|
2015-03-16 01:52:26 +00:00
|
|
|
memset (spaces, ' ', sizeof(spaces));
|
2015-11-02 11:38:08 +00:00
|
|
|
idx = 12 - strlen (var->name);
|
|
|
|
if (idx < 0) idx = 0;
|
2015-03-16 01:52:26 +00:00
|
|
|
spaces[idx] = 0;
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2016-04-08 00:56:42 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
2016-04-04 22:56:48 +00:00
|
|
|
if (ds->show_flgoff) {
|
|
|
|
handle_print_offset (core, ds);
|
2016-04-04 23:33:57 +00:00
|
|
|
r_cons_printf (" ");
|
2016-04-04 22:56:48 +00:00
|
|
|
}
|
2016-04-10 18:59:11 +00:00
|
|
|
r_cons_printf ("%s; ", COLOR (ds, color_other));
|
|
|
|
switch (var->kind) {
|
|
|
|
case 'a':
|
|
|
|
r_cons_printf ("arg %s %s @ %s+0x%x",
|
|
|
|
var->type, var->name,
|
|
|
|
core->anal->reg->name[R_REG_NAME_BP],
|
|
|
|
var->delta);
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
r_cons_printf ("var %s %s @ %s-0x%x",
|
|
|
|
var->type, var->name,
|
|
|
|
core->anal->reg->name[R_REG_NAME_BP],
|
|
|
|
var->delta);
|
|
|
|
break;
|
|
|
|
case 'A':
|
|
|
|
switch (var->delta){
|
|
|
|
case 0:
|
|
|
|
r_cons_printf ("arg %s %s @ ecx",
|
|
|
|
var->type, var->name);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
r_cons_printf ("arg %s %s @ edx",
|
|
|
|
var->type, var->name);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_cons_printf ("arg %s %s @ %s+0x%x",
|
|
|
|
var->type, var->name,
|
|
|
|
core->anal->reg->name[R_REG_NAME_BP],
|
|
|
|
var->delta);
|
|
|
|
}
|
|
|
|
break;
|
2016-05-01 12:48:04 +00:00
|
|
|
case 'e':
|
2016-05-04 20:20:58 +00:00
|
|
|
r_cons_printf ("var %s %s @ %s+0x%x",
|
2016-05-01 12:48:04 +00:00
|
|
|
var->type, var->name,
|
|
|
|
core->anal->reg->name[R_REG_NAME_SP],
|
|
|
|
var->delta);
|
|
|
|
break;
|
2016-04-10 18:59:11 +00:00
|
|
|
}
|
|
|
|
r_cons_printf ("%s\n", COLOR_RESET (ds));
|
2014-12-18 11:54:36 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
r_list_free (vars);
|
|
|
|
// it's already empty, but rlist instance is still there
|
|
|
|
r_list_free (args);
|
2014-12-13 17:06:01 +00:00
|
|
|
}
|
2016-02-07 20:44:35 +00:00
|
|
|
if (demangle)
|
|
|
|
free (fcn_name);
|
2014-12-13 17:06:01 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_setup_print_pre(RCore *core, RDisasmState *ds, bool tail) {
|
|
|
|
handle_setup_pre (core, ds, tail);
|
|
|
|
handle_print_pre (core, ds);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_setup_pre(RCore *core, RDisasmState *ds, bool tail) {
|
2016-03-03 23:33:24 +00:00
|
|
|
RAnalFunction *f;
|
2016-04-27 20:17:19 +00:00
|
|
|
if (!ds->show_functions) return;
|
2016-03-03 23:33:24 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (f) {
|
|
|
|
if (f->addr == ds->at) {
|
|
|
|
if (ds->analop.size == f->size) {
|
2014-07-21 02:18:27 +00:00
|
|
|
handle_set_pre (ds, core->cons->vline[RDWN_CORNER]);
|
2016-03-03 23:33:24 +00:00
|
|
|
} else {
|
2014-07-21 02:18:27 +00:00
|
|
|
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2016-03-03 23:33:24 +00:00
|
|
|
} else if (f->addr + f->size - ds->analop.size == ds->at) {
|
|
|
|
handle_set_pre (ds, core->cons->vline[RDWN_CORNER]);
|
|
|
|
} else if (ds->at > f->addr && ds->at < f->addr+f->size-1) {
|
|
|
|
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
|
|
|
}
|
2015-11-02 11:38:08 +00:00
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->show_fcnlines) {
|
|
|
|
ds->pre = r_str_concat (ds->pre, " ");
|
|
|
|
}
|
|
|
|
if (tail) {
|
|
|
|
r_str_replace_char (ds->pre, '\\', ' ');
|
|
|
|
r_str_replace_char (ds->pre, '|', '\\');
|
|
|
|
}
|
2016-04-27 20:17:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_print_pre(RCore *core, RDisasmState *ds) {
|
|
|
|
RAnalFunction *f;
|
|
|
|
if (!ds->show_functions) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (f) {
|
2016-03-03 23:33:24 +00:00
|
|
|
r_cons_printf ("%s%s%s", COLOR (ds, color_fline),
|
|
|
|
ds->pre, COLOR_RESET (ds));
|
|
|
|
} else {
|
|
|
|
if (ds->show_lines) {
|
|
|
|
r_cons_printf (" ");
|
|
|
|
} else if (ds->show_fcnlines) {
|
|
|
|
r_cons_printf (" ");
|
2015-03-27 12:16:40 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_show_comments_right(RCore *core, RDisasmState *ds) {
|
2015-06-04 22:19:41 +00:00
|
|
|
int linelen, maxclen ;
|
2015-03-16 01:52:26 +00:00
|
|
|
RAnalFunction *f;
|
|
|
|
RFlagItem *item;
|
2014-01-16 17:04:42 +00:00
|
|
|
/* show comment at right? */
|
2015-06-04 22:19:41 +00:00
|
|
|
int scr = ds->show_comment_right;
|
2015-03-16 01:52:26 +00:00
|
|
|
if (!ds->show_comments)
|
|
|
|
return;
|
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
item = r_flag_get_i (core->flags, ds->at);
|
|
|
|
ds->comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
|
2015-04-11 02:33:37 +00:00
|
|
|
if (!ds->comment && item && item->comment && *item->comment) {
|
2015-03-16 01:52:26 +00:00
|
|
|
ds->ocomment = item->comment;
|
|
|
|
ds->comment = strdup (item->comment);
|
|
|
|
}
|
|
|
|
if (!ds->comment)
|
|
|
|
return;
|
|
|
|
maxclen = strlen (ds->comment)+5;
|
|
|
|
linelen = maxclen;
|
|
|
|
if (ds->show_comment_right_default) {
|
|
|
|
if (ds->ocols+maxclen < core->cons->columns) {
|
|
|
|
if (ds->comment && *ds->comment && strlen (ds->comment)<maxclen) {
|
|
|
|
if (!strchr (ds->comment, '\n')) // more than one line?
|
|
|
|
ds->show_comment_right = 1;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!ds->show_comment_right) {
|
|
|
|
int infun, mycols = ds->lcols;
|
|
|
|
if (mycols + linelen + 10 > core->cons->columns)
|
|
|
|
mycols = 0;
|
|
|
|
mycols /= 2;
|
|
|
|
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
2014-01-16 17:04:42 +00:00
|
|
|
#if OLD_COMMENTS
|
2015-03-16 01:52:26 +00:00
|
|
|
r_cons_strcat ("; ");
|
|
|
|
// XXX: always prefix with ; the comments
|
|
|
|
if (*ds->comment != ';') r_cons_strcat (" ; ");
|
|
|
|
r_cons_strcat_justify (ds->comment, mycols, ';');
|
2014-01-16 17:04:42 +00:00
|
|
|
#else
|
2015-03-16 01:52:26 +00:00
|
|
|
infun = f && (f->addr != ds->at);
|
|
|
|
if (infun) {
|
2015-11-02 11:38:08 +00:00
|
|
|
char *str = strdup (ds->show_color ? ds->color_fline : "");
|
2015-03-16 01:52:26 +00:00
|
|
|
str = r_str_concat (str, core->cons->vline[LINE_VERT]);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-03-16 01:52:26 +00:00
|
|
|
str = r_str_concat (str, ds->color_flow);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
// color refline
|
|
|
|
str = r_str_concat (str, " ");
|
|
|
|
str = r_str_concat (str, ds->refline2);
|
|
|
|
// color comment
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-03-16 01:52:26 +00:00
|
|
|
str = r_str_concat (str, ds->color_comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-03-16 01:52:26 +00:00
|
|
|
str = r_str_concat (str, "; ");
|
|
|
|
ds->comment = r_str_prefix_all (ds->comment, str);
|
|
|
|
free (str);
|
|
|
|
} else {
|
|
|
|
ds->comment = r_str_prefix_all (ds->comment, " ; ");
|
|
|
|
}
|
2015-06-01 23:04:10 +00:00
|
|
|
/* print multiline comment */
|
|
|
|
if (ds->cmtfold) {
|
|
|
|
char * p = strdup (ds->comment);
|
2016-04-08 00:56:42 +00:00
|
|
|
char *q = strchr (p, '\n');
|
2015-06-01 23:04:10 +00:00
|
|
|
if (q) {
|
|
|
|
*q = 0;
|
|
|
|
r_cons_strcat (p);
|
|
|
|
r_cons_strcat (" ; [z] unfold");
|
|
|
|
}
|
|
|
|
free (p);
|
|
|
|
} else {
|
|
|
|
r_cons_strcat (ds->comment);
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
#endif
|
2015-03-16 01:52:26 +00:00
|
|
|
if (ds->show_color) handle_print_color_reset (core, ds);
|
|
|
|
r_cons_newline ();
|
|
|
|
free (ds->comment);
|
|
|
|
ds->comment = NULL;
|
|
|
|
|
|
|
|
/* flag one */
|
|
|
|
if (item && item->comment && ds->ocomment != item->comment) {
|
|
|
|
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
|
|
|
r_cons_newline ();
|
|
|
|
r_cons_strcat (" ; ");
|
|
|
|
r_cons_strcat_justify (item->comment, mycols, ';');
|
|
|
|
r_cons_newline ();
|
|
|
|
if (ds->show_color) handle_print_color_reset (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2015-06-04 22:19:41 +00:00
|
|
|
ds->show_comment_right = scr;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
// TODO: rename to ds_show_flags
|
2014-01-20 00:42:16 +00:00
|
|
|
static void handle_show_flags_option(RCore *core, RDisasmState *ds) {
|
2016-03-23 21:13:55 +00:00
|
|
|
//const char *beginch;
|
2016-03-03 23:33:24 +00:00
|
|
|
RFlagItem *flag;
|
|
|
|
RListIter *iter;
|
|
|
|
RAnalFunction *f;
|
|
|
|
const RList /*RFlagList*/ *flaglist;
|
2016-03-23 21:13:55 +00:00
|
|
|
//bool printed = false;
|
2015-10-02 20:59:58 +00:00
|
|
|
|
2016-03-03 23:33:24 +00:00
|
|
|
if (!ds->show_flags) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
flaglist = r_flag_get_list (core->flags, ds->at);
|
|
|
|
|
|
|
|
r_list_foreach (flaglist, iter, flag) {
|
|
|
|
if (f && f->addr == flag->offset && !strcmp (flag->name, f->name)) {
|
|
|
|
// do not show flags that have the same name as the function
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ds->show_flgoff) {
|
|
|
|
if (f) {
|
2016-04-04 23:33:57 +00:00
|
|
|
beginline (core, ds, f, false);
|
2015-01-17 00:56:20 +00:00
|
|
|
} else {
|
2016-03-03 23:33:24 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
2016-04-04 22:56:48 +00:00
|
|
|
r_cons_printf (" ");
|
2016-03-03 23:33:24 +00:00
|
|
|
}
|
|
|
|
handle_print_offset (core, ds);
|
|
|
|
r_cons_printf (" ");
|
|
|
|
} else {
|
2016-03-09 08:50:30 +00:00
|
|
|
r_cons_printf ((f && ds->at > f->addr)?"| ": " ");
|
2016-03-03 23:33:24 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
r_cons_printf (";-- ");
|
|
|
|
}
|
|
|
|
if (ds->show_color)
|
|
|
|
r_cons_strcat (ds->color_flag);
|
2016-03-23 21:13:55 +00:00
|
|
|
//beginch = (iter->p && printed) ? ", " : "";
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->asm_demangle) {
|
|
|
|
const char *lang = r_config_get (core->config, "bin.lang");
|
|
|
|
char *name = r_bin_demangle (core->bin->cur, lang, flag->realname);
|
2016-03-09 08:50:30 +00:00
|
|
|
r_cons_printf ("%s:\n", name? name: flag->realname);
|
2016-03-03 23:33:24 +00:00
|
|
|
R_FREE (name);
|
|
|
|
} else {
|
2016-03-09 08:50:30 +00:00
|
|
|
r_cons_printf ("%s:\n", flag->name);
|
2015-01-17 00:56:20 +00:00
|
|
|
}
|
2016-03-23 21:13:55 +00:00
|
|
|
//printed = true;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2016-03-09 08:53:53 +00:00
|
|
|
if (ds->show_spacy) {
|
|
|
|
if (!r_list_empty (flaglist)) {
|
|
|
|
ds_print_spacy(ds, false);
|
|
|
|
}
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_update_ref_lines(RCore *core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_lines) {
|
|
|
|
ds->line = r_anal_reflines_str (core, ds->at, ds->linesopts);
|
2016-04-03 22:17:57 +00:00
|
|
|
free (ds->refline);
|
2016-04-04 20:30:11 +00:00
|
|
|
ds->refline = ds->line? strdup (ds->line): NULL;
|
2016-04-03 22:17:57 +00:00
|
|
|
free (ds->refline2);
|
2015-11-06 14:46:14 +00:00
|
|
|
ds->refline2 = r_anal_reflines_str (core, ds->at,
|
|
|
|
ds->linesopts | R_ANAL_REFLINE_TYPE_MIDDLE);
|
2015-08-30 21:34:21 +00:00
|
|
|
if (ds->line) {
|
|
|
|
if (strchr (ds->line, '<'))
|
|
|
|
ds->indent_level++;
|
|
|
|
if (strchr (ds->line, '>'))
|
|
|
|
ds->indent_level--;
|
|
|
|
} else {
|
|
|
|
ds->indent_level = 0;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
ds->refline = strdup ("");
|
|
|
|
ds->refline2 = strdup ("");
|
|
|
|
ds->line = NULL;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
static int perform_disassembly(RCore *core, RDisasmState *ds, ut8 *buf, int len) {
|
2016-04-20 23:38:08 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (ds->hint && ds->hint->opcode) {
|
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (ds->hint->opcode);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
ret = r_asm_disassemble (core->assembler, &ds->asmop, buf, len);
|
2015-11-02 20:30:55 +00:00
|
|
|
if (ds->asmop.size < 1) ds->asmop.size = 1;
|
|
|
|
|
2016-01-10 21:30:10 +00:00
|
|
|
if (ds->show_nodup) {
|
2016-01-11 21:28:22 +00:00
|
|
|
const char *opname = (ret < 1)? "invalid": ds->asmop.buf_asm;
|
|
|
|
if (ds->prev_ins && !strcmp (ds->prev_ins, opname)) {
|
2016-01-10 21:30:10 +00:00
|
|
|
if (!ds->prev_ins_eq) {
|
2016-01-11 21:28:22 +00:00
|
|
|
ds->prev_ins_eq = true;
|
|
|
|
r_cons_printf ("...");
|
2016-01-10 21:30:10 +00:00
|
|
|
}
|
2016-01-11 21:28:22 +00:00
|
|
|
ds->prev_ins_count ++;
|
2016-01-10 21:30:10 +00:00
|
|
|
return -31337;
|
|
|
|
}
|
2016-01-11 21:28:22 +00:00
|
|
|
if (ds->prev_ins_eq) {
|
|
|
|
r_cons_printf ("dup (%d)\n", ds->prev_ins_count);
|
|
|
|
}
|
|
|
|
ds->prev_ins_count = 0;
|
2016-01-10 21:30:10 +00:00
|
|
|
ds->prev_ins_eq = false;
|
|
|
|
if (ds->prev_ins) {
|
|
|
|
R_FREE (ds->prev_ins);
|
|
|
|
}
|
|
|
|
ds->prev_ins = strdup (ds->asmop.buf_asm);
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->oplen = ds->asmop.size;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2015-11-02 20:30:55 +00:00
|
|
|
if (ret < 1) {
|
2014-01-16 17:04:42 +00:00
|
|
|
ret = -1;
|
|
|
|
#if HASRETRY
|
2015-11-02 20:30:55 +00:00
|
|
|
if (!ds->cbytes && ds->tries > 0) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->addr = core->assembler->pc;
|
|
|
|
ds->tries--;
|
|
|
|
ds->idx = 0;
|
|
|
|
ds->retry = 1;
|
2014-01-16 17:04:42 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->lastfail = 1;
|
2015-11-02 20:30:55 +00:00
|
|
|
ds->asmop.size = (ds->hint && ds->hint->size) ?
|
|
|
|
ds->hint->size : 1;
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->lastfail = 0;
|
2015-11-02 20:30:55 +00:00
|
|
|
ds->asmop.size = (ds->hint && ds->hint->size) ?
|
|
|
|
ds->hint->size : r_asm_op_get_size (&ds->asmop);
|
2014-12-21 03:18:56 +00:00
|
|
|
ds->oplen = ds->asmop.size;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->pseudo) {
|
2015-11-02 20:30:55 +00:00
|
|
|
r_parse_parse (core->parser, ds->opstr ?
|
|
|
|
ds->opstr : ds->asmop.buf_asm, ds->str);
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = strdup (ds->str);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2015-11-06 14:46:14 +00:00
|
|
|
if (ds->acase) r_str_case (ds->asmop.buf_asm, 1);
|
2014-01-16 17:04:42 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_control_flow_comments(RCore * core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_comments && ds->show_cmtflgrefs) {
|
2014-01-16 17:04:42 +00:00
|
|
|
RFlagItem *item;
|
2014-01-20 00:42:16 +00:00
|
|
|
switch (ds->analop.type) {
|
2014-01-16 17:04:42 +00:00
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
2014-01-20 00:42:16 +00:00
|
|
|
item = r_flag_get_i (core->flags, ds->analop.jump);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (item && item->comment) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
2014-11-13 02:36:48 +00:00
|
|
|
handle_comment_align (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (" ; ref to %s: %s\n", item->name, item->comment);
|
2014-11-23 23:16:36 +00:00
|
|
|
handle_print_color_reset (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_lines_right(RCore *core, RDisasmState *ds){
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->linesright && ds->show_lines && ds->line) {
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("%s%s%s", COLOR (ds, color_flow), ds->line, COLOR_RESET (ds));
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-21 03:18:56 +00:00
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void printCol(RDisasmState *ds, char *sect, int cols, const char *color) {
|
2016-04-08 00:56:42 +00:00
|
|
|
int pre, post;
|
|
|
|
if (cols < 8) cols = 8;
|
|
|
|
int outsz = cols + 32;
|
|
|
|
char *out = malloc (outsz);
|
|
|
|
memset (out, ' ', outsz);
|
|
|
|
int sect_len = strlen (sect);
|
|
|
|
|
|
|
|
if (sect_len > cols) {
|
|
|
|
sect[cols-2] = '.';
|
|
|
|
sect[cols-1] = '.';
|
|
|
|
sect[cols] = 0;
|
|
|
|
}
|
|
|
|
if (ds->show_color) {
|
|
|
|
pre = strlen (color) + 1;
|
|
|
|
post = strlen (color) + 1 + strlen (Color_RESET);
|
|
|
|
snprintf (out, outsz-pre, "%s %s", color, sect);
|
|
|
|
strcat (out, Color_RESET);
|
|
|
|
out[outsz-1] = 0;
|
|
|
|
} else {
|
|
|
|
strcpy (out + 1, sect);
|
|
|
|
pre = 1;
|
|
|
|
post = 0;
|
|
|
|
}
|
|
|
|
out[strlen (out)] = ' ';
|
|
|
|
out[cols + post] = 0;
|
|
|
|
r_cons_strcat (out);
|
|
|
|
free (out);
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_lines_left(RCore *core, RDisasmState *ds) {
|
2014-11-22 04:39:52 +00:00
|
|
|
if (ds->show_section) {
|
2016-04-08 00:56:42 +00:00
|
|
|
char *sect = strdup (getSectionName (core, ds->at));
|
|
|
|
printCol (ds, sect, ds->show_section_col, ds->color_reg);
|
|
|
|
free (sect);
|
2014-11-22 04:39:52 +00:00
|
|
|
}
|
2016-03-29 00:03:17 +00:00
|
|
|
if (ds->show_symbols) {
|
|
|
|
static RFlagItem sfi = {0};
|
|
|
|
const char *name = "";
|
|
|
|
int delta = 0;
|
|
|
|
if (ds->fcn) {
|
|
|
|
sfi.offset = ds->fcn->addr;
|
|
|
|
sfi.name = ds->fcn->name;
|
|
|
|
ds->lastflag = &sfi;
|
|
|
|
} else {
|
|
|
|
RFlagItem *fi = r_flag_get_at (core->flags, ds->at);
|
|
|
|
if (fi) { // && (!ds->lastflag || fi->offset != ds->at)) {
|
|
|
|
sfi.offset = fi->offset;
|
|
|
|
sfi.name = fi->name;
|
|
|
|
ds->lastflag = &sfi;
|
|
|
|
}
|
|
|
|
}
|
2016-04-08 00:56:42 +00:00
|
|
|
if (ds->lastflag && ds->lastflag->name) {
|
2016-03-29 00:03:17 +00:00
|
|
|
name = ds->lastflag->name;
|
|
|
|
delta = ds->at - ds->lastflag->offset;
|
|
|
|
}
|
2016-04-08 00:56:42 +00:00
|
|
|
{
|
|
|
|
char * str = r_str_newf ("%s + %-4d", name, delta);
|
|
|
|
printCol (ds, str, ds->show_symbols_col, ds->color_num);
|
|
|
|
free (str);
|
|
|
|
}
|
2016-03-29 00:03:17 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!ds->linesright && ds->show_lines && ds->line) {
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("%s%s%s", COLOR (ds, color_flow), ds->line, COLOR_RESET (ds));
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_family(RCore *core, RDisasmState *ds) {
|
2015-10-03 11:52:52 +00:00
|
|
|
if (ds->show_family) {
|
|
|
|
const char *familystr = r_anal_op_family_to_string (ds->analop.family);
|
|
|
|
r_cons_printf ("%5s ", familystr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_cycles(RCore *core, RDisasmState *ds) {
|
2014-02-25 23:03:42 +00:00
|
|
|
if (ds->show_cycles) {
|
|
|
|
if (!ds->analop.failcycles)
|
|
|
|
r_cons_printf ("%3d ", ds->analop.cycles);
|
|
|
|
else r_cons_printf ("%3d %3d ", ds->analop.cycles, ds->analop.failcycles);
|
|
|
|
}
|
2014-11-02 02:06:52 +00:00
|
|
|
if (ds->cyclespace) {
|
|
|
|
char spaces [32];
|
|
|
|
int times = R_MIN (ds->analop.cycles/4, 30); // limit to 30
|
|
|
|
memset (spaces, ' ', sizeof (spaces));
|
|
|
|
spaces[times] = 0;
|
|
|
|
r_cons_strcat (spaces);
|
|
|
|
}
|
2014-02-10 22:01:19 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_stackptr(RCore *core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_stackptr) {
|
2016-04-08 00:56:42 +00:00
|
|
|
r_cons_printf ("%5d%s", ds->stackptr,
|
2016-05-11 10:59:32 +00:00
|
|
|
ds->analop.type == R_ANAL_OP_TYPE_CALL?">":
|
2016-04-13 21:33:30 +00:00
|
|
|
ds->analop.stackop == R_ANAL_STACK_ALIGN? "=":
|
|
|
|
ds->stackptr > ds->ostackptr? "+":
|
|
|
|
ds->stackptr < ds->ostackptr? "-": " ");
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->ostackptr = ds->stackptr;
|
2016-05-11 10:59:32 +00:00
|
|
|
if (ds->analop.stackop == R_ANAL_STACK_RESET) {
|
|
|
|
ds->stackptr = 0;
|
|
|
|
} else {
|
|
|
|
ds->stackptr += ds->analop.stackptr;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
/* XXX if we reset the stackptr 'ret 0x4' has not effect.
|
|
|
|
* Use RAnalFunction->RAnalOp->stackptr? */
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->analop.type == R_ANAL_OP_TYPE_RET)
|
|
|
|
ds->stackptr = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_offset(RCore *core, RDisasmState *ds) {
|
2016-05-10 20:15:24 +00:00
|
|
|
r_print_set_screenbounds (core->print, ds->at);
|
2015-01-11 23:11:06 +00:00
|
|
|
if (ds->show_offset) {
|
2015-11-08 22:38:42 +00:00
|
|
|
static RFlagItem sfi = {0};
|
2015-01-18 02:02:56 +00:00
|
|
|
RFlagItem *fi;
|
2015-01-11 23:11:06 +00:00
|
|
|
int delta = 0;
|
2015-01-12 09:45:41 +00:00
|
|
|
if (ds->show_reloff) {
|
2015-01-18 02:02:56 +00:00
|
|
|
RAnalFunction *f = r_anal_get_fcn_at (core->anal,
|
|
|
|
ds->at, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (f) {
|
|
|
|
delta = ds->at - f->addr;
|
2016-03-29 00:03:17 +00:00
|
|
|
sfi.name = f->name;
|
2015-01-18 02:02:56 +00:00
|
|
|
sfi.offset = f->addr;
|
|
|
|
ds->lastflag = &sfi;
|
|
|
|
} else {
|
|
|
|
fi = r_flag_get_i (core->flags, ds->at);
|
|
|
|
if (fi) ds->lastflag = fi;
|
|
|
|
if (ds->lastflag) {
|
|
|
|
if (ds->lastflag->offset == ds->at) {
|
|
|
|
delta = 0;
|
|
|
|
} else {
|
|
|
|
delta = ds->at - ds->lastflag->offset;
|
|
|
|
}
|
2015-01-12 09:45:41 +00:00
|
|
|
} else {
|
2015-01-18 02:02:56 +00:00
|
|
|
delta = ds->at - core->offset;
|
2015-01-12 09:45:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-22 04:39:52 +00:00
|
|
|
r_print_offset (core->print, ds->at, (ds->at==ds->dest),
|
2015-01-11 23:11:06 +00:00
|
|
|
ds->show_offseg, delta);
|
|
|
|
}
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->atabsoff > 0) {
|
|
|
|
if (ds->_tabsoff != ds->atabsoff) {
|
|
|
|
char *b = ds->_tabsbuf;
|
|
|
|
// TODO optimize to avoid down resizing
|
|
|
|
b = malloc (ds->atabsoff + 1);
|
|
|
|
if (b) {
|
|
|
|
memset (b, ' ', ds->atabsoff);
|
|
|
|
b[ds->atabsoff] = 0;
|
|
|
|
free (ds->_tabsbuf);
|
|
|
|
ds->_tabsbuf = b;
|
|
|
|
ds->_tabsoff = ds->atabsoff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r_cons_strcat (ds->_tabsbuf);
|
2015-07-15 15:30:34 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_op_size(RCore *core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_size)
|
|
|
|
r_cons_printf ("%d ", ds->analop.size);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_trace(RCore *core, RDisasmState *ds) {
|
2014-11-02 02:06:52 +00:00
|
|
|
RDebugTracepoint *tp = NULL;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_trace) {
|
2014-11-02 02:06:52 +00:00
|
|
|
tp = r_debug_trace_get (core->dbg, ds->at);
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("%02x:%04x ", tp?tp->times:0, tp?tp->count:0);
|
2014-11-02 02:06:52 +00:00
|
|
|
}
|
|
|
|
if (ds->tracespace) {
|
|
|
|
char spaces [32];
|
|
|
|
int times;
|
|
|
|
if (!tp)
|
|
|
|
tp = r_debug_trace_get (core->dbg, ds->at);
|
|
|
|
if (tp) {
|
|
|
|
times = R_MIN (tp->times, 30); // limit to 30
|
2014-11-02 01:19:31 +00:00
|
|
|
memset (spaces, ' ', sizeof (spaces));
|
|
|
|
spaces[times] = 0;
|
|
|
|
r_cons_strcat (spaces);
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_adistrick_comments(RCore *core, RDisasmState *ds) {
|
2015-11-06 14:46:14 +00:00
|
|
|
if (ds->adistrick) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->middle = r_anal_reflines_middle (core->anal,
|
2015-09-08 21:21:35 +00:00
|
|
|
core->anal->reflines, ds->at, ds->analop.size);
|
2015-11-06 14:46:14 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static int handle_print_meta_infos(RCore * core, RDisasmState *ds, ut8* buf, int len, int idx) {
|
2014-03-08 01:36:33 +00:00
|
|
|
int ret = 0;
|
|
|
|
const char *infos, *metas;
|
2015-06-15 08:55:05 +00:00
|
|
|
char key[100];
|
2014-03-08 01:36:33 +00:00
|
|
|
RAnalMetaItem MI, *mi = &MI;
|
|
|
|
Sdb *s = core->anal->sdb_meta;
|
|
|
|
|
|
|
|
snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, ds->at);
|
|
|
|
infos = sdb_const_get (s, key, 0);
|
|
|
|
if (infos)
|
|
|
|
for (;*infos; infos++) {
|
2015-06-15 08:55:05 +00:00
|
|
|
/* XXX wtf, must use anal.meta.deserialize() */
|
|
|
|
char *p, *q;
|
2014-03-08 01:36:33 +00:00
|
|
|
if (*infos==',')
|
|
|
|
continue;
|
|
|
|
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, *infos, ds->at);
|
|
|
|
metas = sdb_const_get (s, key, 0);
|
|
|
|
MI.size = sdb_array_get_num (s, key, 0, 0);
|
|
|
|
MI.type = *infos;
|
|
|
|
MI.from = ds->at;
|
|
|
|
MI.to = ds->at + MI.size;
|
2015-06-15 08:55:05 +00:00
|
|
|
if (metas) {
|
|
|
|
p = strchr (metas, ',');
|
|
|
|
if (!p) {
|
|
|
|
continue;
|
|
|
|
}
|
2016-04-08 00:56:42 +00:00
|
|
|
MI.space = atoi (p + 1);
|
|
|
|
q = strchr (p + 1, ',');
|
2015-06-15 08:55:05 +00:00
|
|
|
if (!q) {
|
|
|
|
continue;
|
|
|
|
}
|
2016-04-08 00:56:42 +00:00
|
|
|
MI.str = (char*)sdb_decode (q + 1, 0);
|
2014-03-08 01:36:33 +00:00
|
|
|
} else MI.str = NULL;
|
|
|
|
// sdb-get blah
|
|
|
|
// TODO: implement ranged meta find (if not at the begging of function..
|
|
|
|
#if 0
|
|
|
|
RAnalMetaItem *mi = r_meta_find (core->anal, ds->at,
|
|
|
|
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
|
|
|
#endif
|
|
|
|
char *out = NULL;
|
|
|
|
int hexlen;
|
|
|
|
int delta;
|
|
|
|
ds->mi_found = 0;
|
|
|
|
if (mi) {
|
|
|
|
switch (mi->type) {
|
|
|
|
case R_META_TYPE_STRING:
|
2015-11-02 11:38:08 +00:00
|
|
|
{
|
2014-03-08 01:36:33 +00:00
|
|
|
out = r_str_escape (mi->str);
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf (" .string %s\"%s\"%s ; len=%"PFMT64d,
|
|
|
|
COLOR_CONST (ds, YELLOW), out, COLOR_RESET (ds),
|
|
|
|
mi->size);
|
2014-03-08 01:36:33 +00:00
|
|
|
free (out);
|
|
|
|
delta = ds->at-mi->from;
|
|
|
|
ds->oplen = mi->size-delta;
|
|
|
|
ds->asmop.size = (int)mi->size;
|
|
|
|
//i += mi->size-1; // wtf?
|
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
ds->line = ds->refline = ds->refline2 = NULL;
|
|
|
|
ds->mi_found = 1;
|
|
|
|
break;
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-03-08 01:36:33 +00:00
|
|
|
case R_META_TYPE_HIDE:
|
2015-02-04 01:02:33 +00:00
|
|
|
r_cons_printf ("(%d bytes hidden)", mi->size);
|
2014-03-08 01:36:33 +00:00
|
|
|
ds->asmop.size = mi->size;
|
|
|
|
ds->oplen = mi->size;
|
|
|
|
ds->mi_found = 1;
|
|
|
|
break;
|
|
|
|
case R_META_TYPE_DATA:
|
|
|
|
hexlen = len - idx;
|
|
|
|
delta = ds->at-mi->from;
|
|
|
|
if (mi->size<hexlen) hexlen = mi->size;
|
|
|
|
ds->oplen = mi->size;
|
|
|
|
core->print->flags &= ~R_PRINT_FLAGS_HEADER;
|
2014-09-03 08:25:29 +00:00
|
|
|
switch (mi->size) {
|
|
|
|
case 1:
|
2014-12-21 03:18:56 +00:00
|
|
|
r_cons_printf (".byte 0x%02x", buf[idx]);
|
2014-09-03 08:25:29 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
{
|
2016-04-26 09:09:15 +00:00
|
|
|
ut16 data = r_read_ble16(buf+idx, core->print->big_endian);
|
|
|
|
r_cons_printf (".word 0x%04x", data);
|
2014-09-03 08:25:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
{
|
2016-04-26 09:09:15 +00:00
|
|
|
ut32 data = r_read_ble32(buf+idx, core->print->big_endian);
|
|
|
|
r_cons_printf (".dword 0x%08x", data);
|
2016-02-16 01:50:02 +00:00
|
|
|
{
|
2016-04-26 09:09:15 +00:00
|
|
|
RFlagItem *fi = r_flag_get_i (core->flags, data);
|
2016-02-16 01:50:02 +00:00
|
|
|
if (fi) r_cons_printf (" ; %s", fi->name);
|
|
|
|
}
|
2014-09-03 08:25:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
{
|
2016-04-26 09:09:15 +00:00
|
|
|
ut64 data = r_read_ble64(buf+idx, core->print->big_endian);
|
|
|
|
r_cons_printf (".qword 0x%016"PFMT64x, data);
|
2016-02-16 01:50:02 +00:00
|
|
|
{
|
2016-04-26 09:09:15 +00:00
|
|
|
RFlagItem *fi = r_flag_get_i (core->flags, data);
|
2016-02-16 01:50:02 +00:00
|
|
|
if (fi) r_cons_printf (" ; %s", fi->name);
|
|
|
|
}
|
2014-09-03 08:25:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_cons_printf ("hex length=%lld delta=%d\n", mi->size , delta);
|
|
|
|
r_print_hexdump (core->print, ds->at, buf+idx, hexlen-delta, 16, 1);
|
|
|
|
break;
|
|
|
|
}
|
2014-03-08 01:36:33 +00:00
|
|
|
core->inc = 16;
|
|
|
|
core->print->flags |= R_PRINT_FLAGS_HEADER;
|
|
|
|
ds->asmop.size = ret = (int)mi->size; //-delta;
|
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
ds->line = ds->refline = ds->refline2 = NULL;
|
|
|
|
ds->mi_found = 1;
|
|
|
|
break;
|
|
|
|
case R_META_TYPE_FORMAT:
|
|
|
|
r_cons_printf ("format %s {\n", mi->str);
|
2015-11-24 09:47:57 +00:00
|
|
|
r_print_format (core->print, ds->at, buf+idx, len-idx, mi->str, R_PRINT_MUSTSEE, NULL, NULL);
|
|
|
|
r_cons_printf ("} %d", mi->size);
|
2014-09-03 08:25:29 +00:00
|
|
|
ds->oplen = ds->asmop.size = ret = (int)mi->size;
|
2014-03-08 01:36:33 +00:00
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
ds->line = ds->refline = ds->refline2 = NULL;
|
|
|
|
ds->mi_found = 1;
|
|
|
|
break;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-05-04 15:21:05 +00:00
|
|
|
if (MI.str) {
|
|
|
|
free (MI.str);
|
|
|
|
MI.str = NULL;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_instruction_mov_lea(RCore *core, RDisasmState *ds, int idx) {
|
2014-01-16 17:04:42 +00:00
|
|
|
RAnalValue *src;
|
2014-01-20 00:42:16 +00:00
|
|
|
switch (ds->analop.type) {
|
2015-03-23 23:08:48 +00:00
|
|
|
case R_ANAL_OP_TYPE_LENGTH:
|
|
|
|
case R_ANAL_OP_TYPE_CAST:
|
2015-10-18 20:14:06 +00:00
|
|
|
case R_ANAL_OP_TYPE_CMOV:
|
2014-01-16 17:04:42 +00:00
|
|
|
case R_ANAL_OP_TYPE_MOV:
|
2014-01-20 00:42:16 +00:00
|
|
|
src = ds->analop.src[0];
|
2014-01-16 17:04:42 +00:00
|
|
|
if (src && src->memref>0 && src->reg) {
|
2014-07-30 20:41:54 +00:00
|
|
|
if (core->anal->reg) {
|
2014-01-16 17:04:42 +00:00
|
|
|
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
|
2014-01-20 00:42:16 +00:00
|
|
|
RAnalValue *dst = ds->analop.dst;
|
2014-01-16 17:04:42 +00:00
|
|
|
if (dst && dst->reg && dst->reg->name)
|
|
|
|
if (!strcmp (src->reg->name, pc)) {
|
|
|
|
RFlagItem *item;
|
|
|
|
ut8 b[8];
|
2014-01-20 00:42:16 +00:00
|
|
|
ut64 ptr = idx+ds->addr+src->delta+ds->analop.size;
|
2014-01-16 17:04:42 +00:00
|
|
|
ut64 off = 0LL;
|
|
|
|
r_core_read_at (core, ptr, b, src->memref);
|
2016-04-26 09:09:15 +00:00
|
|
|
off = r_mem_get_num (b, src->memref);
|
2014-01-16 17:04:42 +00:00
|
|
|
item = r_flag_get_i (core->flags, off);
|
|
|
|
r_cons_printf ("; MOV %s = [0x%"PFMT64x"] = 0x%"PFMT64x" %s\n",
|
|
|
|
dst->reg->name, ptr, off, item?item->name: "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
// TODO: get from meta anal?
|
|
|
|
case R_ANAL_OP_TYPE_LEA:
|
2014-01-20 00:42:16 +00:00
|
|
|
src = ds->analop.src[0];
|
2014-05-22 11:21:34 +00:00
|
|
|
if (src && src->reg && core->anal->reg && *(core->anal->reg->name)) {
|
2014-01-16 17:04:42 +00:00
|
|
|
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
|
2014-01-20 00:42:16 +00:00
|
|
|
RAnalValue *dst = ds->analop.dst;
|
2014-01-16 17:04:42 +00:00
|
|
|
if (dst && dst->reg && !strcmp (src->reg->name, pc)) {
|
2014-01-18 00:55:03 +00:00
|
|
|
int index = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
int memref = core->assembler->bits/8;
|
|
|
|
RFlagItem *item;
|
|
|
|
ut8 b[64];
|
2014-01-20 00:42:16 +00:00
|
|
|
ut64 ptr = index+ds->addr+src->delta+ds->analop.size;
|
2014-01-16 17:04:42 +00:00
|
|
|
ut64 off = 0LL;
|
|
|
|
r_core_read_at (core, ptr, b, sizeof (b)); //memref);
|
2016-04-26 09:09:15 +00:00
|
|
|
off = r_mem_get_num (b, memref);
|
2014-01-16 17:04:42 +00:00
|
|
|
item = r_flag_get_i (core->flags, off);
|
|
|
|
{
|
|
|
|
char s[64];
|
|
|
|
r_str_ncpy (s, (const char *)b, sizeof (s));
|
|
|
|
r_cons_printf ("; LEA %s = [0x%"PFMT64x"] = 0x%"PFMT64x" \"%s\"\n",
|
|
|
|
dst->reg->name, ptr, off, item?item->name: s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_show_bytes(RCore * core, RDisasmState *ds) {
|
2014-10-15 23:51:48 +00:00
|
|
|
char *nstr, *str = NULL, pad[64];
|
2015-01-17 00:56:20 +00:00
|
|
|
char *flagstr = NULL;
|
2014-10-15 23:51:48 +00:00
|
|
|
char extra[64];
|
|
|
|
int j,k;
|
|
|
|
if (!ds->show_bytes)
|
|
|
|
return;
|
2015-04-06 22:31:35 +00:00
|
|
|
if (ds->nb<1)
|
|
|
|
return;
|
2014-10-15 23:51:48 +00:00
|
|
|
strcpy (extra, " ");
|
2015-01-17 00:56:20 +00:00
|
|
|
if (ds->show_flag_in_bytes) {
|
|
|
|
flagstr = r_flag_get_liststr (core->flags, ds->at);
|
|
|
|
}
|
|
|
|
if (flagstr) {
|
|
|
|
str = flagstr;
|
2015-10-30 02:07:22 +00:00
|
|
|
if (ds->nb > 0) {
|
2015-04-06 22:31:35 +00:00
|
|
|
k = ds->nb-strlen (flagstr)-1;
|
|
|
|
if (k<0) k = 0;
|
|
|
|
for (j=0; j<k; j++)
|
|
|
|
pad[j] = ' ';
|
|
|
|
pad[j] = '\0';
|
|
|
|
} else pad[0] = 0;
|
2014-10-15 23:51:48 +00:00
|
|
|
} else {
|
|
|
|
if (ds->show_flag_in_bytes) {
|
|
|
|
k = ds->nb-1;
|
2015-04-06 22:31:35 +00:00
|
|
|
if (k<0) k = 0;
|
2014-10-15 23:51:48 +00:00
|
|
|
for (j=0; j<k; j++)
|
|
|
|
pad[j] = ' ';
|
|
|
|
pad[j] = '\0';
|
|
|
|
str = strdup ("");
|
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
str = strdup (ds->asmop.buf_hex);
|
|
|
|
if (r_str_ansi_len (str) > ds->nb) {
|
|
|
|
char *p = (char *)r_str_ansi_chrn (str, ds->nb);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (p) {
|
|
|
|
p[0] = '.';
|
|
|
|
p[1] = '\0';
|
|
|
|
}
|
|
|
|
}
|
2014-02-25 00:35:23 +00:00
|
|
|
ds->p->cur_enabled = (ds->cursor != -1);
|
|
|
|
nstr = r_print_hexpair (ds->p, str, ds->index);
|
|
|
|
if (ds->p->bytespace) {
|
2016-01-08 00:23:33 +00:00
|
|
|
k = (ds->nb + (ds->nb / 2)) - r_str_ansi_len (nstr) + 2;
|
2014-02-25 00:35:23 +00:00
|
|
|
} else {
|
2015-04-08 20:28:21 +00:00
|
|
|
k = ds->nb - r_str_ansi_len (nstr)+1;
|
2014-02-25 00:35:23 +00:00
|
|
|
}
|
2016-01-08 00:23:33 +00:00
|
|
|
if (k > 0) {
|
|
|
|
for (j = 0; j < k; j++) {
|
2015-04-06 22:31:35 +00:00
|
|
|
pad[j] = ' ';
|
2016-01-08 00:23:33 +00:00
|
|
|
}
|
2015-04-06 22:31:35 +00:00
|
|
|
pad[j] = 0;
|
|
|
|
if (ds->lbytes) {
|
|
|
|
// hack to align bytes left
|
|
|
|
strcpy (extra, pad);
|
|
|
|
*pad = 0;
|
|
|
|
}
|
2015-04-08 20:28:21 +00:00
|
|
|
} else {
|
|
|
|
pad[0] = 0;
|
|
|
|
}
|
2014-02-25 00:35:23 +00:00
|
|
|
free (str);
|
|
|
|
str = nstr;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-11-27 13:09:37 +00:00
|
|
|
r_cons_printf ("%s%s %s"Color_RESET, pad, str, extra);
|
2015-11-02 11:38:08 +00:00
|
|
|
} else {
|
2015-11-27 13:09:37 +00:00
|
|
|
r_cons_printf ("%s%s %s", pad, str, extra);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-10-15 23:51:48 +00:00
|
|
|
free (str);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_indent(RCore *core, RDisasmState *ds) {
|
2014-08-05 03:37:48 +00:00
|
|
|
if (ds->show_indent) {
|
|
|
|
char indent[128];
|
2015-08-12 08:40:24 +00:00
|
|
|
int num = ds->indent_level * ds->indent_space;
|
2015-12-21 14:53:53 +00:00
|
|
|
if (num < 0) num = 0;
|
|
|
|
if (num >= sizeof (indent))
|
2014-08-05 03:37:48 +00:00
|
|
|
num = sizeof(indent)-1;
|
2014-08-17 18:30:28 +00:00
|
|
|
memset (indent, ' ', num);
|
2014-08-05 03:37:48 +00:00
|
|
|
indent[num] = 0;
|
|
|
|
r_cons_strcat (indent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_opstr(RCore *core, RDisasmState *ds) {
|
2014-08-05 03:37:48 +00:00
|
|
|
handle_print_indent (core, ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
r_cons_strcat (ds->opstr);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_color_reset(RCore *core, RDisasmState *ds) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) r_cons_strcat (Color_RESET);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2015-10-30 02:07:22 +00:00
|
|
|
static int handle_print_middle(RCore *core, RDisasmState *ds, int ret) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->middle != 0) {
|
|
|
|
ret -= ds->middle;
|
2014-11-13 02:59:51 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
2015-11-05 01:07:20 +00:00
|
|
|
r_cons_printf (" ; *middle* %d", ret);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) r_cons_strcat (Color_RESET);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-30 02:07:22 +00:00
|
|
|
static bool handle_print_labels(RCore *core, RDisasmState *ds, RAnalFunction *f) {
|
2014-09-23 07:35:37 +00:00
|
|
|
const char *label;
|
2015-10-30 02:07:22 +00:00
|
|
|
if (!core || !ds) return false;
|
|
|
|
if (!f) f = r_anal_get_fcn_in (core->anal, ds->at, 0);
|
2014-09-23 07:35:37 +00:00
|
|
|
label = r_anal_fcn_label_at (core->anal, f, ds->at);
|
2015-10-30 02:07:22 +00:00
|
|
|
if (!label)
|
|
|
|
return false;
|
|
|
|
if (ds->show_color) {
|
|
|
|
r_cons_strcat (ds->color_label);
|
|
|
|
r_cons_printf (" .%s:\n", label);
|
|
|
|
handle_print_color_reset (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
} else {
|
|
|
|
r_cons_printf (" .%s:\n", label);
|
|
|
|
}
|
2015-10-30 02:07:22 +00:00
|
|
|
return true;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_import_name(RCore * core, RDisasmState *ds) {
|
2014-04-02 20:30:39 +00:00
|
|
|
RListIter *iter = NULL;
|
|
|
|
RBinReloc *rel = NULL;
|
|
|
|
switch (ds->analop.type) {
|
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
|
|
|
if (core->bin->cur->o->imports && core->bin->cur->o->relocs) {
|
2014-11-23 23:16:36 +00:00
|
|
|
r_list_foreach (core->bin->cur->o->relocs, iter, rel) {
|
2014-05-21 01:18:00 +00:00
|
|
|
if ((rel->vaddr == ds->analop.jump) &&
|
2014-04-02 20:30:39 +00:00
|
|
|
(rel->import != NULL)) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2014-04-02 20:30:39 +00:00
|
|
|
r_cons_strcat (ds->color_fname);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-04-02 20:30:39 +00:00
|
|
|
// TODO: handle somehow ordinals import
|
2014-11-13 02:59:51 +00:00
|
|
|
handle_comment_align (core, ds);
|
2014-12-18 11:54:36 +00:00
|
|
|
r_cons_printf (" ; (imp.%s)", rel->import->name);
|
2014-04-02 20:30:39 +00:00
|
|
|
handle_print_color_reset (core, ds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_fcn_name(RCore * core, RDisasmState *ds) {
|
2015-05-13 23:17:35 +00:00
|
|
|
int delta;
|
|
|
|
const char *label;
|
2014-06-25 00:30:42 +00:00
|
|
|
RAnalFunction *f;
|
2014-11-18 22:53:27 +00:00
|
|
|
if (!ds->show_comments)
|
|
|
|
return;
|
2014-01-20 00:42:16 +00:00
|
|
|
switch (ds->analop.type) {
|
2015-05-13 23:17:35 +00:00
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
|
|
|
f = r_anal_get_fcn_in (core->anal,
|
|
|
|
ds->analop.jump, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (f && !strstr (ds->opstr, f->name)) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-05-13 23:17:35 +00:00
|
|
|
r_cons_strcat (ds->color_fname);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-05-13 23:17:35 +00:00
|
|
|
//beginline (core, ds, f);
|
|
|
|
// print label
|
|
|
|
delta = ds->analop.jump - f->addr;
|
|
|
|
label = r_anal_fcn_label_at (core->anal, f, ds->analop.jump);
|
|
|
|
if (label) {
|
2016-03-13 02:13:27 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-05-13 23:17:35 +00:00
|
|
|
r_cons_printf (" ; %s.%s", f->name, label);
|
|
|
|
} else {
|
|
|
|
RAnalFunction *f2 = r_anal_get_fcn_in (core->anal, ds->at, 0);
|
|
|
|
if (f != f2) {
|
2016-03-13 02:13:27 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-05-13 23:17:35 +00:00
|
|
|
if (delta>0) {
|
|
|
|
r_cons_printf (" ; %s+0x%x", f->name, delta);
|
|
|
|
} else if (delta<0) {
|
|
|
|
r_cons_printf (" ; %s-0x%x", f->name, -delta);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; %s", f->name);
|
2015-04-11 23:28:26 +00:00
|
|
|
}
|
2015-04-11 23:06:10 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-05-13 23:17:35 +00:00
|
|
|
handle_print_color_reset (core, ds);
|
|
|
|
}
|
|
|
|
break;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
|
2015-10-08 18:00:31 +00:00
|
|
|
static void handle_print_core_vmode(RCore *core, RDisasmState *ds) {
|
2016-05-12 10:29:00 +00:00
|
|
|
char *shortcut = NULL;
|
2015-10-08 18:00:31 +00:00
|
|
|
|
2016-01-27 01:25:25 +00:00
|
|
|
if (!ds->show_jmphints) return;
|
2014-01-16 17:04:42 +00:00
|
|
|
if (core->vmode) {
|
2014-01-20 00:42:16 +00:00
|
|
|
switch (ds->analop.type) {
|
2014-01-16 17:04:42 +00:00
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
2014-09-22 15:00:18 +00:00
|
|
|
case R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_CALL:
|
2014-11-13 02:59:51 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-10-08 18:00:31 +00:00
|
|
|
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
2016-05-12 10:29:00 +00:00
|
|
|
shortcut = r_core_add_asmqjmp (core, ds->analop.jump);
|
|
|
|
if (shortcut) {
|
|
|
|
r_cons_printf (" ;[%s]", shortcut);
|
|
|
|
free (shortcut);
|
2015-10-08 18:00:31 +00:00
|
|
|
} else {
|
|
|
|
r_cons_strcat (" ;[?]");
|
|
|
|
}
|
|
|
|
if (ds->show_color) r_cons_strcat (Color_RESET);
|
2014-01-16 17:04:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-23 23:58:03 +00:00
|
|
|
// modifies anal register state
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_cc_update(RCore *core, RDisasmState *ds) {
|
2014-01-16 17:04:42 +00:00
|
|
|
// declare static since this variable is reused locally, and needs to maintain
|
|
|
|
// state
|
|
|
|
static RAnalCC cc = {0};
|
2015-11-23 23:58:03 +00:00
|
|
|
if (!ds->show_comments || !ds->show_fcncalls)
|
2015-01-28 16:05:18 +00:00
|
|
|
return;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!r_anal_cc_update (core->anal, &cc, &ds->analop)) {
|
|
|
|
if (ds->show_functions) {
|
2014-09-26 13:40:17 +00:00
|
|
|
RAnalFunction *f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
2014-01-16 17:04:42 +00:00
|
|
|
char tmp[128];
|
|
|
|
char *ccstr = r_anal_cc_to_string (core->anal, &cc);
|
|
|
|
tmp[0] = 0;
|
2014-01-20 00:42:16 +00:00
|
|
|
r_anal_cc_update (core->anal, &cc, &ds->analop);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (ccstr) {
|
|
|
|
RFlagItem *flag = r_flag_get_at (core->flags, cc.jump);
|
|
|
|
if (flag && ccstr) {
|
|
|
|
int delta = 0;
|
|
|
|
if (f) { delta = cc.jump-flag->offset; }
|
|
|
|
if (!strncmp (flag->name, ccstr, strlen (flag->name))) {
|
|
|
|
if (ccstr[strlen (flag->name)] == '(') {
|
|
|
|
tmp[0] = 0;
|
|
|
|
} else {
|
|
|
|
if (delta)
|
2014-11-23 23:16:36 +00:00
|
|
|
snprintf (tmp, sizeof (tmp)-1, " ; %s+%d", flag->name, delta);
|
|
|
|
else snprintf (tmp, sizeof (tmp)-1, " ; %s", flag->name);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (delta)
|
2014-11-23 23:16:36 +00:00
|
|
|
snprintf (tmp, sizeof (tmp)-1, " ; %s+%d", flag->name, delta);
|
|
|
|
else snprintf (tmp, sizeof (tmp)-1, " ; %s", flag->name);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2015-06-04 22:19:41 +00:00
|
|
|
|
|
|
|
if (ds->show_calls) {
|
|
|
|
const char *sn = ds->show_section? getSectionName (core, ds->at): "";
|
|
|
|
int cmtright = ds->show_comment_right;
|
2015-06-04 22:45:42 +00:00
|
|
|
if (core->cons->columns < 120) {
|
|
|
|
cmtright = 0;
|
|
|
|
}
|
2015-06-04 22:19:41 +00:00
|
|
|
// if doesnt fits in screen newline
|
|
|
|
if (cmtright) {
|
2015-06-29 09:37:18 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf (" %s%s; %s%s%s", COLOR_RESET (ds),
|
|
|
|
COLOR (ds, pal_comment), ccstr, tmp, COLOR_RESET (ds));
|
2015-06-04 22:19:41 +00:00
|
|
|
} else {
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("\n%s%s%s%s%s %s^-%s %s%s%s",
|
|
|
|
COLOR (ds, color_fline), ds->pre, COLOR (ds, color_flow),
|
|
|
|
sn, ds->refline, COLOR_RESET (ds), COLOR (ds, pal_comment),
|
|
|
|
ccstr, tmp, COLOR_RESET (ds));
|
2015-06-04 22:19:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
free (ccstr);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (f) {
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
|
|
|
ds->pre = r_str_concat (ds->pre, " ");
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-12-16 12:51:34 +00:00
|
|
|
handle_set_pre (ds, " ");
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r_anal_cc_reset (&cc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-13 02:36:48 +00:00
|
|
|
// align for comment
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_comment_align(RCore *core, RDisasmState *ds) {
|
2014-11-13 02:36:48 +00:00
|
|
|
const int cmtcol = ds->cmtcol;
|
2016-03-03 23:33:24 +00:00
|
|
|
if (ds->show_comment_right_default) {
|
2016-03-13 02:13:27 +00:00
|
|
|
char *ll = r_cons_lastline ();
|
|
|
|
if (ll) {
|
|
|
|
int cstrlen = strlen (ll);
|
|
|
|
int cols, ansilen = r_str_ansi_len (ll);
|
|
|
|
int utf8len = r_utf8_strlen ((const ut8*)ll);
|
2015-05-21 01:42:00 +00:00
|
|
|
|
2016-03-13 02:13:27 +00:00
|
|
|
int cells = utf8len - (cstrlen-ansilen);
|
2015-05-21 01:42:00 +00:00
|
|
|
|
2016-03-13 02:13:27 +00:00
|
|
|
cols = ds->interactive ? core->cons->columns : 1024;
|
|
|
|
//cols = r_cons_get_size (NULL);
|
|
|
|
if (cmtcol+16>=cols) {
|
2014-11-13 02:59:51 +00:00
|
|
|
#if 0
|
2016-03-13 02:13:27 +00:00
|
|
|
r_cons_newline ();
|
|
|
|
r_cons_memset (' ', 10);
|
2014-11-13 02:59:51 +00:00
|
|
|
#endif
|
2016-03-13 02:13:27 +00:00
|
|
|
int len = cmtcol - cells;
|
2015-05-21 01:42:00 +00:00
|
|
|
r_cons_memset (' ', len);
|
2016-03-13 02:13:27 +00:00
|
|
|
} else if (cells < cmtcol) {
|
|
|
|
int len = cmtcol - cells;
|
|
|
|
if (len < cols)
|
|
|
|
r_cons_memset (' ', len);
|
|
|
|
}
|
2014-11-13 02:36:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_dwarf(RCore *core, RDisasmState *ds) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->show_dwarf) {
|
2014-03-10 01:27:32 +00:00
|
|
|
ds->sl = r_bin_addr2text (core->bin, ds->at);
|
2014-01-20 00:42:16 +00:00
|
|
|
int len = strlen (ds->opstr);
|
2015-10-29 11:37:14 +00:00
|
|
|
if (len<30) len = 30 - len;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->sl) {
|
|
|
|
if ((!ds->osl || (ds->osl && strcmp (ds->sl, ds->osl)))) {
|
2014-11-25 01:07:01 +00:00
|
|
|
char *line = strdup (ds->sl);
|
|
|
|
r_str_replace_char (line, '\t', ' ');
|
|
|
|
r_str_replace_char (line, '\x1b', ' ');
|
|
|
|
r_str_replace_char (line, '\r', ' ');
|
|
|
|
r_str_replace_char (line, '\n', '\x00');
|
2014-12-18 11:54:36 +00:00
|
|
|
// handle_set_pre (ds, " ");
|
2014-11-13 02:36:48 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-10-29 11:37:14 +00:00
|
|
|
r_cons_printf ("%s ; %s"Color_RESET, ds->pal_comment, line);
|
2015-11-02 11:38:08 +00:00
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; %s", line);
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->osl);
|
|
|
|
ds->osl = ds->sl;
|
|
|
|
ds->sl = NULL;
|
2014-11-25 01:07:01 +00:00
|
|
|
free (line);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_asmop_payload(RCore *core, RDisasmState *ds) {
|
2015-01-11 03:29:15 +00:00
|
|
|
if (ds->varxs) {
|
|
|
|
// XXX asume analop is filled
|
|
|
|
//r_anal_op (core->anal, &ds->analop, ds->at, core->block+i, core->blocksize-i);
|
|
|
|
int v = ds->analop.ptr;
|
|
|
|
switch (ds->analop.stackop) {
|
2015-11-05 01:07:20 +00:00
|
|
|
case R_ANAL_STACK_GET:
|
|
|
|
if (v<0) {
|
|
|
|
r_cons_printf (" ; local.get %d", -v);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; arg.get %d", v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case R_ANAL_STACK_SET:
|
|
|
|
if (v<0) {
|
|
|
|
r_cons_printf (" ; local.set %d", -v);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; arg.set %d", v);
|
|
|
|
}
|
|
|
|
break;
|
2015-01-11 03:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->asmop.payload != 0)
|
|
|
|
r_cons_printf ("\n; .. payload of %d bytes", ds->asmop.payload);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_op_push_info(RCore *core, RDisasmState *ds){
|
2014-01-20 00:42:16 +00:00
|
|
|
switch (ds->analop.type) {
|
2014-01-16 17:04:42 +00:00
|
|
|
case R_ANAL_OP_TYPE_PUSH:
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->analop.val) {
|
|
|
|
RFlagItem *flag = r_flag_get_i (core->flags, ds->analop.val);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (flag) r_cons_printf (" ; %s", flag->name);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void comment_newline(RCore *core, RDisasmState *ds) {
|
2015-06-04 23:00:41 +00:00
|
|
|
const char *sn;
|
2015-11-02 11:38:08 +00:00
|
|
|
|
|
|
|
if (ds->show_comment_right) return;
|
|
|
|
sn = ds->show_section ? getSectionName (core, ds->at) : "";
|
2015-06-04 23:00:41 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("\n%s%s%s%s%s ^- %s", COLOR (ds, color_fline),
|
|
|
|
ds->pre, sn, ds->refline, COLOR_RESET (ds),
|
|
|
|
COLOR (ds, pal_comment));
|
2015-06-04 23:00:41 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-09-05 12:52:21 +00:00
|
|
|
/* convert numeric value in opcode to ascii char or number */
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_ptr(RCore *core, RDisasmState *ds, int len, int idx) {
|
2014-09-04 22:11:28 +00:00
|
|
|
ut64 p = ds->analop.ptr;
|
2014-11-18 23:26:26 +00:00
|
|
|
int aligned = 0;
|
|
|
|
#define DOALIGN() if (!aligned) { handle_comment_align (core, ds); aligned = 1; }
|
2014-11-18 22:48:25 +00:00
|
|
|
if (!ds->show_comments)
|
|
|
|
return;
|
2015-08-26 01:27:34 +00:00
|
|
|
if (!ds->show_slow) {
|
|
|
|
return;
|
|
|
|
}
|
2014-11-06 23:41:29 +00:00
|
|
|
if (p == UT64_MAX) {
|
|
|
|
/* do nothing */
|
|
|
|
} else if (((st64)p)>0) {
|
|
|
|
const char *kind;
|
2015-02-02 23:31:51 +00:00
|
|
|
char *msg = calloc(sizeof(char), len);
|
2015-07-15 14:45:24 +00:00
|
|
|
RFlagItem *f, *f2;
|
2014-11-06 23:41:29 +00:00
|
|
|
|
2015-02-02 23:31:51 +00:00
|
|
|
r_io_read_at (core->io, p, (ut8*)msg, len-1);
|
2014-11-06 23:41:29 +00:00
|
|
|
|
|
|
|
if (ds->analop.refptr) {
|
2016-04-26 09:09:15 +00:00
|
|
|
ut64 num = r_read_le64 (msg);
|
2014-11-06 23:41:29 +00:00
|
|
|
// TODO: make this more complete
|
|
|
|
switch (ds->analop.refptr) {
|
2016-05-04 15:13:44 +00:00
|
|
|
case 1: num &= UT8_MAX; break;
|
|
|
|
case 2: num &= UT16_MAX; break;
|
|
|
|
case 4: num &= UT32_MAX; break;
|
|
|
|
case 8: num &= UT64_MAX; break;
|
2014-11-06 23:41:29 +00:00
|
|
|
}
|
2016-05-04 15:13:44 +00:00
|
|
|
st64 n = (st64)num;
|
|
|
|
st32 n32 = (st32)(n & UT32_MAX);
|
2014-11-13 02:36:48 +00:00
|
|
|
handle_comment_align (core, ds);
|
2014-11-13 02:59:51 +00:00
|
|
|
if (ds->show_color) {
|
|
|
|
r_cons_printf (ds->pal_comment);
|
|
|
|
}
|
2015-04-03 15:25:07 +00:00
|
|
|
if (ds->analop.type == R_ANAL_OP_TYPE_LEA) {
|
2015-06-04 23:00:41 +00:00
|
|
|
comment_newline (core, ds);
|
2014-11-14 02:42:07 +00:00
|
|
|
const char *flag = "";
|
2015-04-03 15:25:07 +00:00
|
|
|
f = r_flag_get_i (core->flags, p);
|
2014-11-14 02:42:07 +00:00
|
|
|
if (f) flag = f->name;
|
2016-03-13 20:56:46 +00:00
|
|
|
r_cons_printf (" ; 0x%"PFMT64x"%s%s", p, *flag?" ; ":"", flag);
|
2015-04-03 15:25:07 +00:00
|
|
|
} else {
|
2015-07-17 09:33:16 +00:00
|
|
|
f = NULL;
|
2015-04-03 15:25:07 +00:00
|
|
|
if (n==UT32_MAX || n==UT64_MAX) {
|
2015-06-29 09:37:18 +00:00
|
|
|
r_cons_printf (" ; [0x%"PFMT64x":%d]=-1", p, ds->analop.refptr);
|
2015-04-03 15:25:07 +00:00
|
|
|
} else if (n == n32 && (n32>-512 && n32 <512)) {
|
2015-06-29 09:37:18 +00:00
|
|
|
r_cons_printf (" ; [0x%"PFMT64x":%d]=%"PFMT64d, p, ds->analop.refptr, n);
|
2015-04-03 15:25:07 +00:00
|
|
|
} else {
|
2015-07-08 16:46:35 +00:00
|
|
|
const char *kind, *flag = "";
|
|
|
|
char *msg2 = NULL;
|
2015-04-03 15:25:07 +00:00
|
|
|
f = r_flag_get_i (core->flags, n);
|
2015-07-08 16:46:35 +00:00
|
|
|
if (f) {
|
|
|
|
flag = f->name;
|
|
|
|
} else {
|
2015-07-15 14:45:24 +00:00
|
|
|
msg2 = calloc (sizeof (char), len);
|
2015-07-08 16:46:35 +00:00
|
|
|
r_io_read_at (core->io, n, (ut8*)msg2, len-1);
|
|
|
|
kind = r_anal_data_kind (core->anal, p, (const ut8*)msg2, len-1);
|
|
|
|
if (kind && !strcmp (kind, "text")) {
|
|
|
|
r_str_filter (msg2, 0);
|
|
|
|
if (*msg2) {
|
|
|
|
char *lala = r_str_newf ("\"%s\"", msg2);
|
|
|
|
free (msg2);
|
|
|
|
flag = msg2 = lala;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// try to guess what's in there
|
2016-03-13 23:15:51 +00:00
|
|
|
r_cons_printf (" ; [0x%"PFMT64x":%d]=0x%"PFMT64x"%s%s",
|
|
|
|
p, ds->analop.refptr, n, (flag&&*flag)?" ":"", flag);
|
2015-07-08 16:46:35 +00:00
|
|
|
free (msg2);
|
2015-04-03 15:25:07 +00:00
|
|
|
}
|
2015-07-15 14:45:24 +00:00
|
|
|
// not just for LEA
|
|
|
|
f2 = r_flag_get_i (core->flags, p);
|
|
|
|
if (f2 && f != f2) {
|
|
|
|
r_cons_printf (" LEA %s", f2->name);
|
|
|
|
}
|
2014-11-06 23:41:29 +00:00
|
|
|
}
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) r_cons_printf (Color_RESET);
|
2014-11-06 23:41:29 +00:00
|
|
|
}
|
2014-11-14 02:42:07 +00:00
|
|
|
#if 1
|
|
|
|
if (!IS_PRINTABLE (*msg))
|
|
|
|
*msg = 0;
|
2015-02-02 23:31:51 +00:00
|
|
|
else msg[len-1] = 0;
|
2014-11-14 02:42:07 +00:00
|
|
|
#endif
|
2014-09-04 22:11:28 +00:00
|
|
|
f = r_flag_get_i (core->flags, p);
|
2014-08-05 03:37:48 +00:00
|
|
|
if (f) {
|
2014-11-10 18:26:09 +00:00
|
|
|
r_str_filter (msg, 0);
|
2015-06-04 23:00:41 +00:00
|
|
|
comment_newline (core, ds);
|
2014-11-13 02:59:51 +00:00
|
|
|
if (ds->show_color) {
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-11-13 02:59:51 +00:00
|
|
|
r_cons_printf ("%s", ds->pal_comment);
|
|
|
|
}
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-11-10 18:26:09 +00:00
|
|
|
if (*msg) {
|
|
|
|
r_cons_printf (" ; \"%s\" @ 0x%"PFMT64x, msg, p);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; %s", f->name);
|
|
|
|
}
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) r_cons_printf (Color_RESET);
|
2014-08-05 03:37:48 +00:00
|
|
|
} else {
|
2014-09-04 22:11:28 +00:00
|
|
|
if (p==UT64_MAX || p==UT32_MAX) {
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-09-04 22:11:28 +00:00
|
|
|
r_cons_printf (" ; -1", p);
|
2016-04-22 08:36:30 +00:00
|
|
|
} else if (((char)p>0) && p>='!' && p<='~') {
|
|
|
|
char ch = p;
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2016-04-22 08:36:30 +00:00
|
|
|
r_cons_printf (" ; '%c'", ch);
|
2014-09-20 13:56:12 +00:00
|
|
|
} else if (p>10) {
|
2014-09-22 11:45:36 +00:00
|
|
|
if ((st64)p<0) {
|
|
|
|
// resolve local var if possible
|
|
|
|
RAnalVar *v = r_anal_var_get (core->anal, ds->at, 'v', 1, (int)p);
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-09-22 11:45:36 +00:00
|
|
|
if (v) {
|
2014-09-26 13:40:17 +00:00
|
|
|
r_cons_printf (" ; var %s", v->name);
|
2014-09-22 11:45:36 +00:00
|
|
|
r_anal_var_free (v);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; var %d", (int)-p);
|
|
|
|
}
|
|
|
|
} else {
|
2014-11-11 17:06:20 +00:00
|
|
|
if (r_core_anal_address (core, p) & R_ANAL_ADDR_TYPE_ASCII) {
|
|
|
|
r_str_filter (msg, 0);
|
2014-11-18 23:26:26 +00:00
|
|
|
if (*msg) {
|
|
|
|
DOALIGN();
|
2014-11-14 02:42:07 +00:00
|
|
|
r_cons_printf (" ; \"%s\" 0x%08"PFMT64x" ",
|
|
|
|
msg, p);
|
2014-11-18 23:26:26 +00:00
|
|
|
}
|
2014-11-11 17:06:20 +00:00
|
|
|
}
|
2014-11-10 18:26:09 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-02 23:31:51 +00:00
|
|
|
kind = r_anal_data_kind (core->anal, p, (const ut8*)msg, len-1);
|
2014-11-10 18:26:09 +00:00
|
|
|
if (kind) {
|
|
|
|
if (!strcmp (kind, "text")) {
|
|
|
|
r_str_filter (msg, 0);
|
|
|
|
if (*msg) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2014-11-13 02:59:51 +00:00
|
|
|
r_cons_printf (ds->pal_comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-11-10 18:26:09 +00:00
|
|
|
r_cons_printf (" ; \"%s\" @ 0x%"PFMT64x, msg, p);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2014-11-13 02:59:51 +00:00
|
|
|
r_cons_printf (Color_RESET);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-11-10 18:26:09 +00:00
|
|
|
}
|
|
|
|
} else if (!strcmp (kind, "invalid")){
|
|
|
|
int *n = (int*)&p;
|
2014-11-13 02:59:51 +00:00
|
|
|
if (*n>-0xfff && *n < 0xfff) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2014-11-13 02:59:51 +00:00
|
|
|
r_cons_printf (ds->pal_comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-11-18 23:26:26 +00:00
|
|
|
DOALIGN();
|
2014-11-10 18:26:09 +00:00
|
|
|
r_cons_printf (" ; %d", *n);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2014-11-13 02:59:51 +00:00
|
|
|
r_cons_printf (Color_RESET);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2014-11-13 02:59:51 +00:00
|
|
|
}
|
2014-11-10 18:26:09 +00:00
|
|
|
} else {
|
|
|
|
//r_cons_printf (" ; %s", kind);
|
2014-09-22 11:45:36 +00:00
|
|
|
}
|
2014-11-10 18:26:09 +00:00
|
|
|
// TODO: check for more data kinds
|
2014-09-04 22:11:28 +00:00
|
|
|
}
|
2014-08-05 03:37:48 +00:00
|
|
|
}
|
2015-03-05 23:56:10 +00:00
|
|
|
free (msg);
|
2014-07-18 16:24:38 +00:00
|
|
|
} else handle_print_as_string (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2014-11-03 15:24:04 +00:00
|
|
|
// TODO: Use sdb in rbin to accelerate this
|
|
|
|
// we shuold use aligned reloc addresses instead of iterating all of them
|
|
|
|
static RBinReloc *getreloc(RCore *core, ut64 addr, int size) {
|
|
|
|
RList *list;
|
|
|
|
RBinReloc *r;
|
|
|
|
RListIter *iter;
|
|
|
|
if (size<1 || addr == UT64_MAX) return NULL;
|
|
|
|
list = r_bin_get_relocs (core->bin);
|
|
|
|
#if 0
|
|
|
|
addr addr+size
|
|
|
|
|__._______|
|
|
|
|
|
|
|
|
|
reloc
|
|
|
|
#endif
|
|
|
|
r_list_foreach (list, iter, r) {
|
|
|
|
if ((r->vaddr >= addr) && (r->vaddr<(addr+size)))
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_relocs(RCore *core, RDisasmState *ds) {
|
2014-11-03 15:24:04 +00:00
|
|
|
RBinReloc *rel = getreloc (core, ds->at, ds->analop.size);
|
|
|
|
if (rel) {
|
2014-12-05 12:29:33 +00:00
|
|
|
if (rel->import)
|
2014-11-06 23:41:29 +00:00
|
|
|
r_cons_printf (" ; RELOC %d %s", rel->type, rel->import->name);
|
2014-11-04 11:17:27 +00:00
|
|
|
else if (rel->symbol)
|
2014-11-06 23:41:29 +00:00
|
|
|
r_cons_printf (" ; RELOC %d %s", rel->type, rel->symbol->name);
|
|
|
|
else r_cons_printf (" ; RELOC %d ", rel->type);
|
2014-11-03 15:24:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-09 22:34:21 +00:00
|
|
|
static int likely = 0;
|
2015-09-10 02:20:09 +00:00
|
|
|
static int show_slow = 0;
|
2016-01-14 23:17:15 +00:00
|
|
|
static int show_emu_str = 0;
|
2015-09-09 22:34:21 +00:00
|
|
|
|
2015-10-29 22:37:51 +00:00
|
|
|
static int mymemwrite0(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mymemwrite1(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-09-09 22:34:21 +00:00
|
|
|
static int myregwrite(RAnalEsil *esil, const char *name, ut64 val) {
|
2015-09-10 20:28:04 +00:00
|
|
|
char str[64], *msg = NULL;
|
2015-09-10 02:20:09 +00:00
|
|
|
ut32 *n32 = (ut32*)str;
|
2015-09-09 22:34:21 +00:00
|
|
|
likely = 1;
|
2015-09-10 02:20:09 +00:00
|
|
|
|
|
|
|
if (!show_slow) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset (str, 0, sizeof (str));
|
2015-09-10 20:28:04 +00:00
|
|
|
if (val != 0LL) {
|
2015-09-10 03:14:47 +00:00
|
|
|
RFlagItem *fi = r_flag_get_i (esil->anal->flb.f, val);
|
|
|
|
if (fi) {
|
|
|
|
strncpy (str, fi->name, sizeof (str)-1);
|
|
|
|
}
|
2015-09-14 14:22:57 +00:00
|
|
|
if (!str[0]) {
|
|
|
|
(void)r_io_read_at (esil->anal->iob.io, val, (ut8*)str, sizeof (str)-1);
|
2015-09-10 20:28:04 +00:00
|
|
|
str[sizeof (str)-1] = 0;
|
|
|
|
if (*str && r_str_is_printable (str)) {
|
|
|
|
// do nothing
|
|
|
|
msg = r_str_newf ("\"%s\"", str);
|
2015-09-10 03:14:47 +00:00
|
|
|
} else {
|
2015-09-10 20:28:04 +00:00
|
|
|
str[0] = 0;
|
|
|
|
if (*n32 == 0) {
|
2016-01-14 23:17:15 +00:00
|
|
|
// msg = strdup ("NULL");
|
2015-09-10 20:28:04 +00:00
|
|
|
} else if (*n32 == UT32_MAX) {
|
|
|
|
/* nothing */
|
|
|
|
} else {
|
2016-01-14 23:17:15 +00:00
|
|
|
if (!show_emu_str) {
|
|
|
|
msg = r_str_newf ("-> 0x%x", *n32);
|
|
|
|
}
|
2015-09-10 20:28:04 +00:00
|
|
|
}
|
2015-09-10 03:14:47 +00:00
|
|
|
}
|
2015-09-10 20:28:04 +00:00
|
|
|
} else {
|
|
|
|
msg = r_str_newf ("%s", str);
|
2015-09-10 03:14:47 +00:00
|
|
|
}
|
2015-09-10 02:20:09 +00:00
|
|
|
}
|
2016-01-14 23:17:15 +00:00
|
|
|
if (show_emu_str) {
|
|
|
|
if (msg && *msg) r_cons_printf ("; %s", msg);
|
|
|
|
} else {
|
|
|
|
r_cons_printf ("; %s=0x%"PFMT64x" %s", name, val, msg? msg: "");
|
|
|
|
}
|
2015-09-10 02:20:09 +00:00
|
|
|
free (msg);
|
2015-09-09 22:34:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-09-09 23:42:56 +00:00
|
|
|
// TODO: Move into ds-> after cleanup
|
|
|
|
static ut64 opc = UT64_MAX;
|
|
|
|
static ut8 *regstate = NULL;
|
|
|
|
|
|
|
|
static void handle_print_esil_anal_init(RCore *core, RDisasmState *ds) {
|
|
|
|
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
|
|
opc = r_reg_getv (core->anal->reg, pc);
|
2015-11-23 23:58:03 +00:00
|
|
|
if (!opc || opc==UT64_MAX) opc = core->offset;
|
2015-09-11 21:46:09 +00:00
|
|
|
if (!ds->show_emu) {
|
2015-09-09 23:42:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!core->anal->esil) {
|
|
|
|
int iotrap = r_config_get_i (core->config, "esil.iotrap");
|
2016-01-19 23:36:21 +00:00
|
|
|
int stacksize = r_config_get_i (core->config, "esil.stacksize");
|
2016-01-20 16:13:30 +00:00
|
|
|
if (!(core->anal->esil = r_anal_esil_new (stacksize, iotrap))) {
|
|
|
|
R_FREE (regstate);
|
|
|
|
return;
|
|
|
|
}
|
2015-09-09 23:42:56 +00:00
|
|
|
r_anal_esil_setup (core->anal->esil, core->anal, 0, 0);
|
|
|
|
}
|
|
|
|
free (regstate);
|
2016-04-21 00:25:49 +00:00
|
|
|
if (core->anal->gp) {
|
|
|
|
r_reg_setv (core->anal->reg, "gp", opc);
|
|
|
|
}
|
2015-09-09 23:42:56 +00:00
|
|
|
regstate = r_reg_arena_peek (core->anal->reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_print_esil_anal_fini(RCore *core, RDisasmState *ds) {
|
2015-11-23 23:58:03 +00:00
|
|
|
if (ds->show_emu && regstate) {
|
|
|
|
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
|
|
r_reg_arena_poke (core->anal->reg, regstate);
|
|
|
|
r_reg_setv (core->anal->reg, pc, opc);
|
|
|
|
free (regstate);
|
|
|
|
regstate = NULL;
|
|
|
|
}
|
2015-09-09 23:42:56 +00:00
|
|
|
}
|
|
|
|
|
2015-11-23 00:40:35 +00:00
|
|
|
static void handle_print_bbline(RCore *core, RDisasmState *ds) {
|
2016-02-23 17:30:32 +00:00
|
|
|
RAnalBlock *bb;
|
|
|
|
|
|
|
|
if (!ds->show_bbline || !ds->fcn) return;
|
2015-11-23 00:40:35 +00:00
|
|
|
|
2016-02-23 17:30:32 +00:00
|
|
|
bb = r_anal_fcn_bbget (ds->fcn, ds->at);
|
|
|
|
if (bb) {
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2015-12-28 02:07:00 +00:00
|
|
|
handle_update_ref_lines (core, ds);
|
2016-02-23 14:31:24 +00:00
|
|
|
if (!ds->linesright && ds->show_lines && ds->line) {
|
|
|
|
r_cons_printf ("%s%s%s", COLOR (ds, color_flow),
|
|
|
|
ds->refline2, COLOR_RESET (ds));
|
2015-11-23 00:40:35 +00:00
|
|
|
}
|
2015-12-28 02:07:00 +00:00
|
|
|
r_cons_printf("|\n");
|
2015-11-23 00:40:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-23 23:58:03 +00:00
|
|
|
// modifies anal register state
|
2015-09-09 22:34:21 +00:00
|
|
|
static void handle_print_esil_anal(RCore *core, RDisasmState *ds) {
|
|
|
|
RAnalEsil *esil = core->anal->esil;
|
|
|
|
const char *pc;
|
2015-10-29 22:37:51 +00:00
|
|
|
int i, ioc, nargs;
|
2015-11-23 23:58:03 +00:00
|
|
|
if (!esil || !ds->show_comments || !ds->show_emu) {
|
2016-03-03 23:33:24 +00:00
|
|
|
goto beach;
|
2015-09-09 22:41:19 +00:00
|
|
|
}
|
2016-04-11 08:16:47 +00:00
|
|
|
{
|
|
|
|
const RAnalMetaItem *mi = r_meta_find (core->anal, ds->at, R_META_TYPE_ANY, 0);
|
|
|
|
if (mi) { goto beach; }
|
|
|
|
}
|
2015-09-09 22:34:21 +00:00
|
|
|
ioc = r_config_get_i (core->config, "io.cache");
|
|
|
|
r_config_set (core->config, "io.cache", "true");
|
|
|
|
handle_comment_align (core, ds);
|
2015-09-09 23:42:56 +00:00
|
|
|
esil = core->anal->esil;
|
2015-09-09 22:34:21 +00:00
|
|
|
pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
2015-09-21 22:11:33 +00:00
|
|
|
r_reg_setv (core->anal->reg, pc, ds->at + ds->analop.size);
|
2015-09-10 02:20:09 +00:00
|
|
|
show_slow = ds->show_slow; // hacky global
|
2016-01-14 23:17:15 +00:00
|
|
|
show_emu_str = ds->show_emu_str; // hacky global
|
2015-09-09 23:42:56 +00:00
|
|
|
esil->cb.hook_reg_write = myregwrite;
|
2015-10-29 22:37:51 +00:00
|
|
|
if (ds->show_emu_write) {
|
|
|
|
esil->cb.hook_mem_write = mymemwrite0;
|
|
|
|
} else {
|
|
|
|
esil->cb.hook_mem_write = mymemwrite1;
|
|
|
|
}
|
2015-09-09 22:34:21 +00:00
|
|
|
likely = 0;
|
|
|
|
r_anal_esil_parse (esil, R_STRBUF_SAFEGET (&ds->analop.esil));
|
|
|
|
r_anal_esil_stack_free (esil);
|
2015-10-29 22:37:51 +00:00
|
|
|
switch (ds->analop.type) {
|
|
|
|
case R_ANAL_OP_TYPE_SWI: {
|
|
|
|
char *s = cmd_syscall_dostr (core, -1);
|
2015-10-29 10:22:49 +00:00
|
|
|
if (s) {
|
|
|
|
r_cons_printf ("; %s", s);
|
|
|
|
free (s);
|
|
|
|
}
|
2015-10-29 22:37:51 +00:00
|
|
|
} break;
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
2015-09-09 22:34:21 +00:00
|
|
|
if (likely) {
|
2015-10-29 10:22:49 +00:00
|
|
|
r_cons_printf ("; likely");
|
2015-09-09 22:34:21 +00:00
|
|
|
} else {
|
|
|
|
r_cons_printf ("; unlikely");
|
|
|
|
}
|
2015-10-29 22:37:51 +00:00
|
|
|
break;
|
|
|
|
case R_ANAL_OP_TYPE_UCALL:
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
|
|
|
{
|
2016-04-03 16:13:12 +00:00
|
|
|
RAnalFunction *fcn;
|
2015-10-30 02:07:22 +00:00
|
|
|
const char *usefmt = NULL;
|
2016-04-03 16:13:12 +00:00
|
|
|
ut64 pcv = ds->analop.jump;
|
|
|
|
if (pcv == UT64_MAX) {
|
2016-04-03 16:41:50 +00:00
|
|
|
pcv = ds->analop.ptr; // call [reloc-addr] // windows style
|
2016-04-03 16:13:12 +00:00
|
|
|
if (pcv == UT64_MAX) {
|
2016-04-03 16:41:50 +00:00
|
|
|
pcv = r_reg_getv (core->anal->reg, pc);
|
2016-04-03 16:13:12 +00:00
|
|
|
}
|
2015-10-30 02:07:22 +00:00
|
|
|
}
|
2016-04-03 16:13:12 +00:00
|
|
|
fcn = r_anal_get_fcn_at (core->anal, pcv, 0);
|
2015-10-29 22:37:51 +00:00
|
|
|
if (fcn) {
|
|
|
|
nargs = fcn->nargs;
|
2015-10-30 02:07:22 +00:00
|
|
|
usefmt = r_anal_get_fcnsign (core->anal, fcn->name);
|
2015-10-29 22:37:51 +00:00
|
|
|
} else {
|
2015-10-30 02:07:22 +00:00
|
|
|
RFlagItem *item = r_flag_get_i (core->flags, pcv);
|
|
|
|
if (item) usefmt = r_anal_get_fcnsign (core->anal, item->name);
|
|
|
|
if (!usefmt) nargs = DEFAULT_NARGS;
|
|
|
|
}
|
|
|
|
if (usefmt) {
|
|
|
|
const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
|
|
|
|
ut64 spv = r_reg_getv (core->anal->reg, sp);
|
|
|
|
spv += (core->anal->bits == 64)? 8: 4;
|
|
|
|
r_cons_newline ();
|
|
|
|
r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x, usefmt, spv);
|
|
|
|
r_cons_chop ();
|
|
|
|
} else {
|
2016-04-11 00:24:21 +00:00
|
|
|
//handle_print_pre (core, ds, false);
|
|
|
|
//handle_print_lines_left (core, ds);
|
2016-04-08 00:56:42 +00:00
|
|
|
r_cons_printf ("; CALL: ");
|
2015-10-30 02:07:22 +00:00
|
|
|
for (i = 0; i < nargs; i++) {
|
|
|
|
ut64 v = r_debug_arg_get (core->dbg, R_ANAL_CC_TYPE_STDCALL, i);
|
|
|
|
r_cons_printf ("%s0x%"PFMT64x, i?", ":"", v);
|
|
|
|
}
|
2015-10-29 22:37:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2015-09-09 22:34:21 +00:00
|
|
|
}
|
|
|
|
r_config_set_i (core->config, "io.cache", ioc);
|
2016-03-03 23:33:24 +00:00
|
|
|
beach:
|
|
|
|
if (ds->show_spacy) {
|
|
|
|
switch (ds->analop.type) {
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
|
|
|
case R_ANAL_OP_TYPE_UJMP:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
case R_ANAL_OP_TYPE_RET:
|
2016-03-09 08:53:53 +00:00
|
|
|
ds_print_spacy (ds, 1);
|
2016-03-03 23:33:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-09-09 22:34:21 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_comments_right(RCore *core, RDisasmState *ds) {
|
2015-03-08 01:27:39 +00:00
|
|
|
char *desc = NULL;
|
2014-11-03 15:24:04 +00:00
|
|
|
handle_print_relocs (core, ds);
|
2015-03-08 01:27:39 +00:00
|
|
|
if (ds->asm_describe) {
|
2015-07-15 12:55:00 +00:00
|
|
|
char *locase = strdup (ds->asmop.buf_asm);
|
|
|
|
char *op = strchr (locase, ' ');
|
2015-03-08 01:27:39 +00:00
|
|
|
if (op) *op = 0;
|
2015-07-15 12:55:00 +00:00
|
|
|
r_str_case (locase, 0);
|
|
|
|
desc = r_asm_describe (core->assembler, locase);
|
|
|
|
free (locase);
|
2015-03-08 01:27:39 +00:00
|
|
|
}
|
|
|
|
if (ds->show_comments) {
|
|
|
|
if (desc) {
|
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-03-08 01:27:39 +00:00
|
|
|
r_cons_strcat (ds->color_comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-03-08 01:27:39 +00:00
|
|
|
r_cons_strcat (" ; ");
|
|
|
|
r_cons_strcat (desc);
|
|
|
|
}
|
|
|
|
if (ds->show_comment_right && ds->comment) {
|
|
|
|
if (!desc) {
|
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-03-08 01:27:39 +00:00
|
|
|
r_cons_strcat (ds->color_comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-03-08 01:27:39 +00:00
|
|
|
r_cons_strcat (" ; ");
|
|
|
|
}
|
|
|
|
//r_cons_strcat_justify (comment, strlen (ds->refline) + 5, ';');
|
|
|
|
r_cons_strcat (ds->comment);
|
2015-11-02 11:38:08 +00:00
|
|
|
if (ds->show_color) {
|
2015-03-08 01:27:39 +00:00
|
|
|
handle_print_color_reset (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
}
|
2015-03-08 01:27:39 +00:00
|
|
|
free (ds->comment);
|
|
|
|
ds->comment = NULL;
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2015-03-08 01:27:39 +00:00
|
|
|
free (desc);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-06-18 23:11:53 +00:00
|
|
|
|
2014-11-10 12:26:03 +00:00
|
|
|
#if 0
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_refptr_meta_infos(RCore *core, RDisasmState *ds, ut64 word8 ) {
|
2014-02-24 09:55:15 +00:00
|
|
|
RAnalMetaItem *mi2 = r_meta_find (core->anal, word8,
|
|
|
|
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (mi2) {
|
|
|
|
switch (mi2->type) {
|
|
|
|
case R_META_TYPE_STRING:
|
2014-02-23 00:56:26 +00:00
|
|
|
{ char *str = r_str_escape (mi2->str);
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d
|
|
|
|
") \"%s\" ", word8, mi2->size, str);
|
|
|
|
free (str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
r_cons_printf (" (data)");
|
|
|
|
break;
|
|
|
|
default:
|
2014-07-22 23:34:28 +00:00
|
|
|
r_cons_printf (" (%c) %s", mi2->type, mi2->str);
|
2014-01-16 17:04:42 +00:00
|
|
|
break;
|
2014-05-04 15:21:05 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-01-23 02:47:20 +00:00
|
|
|
mi2 = r_meta_find (core->anal, (ut64)ds->analop.ptr,
|
2014-01-16 17:04:42 +00:00
|
|
|
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
|
|
|
if (mi2) {
|
2014-02-23 00:56:26 +00:00
|
|
|
char *str = r_str_escape (mi2->str);
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (" \"%s\" @ 0x%08"PFMT64x":%"PFMT64d,
|
2014-01-20 00:42:16 +00:00
|
|
|
str, ds->analop.ptr, mi2->size);
|
2014-01-16 17:04:42 +00:00
|
|
|
free (str);
|
|
|
|
} else r_cons_printf (" ; 0x%08x [0x%"PFMT64x"]",
|
2014-01-20 00:42:16 +00:00
|
|
|
word8, ds->analop.ptr);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-10 12:26:03 +00:00
|
|
|
#endif
|
2014-01-20 00:42:16 +00:00
|
|
|
|
2014-05-07 00:51:04 +00:00
|
|
|
static void handle_print_as_string(RCore *core, RDisasmState *ds) {
|
|
|
|
char *str = r_num_as_string (NULL, ds->analop.ptr);
|
|
|
|
if (str) {
|
2014-11-13 02:36:48 +00:00
|
|
|
handle_comment_align (core, ds);
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf (" %s; \"%s\"%s", COLOR (ds, pal_comment),
|
|
|
|
str, COLOR_RESET (ds));
|
2014-05-07 00:51:04 +00:00
|
|
|
}
|
|
|
|
free (str);
|
|
|
|
}
|
|
|
|
|
2014-11-10 12:26:03 +00:00
|
|
|
#if 0
|
2016-04-27 20:17:19 +00:00
|
|
|
static void handle_print_refptr(RCore *core, RDisasmState *ds) {
|
2014-01-16 17:04:42 +00:00
|
|
|
ut64 word8 = 0;
|
|
|
|
ut32 word4 = 0;
|
|
|
|
int ret;
|
2014-01-20 00:42:16 +00:00
|
|
|
ret = handle_read_refptr (core, ds, &word8, &word4);
|
2014-01-16 17:04:42 +00:00
|
|
|
if (ret) {
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_print_refptr_meta_infos (core, ds, word8);
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-08-05 03:37:48 +00:00
|
|
|
st64 sref = ds->analop.ptr; // todo. use .refptr?
|
|
|
|
if (sref>0) {
|
|
|
|
RFlagItem *f = r_flag_get_i (core->flags, ds->analop.ptr);
|
|
|
|
if (f) {
|
|
|
|
r_cons_printf (" ; %s", f->name);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (" ; 0x%08"PFMT64x, ds->analop.ptr);
|
|
|
|
}
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-10 12:26:03 +00:00
|
|
|
#endif
|
2014-01-20 00:42:16 +00:00
|
|
|
|
2014-01-16 17:04:42 +00:00
|
|
|
// int l is for lines
|
|
|
|
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
|
|
|
|
int continueoninvbreak = (len == l) && invbreak;
|
2015-12-14 09:19:07 +00:00
|
|
|
RAnalFunction *of = NULL;
|
2014-01-16 17:04:42 +00:00
|
|
|
RAnalFunction *f = NULL;
|
2016-02-22 22:45:36 +00:00
|
|
|
int ret, i, inc, skip_bytes = 0, idx = 0;
|
2015-12-14 09:19:07 +00:00
|
|
|
int dorepeat = 1;
|
2014-01-16 17:04:42 +00:00
|
|
|
ut8 *nbuf = NULL;
|
2014-01-20 00:42:16 +00:00
|
|
|
RDisasmState *ds;
|
2014-02-14 19:40:22 +00:00
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
// 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 = len;
|
|
|
|
ds->addr = addr;
|
2015-09-28 09:21:23 +00:00
|
|
|
ds->hint = NULL;
|
2015-12-14 09:19:07 +00:00
|
|
|
//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
|
|
|
|
// XXX - is there a better way to reset a the analysis counter so that
|
|
|
|
// when code is disassembled, it can actually find the correct offsets
|
2015-12-14 09:57:50 +00:00
|
|
|
if (true || ds->show_emu) {
|
2015-12-14 09:19:07 +00:00
|
|
|
r_reg_arena_push (core->anal->reg);
|
|
|
|
}
|
|
|
|
if (core->anal->cur && core->anal->cur->reset_counter) {
|
|
|
|
core->anal->cur->reset_counter (core->anal, addr);
|
|
|
|
}
|
|
|
|
|
2015-09-08 21:21:35 +00:00
|
|
|
handle_reflines_init (core->anal, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
core->inc = 0;
|
2015-10-08 18:00:31 +00:00
|
|
|
/* reset jmp table if not asked to keep it */
|
|
|
|
if (!core->keep_asmqjmps) { // hack
|
|
|
|
core->asmqjmps_count = 0;
|
|
|
|
core->asmqjmps_size = R_CORE_ASMQJMPS_NUM;
|
|
|
|
core->asmqjmps = realloc (core->asmqjmps, core->asmqjmps_size * sizeof (ut64));
|
|
|
|
if (core->asmqjmps) {
|
|
|
|
for (i = 0; i < R_CORE_ASMQJMPS_NUM; i++) {
|
|
|
|
core->asmqjmps[i] = UT64_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
toro:
|
|
|
|
// uhm... is this necesary? imho can be removed
|
2014-01-20 00:42:16 +00:00
|
|
|
r_asm_set_pc (core->assembler, ds->addr+idx);
|
2015-11-02 20:30:55 +00:00
|
|
|
core->cons->vline = r_config_get_i (core->config, "scr.utf8") ?
|
|
|
|
r_vline_u : r_vline_a;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
// TODO: support in-the-middle-of-instruction too
|
2016-04-03 22:52:45 +00:00
|
|
|
r_anal_op_fini (&ds->analop);
|
2016-03-03 23:33:24 +00:00
|
|
|
if (r_anal_op (core->anal, &ds->analop, core->offset + core->print->cur,
|
|
|
|
buf+core->print->cur, (int)(len - core->print->cur))) {
|
2014-01-20 00:42:16 +00:00
|
|
|
// TODO: check for ds->analop.type and ret
|
|
|
|
ds->dest = ds->analop.jump;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* highlight eip */
|
|
|
|
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
|
2016-03-03 23:33:24 +00:00
|
|
|
RFlagItem *item = r_flag_get (core->flags, pc);
|
2015-11-02 20:30:55 +00:00
|
|
|
if (item) ds->dest = item->offset;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
|
2015-09-09 23:42:56 +00:00
|
|
|
handle_print_esil_anal_init (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_break (NULL, NULL);
|
2016-02-22 22:45:36 +00:00
|
|
|
inc = 0;
|
|
|
|
if (ds->l == 0) {
|
2016-02-22 22:53:29 +00:00
|
|
|
len = ds->l = core->blocksize;
|
2016-02-22 22:45:36 +00:00
|
|
|
}
|
2015-11-02 20:30:55 +00:00
|
|
|
for (i = idx = ret = 0; idx < len && ds->lines < ds->l;
|
2015-10-14 13:38:55 +00:00
|
|
|
idx += inc, i++, ds->index += inc, ds->lines++) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->at = ds->addr + idx;
|
2014-11-01 22:54:51 +00:00
|
|
|
if (r_cons_singleton ()->breaked) {
|
|
|
|
dorepeat = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
break;
|
2014-11-01 22:54:51 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
r_core_seek_archbits (core, ds->at); // slow but safe
|
|
|
|
ds->hint = r_core_hint_begin (core, ds->hint, ds->at);
|
|
|
|
r_asm_set_pc (core->assembler, ds->at);
|
|
|
|
handle_update_ref_lines (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
/* show type links */
|
2014-01-20 00:42:16 +00:00
|
|
|
r_core_cmdf (core, "tf 0x%08"PFMT64x, ds->at);
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-09-26 13:40:17 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
2016-02-23 17:30:32 +00:00
|
|
|
ds->fcn = f;
|
2015-12-14 09:19:07 +00:00
|
|
|
if (f && f->folded && ds->at >= f->addr && ds->at < f->addr+f->size) {
|
2015-12-14 23:18:44 +00:00
|
|
|
int delta = (ds->at <= f->addr)? (ds->at - f->addr + f->size): 0;
|
2015-12-14 09:19:07 +00:00
|
|
|
if (of != f) {
|
2016-03-15 10:47:13 +00:00
|
|
|
char cmt[32];
|
|
|
|
get_bits_comment(core, f, cmt, sizeof (cmt));
|
2015-12-15 00:03:42 +00:00
|
|
|
handle_show_comments_right (core, ds);
|
2016-03-15 10:47:13 +00:00
|
|
|
r_cons_printf ("%s%s%s (fcn) %s%s%s\n",
|
2016-03-09 09:08:53 +00:00
|
|
|
COLOR (ds, color_fline), core->cons->vline[RUP_CORNER],
|
2016-03-15 10:47:13 +00:00
|
|
|
COLOR (ds, color_fname), f->name, cmt, COLOR_RESET (ds));
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, true);
|
2015-12-14 09:19:07 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
handle_print_offset (core, ds);
|
|
|
|
r_cons_printf ("(%d byte folded function)\n", f->size);
|
2015-12-14 23:18:44 +00:00
|
|
|
//r_cons_printf ("%s%s%s\n", COLOR (ds, color_fline), core->cons->vline[RDWN_CORNER], COLOR_RESET (ds));
|
|
|
|
if (delta<0) delta = -delta;
|
|
|
|
ds->addr += delta + idx;
|
2015-12-14 09:19:07 +00:00
|
|
|
r_io_read_at (core->io, ds->addr, buf, len);
|
|
|
|
inc = 0; //delta;
|
|
|
|
idx = 0;
|
|
|
|
of = f;
|
2016-02-07 20:44:35 +00:00
|
|
|
if (len == l)
|
2015-12-16 14:30:13 +00:00
|
|
|
break;
|
2015-12-14 09:19:07 +00:00
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
ds->lines--;
|
2015-12-14 23:37:33 +00:00
|
|
|
ds->addr += 1;
|
|
|
|
r_io_read_at (core->io, ds->addr, buf, len);
|
|
|
|
inc = 0; //delta;
|
|
|
|
idx = 0;
|
2015-12-14 09:19:07 +00:00
|
|
|
// r_cons_printf ("delta %d fsize %d\n", delta, f->size);
|
2015-12-14 23:37:33 +00:00
|
|
|
// inc = 1;
|
2015-12-14 09:19:07 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!ds->hint || !ds->hint->bits) {
|
2014-01-16 17:04:42 +00:00
|
|
|
if (f) {
|
|
|
|
if (f->bits) {
|
2015-11-02 20:30:55 +00:00
|
|
|
if (!ds->oldbits) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->oldbits = r_config_get_i (core->config, "asm.bits");
|
2015-11-02 20:30:55 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits != f->bits) {
|
2014-01-16 17:04:42 +00:00
|
|
|
r_config_set_i (core->config, "asm.bits", f->bits);
|
|
|
|
}
|
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_show_comments_right (core, ds);
|
|
|
|
ret = perform_disassembly (core, ds, buf+idx, len-idx);
|
2016-01-10 21:30:10 +00:00
|
|
|
if (ret == -31337) {
|
|
|
|
inc = ds->oplen;
|
|
|
|
continue;
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->retry) {
|
|
|
|
ds->retry = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_atabs_option (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
// TODO: store previous oplen in core->dec
|
2015-11-02 20:30:55 +00:00
|
|
|
if (core->inc == 0) {
|
2014-01-20 00:42:16 +00:00
|
|
|
core->inc = ds->oplen;
|
2015-11-02 20:30:55 +00:00
|
|
|
}
|
2016-04-03 23:03:31 +00:00
|
|
|
if (ds->analop.mnemonic || !ds->lastfail) {
|
2015-03-24 02:23:56 +00:00
|
|
|
r_anal_op_fini (&ds->analop);
|
|
|
|
}
|
2015-11-02 20:30:55 +00:00
|
|
|
if (!ds->lastfail) {
|
2014-01-20 00:42:16 +00:00
|
|
|
r_anal_op (core->anal, &ds->analop, ds->at, buf+idx, (int)(len-idx));
|
2015-11-02 20:30:55 +00:00
|
|
|
}
|
|
|
|
if (ret < 1) {
|
2014-01-20 00:42:16 +00:00
|
|
|
r_strbuf_init (&ds->analop.esil);
|
|
|
|
ds->analop.type = R_ANAL_OP_TYPE_ILL;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->hint) {
|
|
|
|
if (ds->hint->size) ds->analop.size = ds->hint->size;
|
|
|
|
if (ds->hint->ptr) ds->analop.ptr = ds->hint->ptr;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2016-02-23 17:30:32 +00:00
|
|
|
handle_print_bbline (core, ds);
|
2016-04-03 23:59:30 +00:00
|
|
|
if (ds->at >= addr) {
|
|
|
|
r_print_set_rowoff (core->print, ds->lines, ds->at - addr);
|
|
|
|
}
|
2015-12-17 19:18:50 +00:00
|
|
|
if (ds->midflags) {
|
|
|
|
skip_bytes = handleMidFlags (core, ds, true);
|
|
|
|
if (skip_bytes && ds->midflags == R_MIDFLAGS_SHOW)
|
|
|
|
ds->at += skip_bytes;
|
|
|
|
}
|
|
|
|
handle_show_flags_option (core, ds);
|
|
|
|
if (skip_bytes && ds->midflags == R_MIDFLAGS_SHOW)
|
|
|
|
ds->at -= skip_bytes;
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_instruction_mov_lea (core, ds, idx);
|
|
|
|
handle_control_flow_comments (core, ds);
|
|
|
|
handle_adistrick_comments (core, ds);
|
2014-01-16 17:04:42 +00:00
|
|
|
/* XXX: This is really cpu consuming.. need to be fixed */
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_show_functions (core, ds);
|
2015-10-17 22:07:58 +00:00
|
|
|
handle_show_xrefs (core, ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2015-10-17 22:07:58 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
2015-11-02 20:30:55 +00:00
|
|
|
|
2016-01-27 02:33:52 +00:00
|
|
|
if (ds->show_comments && !ds->show_comment_right) {
|
|
|
|
if (ds->show_emu) {
|
|
|
|
handle_print_esil_anal (core, ds);
|
|
|
|
r_cons_newline ();
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2016-01-27 02:33:52 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
}
|
2016-01-27 01:35:45 +00:00
|
|
|
}
|
|
|
|
|
2015-11-02 20:30:55 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->addr, 0);
|
|
|
|
if (handle_print_labels (core, ds, f)) {
|
|
|
|
handle_show_functions (core, ds);
|
|
|
|
handle_show_xrefs (core, ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2015-11-02 20:30:55 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
2014-12-13 17:06:01 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_print_offset (core, ds);
|
|
|
|
handle_print_op_size (core, ds);
|
|
|
|
handle_print_trace (core, ds);
|
2014-02-10 22:01:19 +00:00
|
|
|
handle_print_cycles (core, ds);
|
2015-10-03 11:52:52 +00:00
|
|
|
handle_print_family (core, ds);
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_print_stackptr (core, ds);
|
2014-04-09 02:53:34 +00:00
|
|
|
ret = handle_print_meta_infos (core, ds, buf, len, idx);
|
2014-12-21 03:18:56 +00:00
|
|
|
if (!ds->mi_found) {
|
|
|
|
/* show cursor */
|
|
|
|
handle_print_show_cursor (core, ds);
|
|
|
|
handle_print_show_bytes (core, ds);
|
|
|
|
handle_print_lines_right (core, ds);
|
|
|
|
handle_build_op_str (core, ds);
|
|
|
|
handle_print_opstr (core, ds);
|
2016-03-13 02:13:27 +00:00
|
|
|
|
2014-12-21 03:18:56 +00:00
|
|
|
handle_print_fcn_name (core, ds);
|
|
|
|
handle_print_color_reset (core, ds);
|
|
|
|
handle_print_dwarf (core, ds);
|
|
|
|
ret = handle_print_middle (core, ds, ret);
|
2016-03-13 02:13:27 +00:00
|
|
|
|
2014-12-21 03:18:56 +00:00
|
|
|
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-idx+5);
|
|
|
|
r_asm_set_syntax (core->assembler, os);
|
|
|
|
}
|
|
|
|
handle_print_core_vmode (core, ds);
|
|
|
|
handle_print_cc_update (core, ds);
|
|
|
|
} else {
|
|
|
|
ds->mi_found = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_print_op_push_info (core, ds);
|
2016-01-27 01:35:45 +00:00
|
|
|
handle_print_ptr (core, ds, len + 256, idx);
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_print_comments_right (core, ds);
|
2015-11-02 20:30:55 +00:00
|
|
|
if (!(ds->show_comments && ds->show_comment_right && ds->comment)) {
|
2016-01-27 01:49:40 +00:00
|
|
|
handle_print_esil_anal (core, ds);
|
|
|
|
r_cons_newline ();
|
2015-11-02 20:30:55 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->line) {
|
2015-08-30 22:20:07 +00:00
|
|
|
if (ds->show_lines_ret && ds->analop.type == R_ANAL_OP_TYPE_RET) {
|
2015-11-02 11:38:08 +00:00
|
|
|
if (strchr (ds->line, '>')) {
|
2014-01-20 00:42:16 +00:00
|
|
|
memset (ds->line, ' ', r_str_len_utf8 (ds->line));
|
2015-09-02 08:01:53 +00:00
|
|
|
}
|
2015-11-02 11:38:08 +00:00
|
|
|
r_cons_printf ("%s%s%s%s; --------------------------------------\n",
|
|
|
|
ds->pre, COLOR (ds, color_flow), ds->line, COLOR_RESET (ds));
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2016-04-03 22:52:45 +00:00
|
|
|
R_FREE (ds->line);
|
|
|
|
R_FREE (ds->refline);
|
|
|
|
R_FREE (ds->refline2);
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2016-01-10 21:30:10 +00:00
|
|
|
R_FREE (ds->opstr);
|
2015-05-05 22:56:31 +00:00
|
|
|
inc = ds->oplen;
|
2015-12-17 19:18:50 +00:00
|
|
|
if (ds->midflags == R_MIDFLAGS_REALIGN && skip_bytes)
|
|
|
|
inc = skip_bytes;
|
2016-02-07 20:44:35 +00:00
|
|
|
if (inc < 1)
|
|
|
|
inc = 1;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
if (nbuf == buf) {
|
|
|
|
free (buf);
|
|
|
|
buf = NULL;
|
2013-01-24 02:48:24 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_break_end ();
|
|
|
|
|
|
|
|
#if HASRETRY
|
2014-11-01 22:54:51 +00:00
|
|
|
if (!ds->cbytes && ds->lines<ds->l && dorepeat) {
|
2014-01-16 17:04:42 +00:00
|
|
|
retry:
|
|
|
|
if (len<4) len = 4;
|
|
|
|
buf = nbuf = malloc (len);
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->tries>0) {
|
|
|
|
if (r_core_read_at (core, ds->addr, buf, len) ) {
|
2014-01-16 17:04:42 +00:00
|
|
|
goto toro;
|
|
|
|
}
|
2013-01-24 02:48:24 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->lines<ds->l) {
|
2014-08-15 02:06:51 +00:00
|
|
|
//ds->addr += idx;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (r_core_read_at (core, ds->addr, buf, len) != len) {
|
|
|
|
//ds->tries = -1;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
goto toro;
|
2013-01-24 02:48:24 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
if (continueoninvbreak)
|
|
|
|
goto toro;
|
2013-01-24 02:48:24 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
#endif
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2013-08-11 13:38:42 +00:00
|
|
|
}
|
2016-03-01 23:49:43 +00:00
|
|
|
r_print_set_rowoff (core->print, ds->lines, ds->at - addr);
|
2016-02-07 22:31:24 +00:00
|
|
|
r_print_set_rowoff (core->print, ds->lines + 1, UT32_MAX);
|
2015-09-12 17:12:57 +00:00
|
|
|
// TODO: this should be called from deinit_ds()
|
2014-01-20 00:42:16 +00:00
|
|
|
r_anal_op_fini (&ds->analop);
|
2015-09-12 17:12:57 +00:00
|
|
|
// TODO: this too (must review)
|
2015-09-09 23:42:56 +00:00
|
|
|
handle_print_esil_anal_fini (core, ds);
|
2016-04-03 21:52:36 +00:00
|
|
|
handle_reflines_fini (core->anal, ds);
|
2015-09-12 17:12:57 +00:00
|
|
|
handle_deinit_ds (core, ds);
|
2015-12-14 09:57:50 +00:00
|
|
|
if (true || ds->show_emu) {
|
2015-12-14 09:19:07 +00:00
|
|
|
r_reg_arena_pop (core->anal->reg);
|
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
return idx; //-ds->lastfail;
|
2013-08-11 13:38:42 +00:00
|
|
|
}
|
|
|
|
|
2014-08-23 05:23:55 +00:00
|
|
|
/* Disassemble either `nb_opcodes` instructions, or
|
|
|
|
* `nb_bytes` bytes; both can be negative.
|
|
|
|
* Set to 0 the parameter you don't use */
|
|
|
|
R_API int r_core_print_disasm_instructions (RCore *core, int nb_bytes, int nb_opcodes) {
|
2014-01-22 22:58:23 +00:00
|
|
|
RDisasmState *ds = NULL;
|
2014-01-16 17:04:42 +00:00
|
|
|
int i, j, ret, err = 0;
|
|
|
|
RAnalFunction *f;
|
2014-01-20 00:42:16 +00:00
|
|
|
char *tmpopstr;
|
2014-08-23 05:23:55 +00:00
|
|
|
const ut64 old_offset = core->offset;
|
2015-11-05 01:07:20 +00:00
|
|
|
bool hasanal = false;
|
2014-08-23 05:23:55 +00:00
|
|
|
|
2016-04-26 09:09:15 +00:00
|
|
|
r_reg_arena_push (core->anal->reg);
|
2014-08-23 05:23:55 +00:00
|
|
|
if (!nb_bytes) {
|
|
|
|
nb_bytes = core->blocksize;
|
|
|
|
if (nb_opcodes < 0) {
|
|
|
|
/* Backward disassembly or nb_opcodes opcodes
|
|
|
|
* - We compute the new starting offset
|
|
|
|
* - Read at the new offset */
|
|
|
|
nb_opcodes = -nb_opcodes;
|
|
|
|
r_core_asm_bwdis_len (core, &nb_bytes, &core->offset, nb_opcodes);
|
|
|
|
r_core_read_at (core, core->offset, core->block, nb_bytes);
|
|
|
|
}
|
2014-12-17 23:27:12 +00:00
|
|
|
} else {
|
2014-08-23 05:23:55 +00:00
|
|
|
if (nb_bytes < 0) { // Disassemble backward `nb_bytes` bytes
|
|
|
|
nb_bytes = -nb_bytes;
|
|
|
|
core->offset -= nb_bytes;
|
|
|
|
r_core_read_at (core, core->offset, core->block, nb_bytes);
|
|
|
|
}
|
|
|
|
}
|
2013-11-07 01:07:10 +00:00
|
|
|
|
2014-02-14 19:40:22 +00:00
|
|
|
// XXX - is there a better way to reset a the analysis counter so that
|
|
|
|
// when code is disassembled, it can actually find the correct offsets
|
2014-02-20 02:08:12 +00:00
|
|
|
if (core->anal->cur && core->anal->cur->reset_counter)
|
2014-02-14 19:40:22 +00:00
|
|
|
core->anal->cur->reset_counter (core->anal, core->offset);
|
|
|
|
|
2014-01-20 00:42:16 +00:00
|
|
|
ds = handle_init_ds (core);
|
2014-08-23 05:23:55 +00:00
|
|
|
ds->len = nb_bytes;
|
|
|
|
ds->l = nb_opcodes;
|
2015-10-20 22:26:32 +00:00
|
|
|
ds->len = nb_opcodes * 8;
|
2011-06-04 01:14:04 +00:00
|
|
|
|
2015-10-20 23:51:34 +00:00
|
|
|
if (ds->len > core->blocksize) {
|
|
|
|
if (core->fixedblock) {
|
|
|
|
nb_bytes = ds->len = core->blocksize;
|
|
|
|
} else {
|
|
|
|
r_core_block_size (core, ds->len);
|
|
|
|
r_core_block_read (core, 0);
|
|
|
|
}
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-08-23 05:23:55 +00:00
|
|
|
if (ds->l == 0)
|
|
|
|
ds->l = ds->len;
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-11-01 22:54:51 +00:00
|
|
|
r_cons_break (NULL, NULL);
|
2015-10-20 22:26:32 +00:00
|
|
|
#define isTheEnd (nb_opcodes? j<nb_opcodes: i<nb_bytes)
|
|
|
|
for (i = j = 0; isTheEnd; i += ret, j++) {
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->at = core->offset +i;
|
2015-11-05 01:07:20 +00:00
|
|
|
hasanal = false;
|
2014-01-20 00:42:16 +00:00
|
|
|
r_core_seek_archbits (core, ds->at);
|
2014-11-01 22:54:51 +00:00
|
|
|
if (r_cons_singleton ()->breaked)
|
|
|
|
break;
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->hint) {
|
|
|
|
r_anal_hint_free (ds->hint);
|
|
|
|
ds->hint = NULL;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->hint = r_core_hint_begin (core, ds->hint, ds->at);
|
|
|
|
r_asm_set_pc (core->assembler, ds->at);
|
2014-01-16 17:04:42 +00:00
|
|
|
// XXX copypasta from main disassembler function
|
2014-09-26 13:40:17 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!ds->hint || !ds->hint->bits) {
|
2014-01-16 17:04:42 +00:00
|
|
|
if (f) {
|
|
|
|
if (f->bits) {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (!ds->oldbits)
|
|
|
|
ds->oldbits = r_config_get_i (core->config, "asm.bits");
|
|
|
|
if (ds->oldbits != f->bits) {
|
2014-01-16 17:04:42 +00:00
|
|
|
r_config_set_i (core->config, "asm.bits", f->bits);
|
|
|
|
}
|
2013-09-30 10:56:00 +00:00
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits != 0) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2013-09-30 10:56:00 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2013-07-03 15:43:20 +00:00
|
|
|
}
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
|
|
|
ret = r_asm_disassemble (core->assembler,
|
2014-08-23 05:23:55 +00:00
|
|
|
&ds->asmop, core->block+i, core->blocksize-i);
|
2016-04-03 22:17:57 +00:00
|
|
|
r_anal_op_fini (&ds->analop);
|
2015-06-04 11:05:02 +00:00
|
|
|
if (ds->show_color && !hasanal) {
|
2015-09-10 20:49:05 +00:00
|
|
|
r_anal_op (core->anal, &ds->analop, ds->at,
|
2015-10-20 21:37:20 +00:00
|
|
|
core->block + i, core->blocksize - i);
|
2015-11-05 01:07:20 +00:00
|
|
|
hasanal = true;
|
2015-06-04 11:05:02 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
//r_cons_printf ("0x%08"PFMT64x" ", core->offset+i);
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->hint && ds->hint->size)
|
|
|
|
ret = ds->hint->size;
|
|
|
|
if (ds->hint && ds->hint->opcode) {
|
2014-05-09 15:40:28 +00:00
|
|
|
free (ds->opstr);
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->opstr = strdup (ds->hint->opcode);
|
2014-01-16 17:04:42 +00:00
|
|
|
} else {
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->use_esil) {
|
2015-06-04 11:05:02 +00:00
|
|
|
if (!hasanal) {
|
2015-11-05 01:07:20 +00:00
|
|
|
r_anal_op (core->anal, &ds->analop,
|
|
|
|
ds->at, core->block+i,
|
|
|
|
core->blocksize-i);
|
|
|
|
hasanal = true;
|
2015-06-04 11:05:02 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
if (*R_STRBUF_SAFEGET (&ds->analop.esil)) {
|
2014-05-09 15:40:28 +00:00
|
|
|
free (ds->opstr);
|
2014-01-20 00:42:16 +00:00
|
|
|
ds->opstr = strdup (R_STRBUF_SAFEGET (&ds->analop.esil));
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-11-07 03:27:57 +00:00
|
|
|
} else if (ds->filter) {
|
2015-10-20 21:37:20 +00:00
|
|
|
char *asm_str;
|
2014-11-07 03:27:57 +00:00
|
|
|
int ofs = core->parser->flagspace;
|
|
|
|
int fs = ds->flagspace_ports;
|
|
|
|
if (ds->analop.type == R_ANAL_OP_TYPE_IO) {
|
|
|
|
core->parser->notin_flagspace = -1;
|
|
|
|
core->parser->flagspace = fs;
|
|
|
|
} else {
|
|
|
|
if (fs != -1) {
|
|
|
|
core->parser->notin_flagspace = fs;
|
|
|
|
core->parser->flagspace = fs;
|
|
|
|
} else {
|
|
|
|
core->parser->notin_flagspace = -1;
|
|
|
|
core->parser->flagspace = -1;
|
|
|
|
}
|
|
|
|
}
|
2015-10-20 21:37:20 +00:00
|
|
|
core->parser->hint = ds->hint;
|
2014-11-07 03:27:57 +00:00
|
|
|
r_parse_filter (core->parser, core->flags,
|
2016-04-26 09:09:15 +00:00
|
|
|
ds->asmop.buf_asm, ds->str, sizeof (ds->str), core->print->big_endian);
|
2015-10-20 21:37:20 +00:00
|
|
|
ds->opstr = strdup (ds->str);
|
|
|
|
asm_str = colorize_asm_string (core, ds);
|
2014-11-07 03:27:57 +00:00
|
|
|
core->parser->flagspace = ofs;
|
|
|
|
free (ds->opstr);
|
2015-10-20 21:37:20 +00:00
|
|
|
ds->opstr = asm_str;
|
2014-11-07 03:27:57 +00:00
|
|
|
core->parser->flagspace = ofs; // ???
|
2015-10-20 21:37:20 +00:00
|
|
|
} else {
|
|
|
|
ds->opstr = strdup (ds->asmop.buf_asm);
|
|
|
|
}
|
|
|
|
if (ds->decode) {
|
2014-05-09 15:40:28 +00:00
|
|
|
free (ds->opstr);
|
2015-06-04 11:05:02 +00:00
|
|
|
if (!hasanal) {
|
|
|
|
r_anal_op (core->anal, &ds->analop, ds->at, core->block+i, core->blocksize-i);
|
2015-11-05 01:07:20 +00:00
|
|
|
hasanal = true;
|
2015-06-04 11:05:02 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
tmpopstr = r_anal_op_to_string (core->anal, &ds->analop);
|
|
|
|
ds->opstr = (tmpopstr)? tmpopstr: strdup (ds->asmop.buf_asm);
|
2013-07-04 01:34:28 +00:00
|
|
|
}
|
2013-07-03 15:43:20 +00:00
|
|
|
}
|
2016-02-07 20:44:35 +00:00
|
|
|
if (ret < 1) {
|
2014-01-16 17:04:42 +00:00
|
|
|
err = 1;
|
|
|
|
ret = 1;
|
2015-11-02 17:57:01 +00:00
|
|
|
}
|
|
|
|
{
|
2015-06-04 11:05:02 +00:00
|
|
|
const char *opcolor = NULL;
|
|
|
|
if (ds->show_color) {
|
|
|
|
opcolor = r_print_color_op_type (core->print, ds->analop.type);
|
2015-08-09 20:16:17 +00:00
|
|
|
r_cons_printf ("%s%s" Color_RESET "\n", opcolor, ds->opstr);
|
|
|
|
} else {
|
|
|
|
r_cons_printf ("%s\n", ds->opstr);
|
2015-06-04 11:05:02 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
free (ds->opstr);
|
|
|
|
ds->opstr = NULL;
|
2013-01-22 17:08:33 +00:00
|
|
|
}
|
2014-03-11 01:47:10 +00:00
|
|
|
if (ds->hint) {
|
|
|
|
r_anal_hint_free (ds->hint);
|
|
|
|
ds->hint = NULL;
|
|
|
|
}
|
2013-01-22 17:08:33 +00:00
|
|
|
}
|
2014-11-01 22:54:51 +00:00
|
|
|
r_cons_break_end ();
|
2014-01-20 00:42:16 +00:00
|
|
|
if (ds->oldbits) {
|
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2013-05-24 00:53:15 +00:00
|
|
|
}
|
2014-01-20 00:42:16 +00:00
|
|
|
handle_deinit_ds (core, ds);
|
2014-08-23 05:23:55 +00:00
|
|
|
core->offset = old_offset;
|
2015-11-23 23:58:03 +00:00
|
|
|
r_reg_arena_pop (core->anal->reg);
|
2014-06-25 00:30:42 +00:00
|
|
|
return err;
|
2013-01-22 17:08:33 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
|
2014-08-23 05:23:55 +00:00
|
|
|
R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int nb_bytes, int nb_opcodes) {
|
2014-01-16 17:04:42 +00:00
|
|
|
RAsmOp asmop;
|
|
|
|
RAnalOp analop;
|
2014-12-05 13:08:53 +00:00
|
|
|
RDisasmState *ds;
|
|
|
|
RAnalFunction *f;
|
2016-03-09 10:59:17 +00:00
|
|
|
int i, j, k, oplen, ret, line;
|
2015-06-04 14:53:04 +00:00
|
|
|
ut64 old_offset = core->offset;
|
2014-12-17 20:25:24 +00:00
|
|
|
ut64 at;
|
|
|
|
int dis_opcodes = 0;
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("[");
|
2015-04-08 08:41:42 +00:00
|
|
|
int limit_by = 'b';
|
2014-02-14 19:40:22 +00:00
|
|
|
|
2015-04-08 08:41:42 +00:00
|
|
|
if (nb_opcodes != 0) {
|
|
|
|
limit_by = 'o';
|
|
|
|
}
|
2015-02-16 23:54:55 +00:00
|
|
|
if (nb_opcodes) { // Disassemble `nb_opcodes` opcodes.
|
2014-08-23 05:23:55 +00:00
|
|
|
if (nb_opcodes < 0) {
|
2015-02-16 23:54:55 +00:00
|
|
|
int count, nbytes = 0;
|
2014-08-23 05:23:55 +00:00
|
|
|
/* Backward disassembly of `nb_opcodes` opcodes:
|
|
|
|
* - We compute the new starting offset
|
|
|
|
* - Read at the new offset */
|
|
|
|
nb_opcodes = -nb_opcodes;
|
2015-06-04 14:53:04 +00:00
|
|
|
|
|
|
|
if (nb_opcodes > 0xffff) {
|
|
|
|
eprintf ("Too many backward instructions\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2015-02-16 23:54:55 +00:00
|
|
|
if (!r_core_asm_bwdis_len (core, &nbytes, &addr, nb_opcodes)) {
|
2015-06-04 14:53:04 +00:00
|
|
|
/* workaround to avoid empty arrays */
|
|
|
|
#define BWRETRY 0
|
|
|
|
#if BWRETRY
|
|
|
|
nb_opcodes+=1;
|
|
|
|
if (!r_core_asm_bwdis_len (core, &nbytes, &addr, nb_opcodes)) {
|
|
|
|
#endif
|
|
|
|
r_cons_printf ("]");
|
2015-09-14 10:35:38 +00:00
|
|
|
return false;
|
2015-06-04 14:53:04 +00:00
|
|
|
#if BWRETRY
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
nb_opcodes-=1;
|
2014-12-19 19:44:44 +00:00
|
|
|
}
|
2015-02-16 23:54:55 +00:00
|
|
|
count = R_MIN (nb_bytes, nbytes);
|
|
|
|
if (count>0) {
|
|
|
|
r_core_read_at (core, addr, buf, count);
|
|
|
|
r_core_read_at (core, addr+count, buf+count, nb_bytes-count);
|
|
|
|
} else {
|
2015-04-06 22:31:35 +00:00
|
|
|
if (nb_bytes>0)
|
|
|
|
memset (buf, 0xff, nb_bytes);
|
2015-02-16 23:54:55 +00:00
|
|
|
}
|
2014-12-17 20:25:24 +00:00
|
|
|
} else {
|
|
|
|
// If we are disassembling a positive number of lines, enable dis_opcodes
|
|
|
|
// to be used to finish the loop
|
|
|
|
// If we are disasembling a negative number of lines, we just calculate
|
|
|
|
// the equivalent addr and nb_size and scan a positive number of BYTES
|
|
|
|
// so keep dis_opcodes = 0;
|
|
|
|
dis_opcodes = 1;
|
2014-12-17 23:27:12 +00:00
|
|
|
r_core_read_at (core, addr, buf, nb_bytes);
|
2014-08-23 05:23:55 +00:00
|
|
|
}
|
2016-02-16 20:48:07 +00:00
|
|
|
} else { // Disassemble `nb_bytes` bytes
|
2014-08-23 05:23:55 +00:00
|
|
|
if (nb_bytes < 0) {
|
|
|
|
//Backward disassembly of `nb_bytes` bytes
|
|
|
|
nb_bytes = -nb_bytes;
|
|
|
|
addr -= nb_bytes;
|
|
|
|
r_core_read_at (core, addr, buf, nb_bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
core->offset = addr;
|
|
|
|
|
2014-02-14 19:40:22 +00:00
|
|
|
// XXX - is there a better way to reset a the analysis counter so that
|
|
|
|
// when code is disassembled, it can actually find the correct offsets
|
2014-11-25 11:24:37 +00:00
|
|
|
if (core->anal && core->anal->cur && core->anal->cur->reset_counter) {
|
2014-02-14 19:40:22 +00:00
|
|
|
core->anal->cur->reset_counter (core->anal, addr);
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
// TODO: add support for anal hints
|
2014-12-17 23:27:12 +00:00
|
|
|
// If using #bytes i = j
|
|
|
|
// If using #opcodes, j is the offset from start address. i is the
|
|
|
|
// offset in current disassembly buffer (256 by default)
|
2016-03-09 10:59:17 +00:00
|
|
|
i = k = j = line = 0;
|
2015-04-09 23:57:17 +00:00
|
|
|
// i = number of bytes
|
|
|
|
// j = number of instructions
|
2016-03-09 10:59:17 +00:00
|
|
|
// k = delta from addr
|
2014-12-17 23:27:12 +00:00
|
|
|
for (;;) {
|
2016-03-09 10:59:17 +00:00
|
|
|
bool end_nbopcodes, end_nbbytes;
|
|
|
|
|
|
|
|
at = addr + k;
|
2014-01-16 17:04:42 +00:00
|
|
|
r_asm_set_pc (core->assembler, at);
|
2014-12-17 23:27:12 +00:00
|
|
|
// 32 is the biggest opcode length in intel
|
|
|
|
// Make sure we have room for it
|
2016-03-09 10:59:17 +00:00
|
|
|
if (dis_opcodes == 1 && i >= nb_bytes - 32) {
|
2014-12-17 23:27:12 +00:00
|
|
|
// Read another nb_bytes bytes into buf from current offset
|
2014-12-17 20:25:24 +00:00
|
|
|
r_core_read_at (core, at, buf, nb_bytes);
|
2016-03-09 10:59:17 +00:00
|
|
|
i = 0;
|
2014-12-17 20:25:24 +00:00
|
|
|
}
|
2016-03-09 10:59:17 +00:00
|
|
|
|
2015-04-08 08:41:42 +00:00
|
|
|
if (limit_by == 'o') {
|
2016-03-09 10:59:17 +00:00
|
|
|
if (j >= nb_opcodes) {
|
2015-04-08 08:41:42 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-03-09 10:59:17 +00:00
|
|
|
} else if (i >= nb_bytes) {
|
|
|
|
break;
|
2015-04-08 01:20:11 +00:00
|
|
|
}
|
2016-03-09 10:59:17 +00:00
|
|
|
ret = r_asm_disassemble (core->assembler, &asmop, buf + i, nb_bytes - i);
|
|
|
|
if (ret < 1) {
|
|
|
|
r_cons_printf (j > 0 ? ",{" : "{");
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("\"offset\":%"PFMT64d, at);
|
|
|
|
r_cons_printf (",\"size\":1,\"type\":\"invalid\"}");
|
|
|
|
i++;
|
2016-03-09 10:59:17 +00:00
|
|
|
k++;
|
2014-12-17 23:27:12 +00:00
|
|
|
j++;
|
2014-01-16 17:04:42 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-03-09 10:59:17 +00:00
|
|
|
r_anal_op (core->anal, &analop, at, buf + i, nb_bytes - i);
|
2014-12-05 12:29:33 +00:00
|
|
|
ds = handle_init_ds (core);
|
|
|
|
if (ds->pseudo) r_parse_parse (core->parser, asmop.buf_asm, asmop.buf_asm);
|
2014-12-16 21:49:32 +00:00
|
|
|
f = r_anal_get_fcn_in (core->anal, at, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
|
2014-12-15 19:36:34 +00:00
|
|
|
if (ds->varsub && f) {
|
|
|
|
core->parser->varlist = r_anal_var_list;
|
2015-11-19 22:12:08 +00:00
|
|
|
r_parse_varsub (core->parser, f, at, ds->analop.size,
|
2014-12-15 19:36:34 +00:00
|
|
|
asmop.buf_asm, asmop.buf_asm, sizeof (asmop.buf_asm));
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
oplen = r_asm_op_get_size (&asmop);
|
2014-12-18 00:07:26 +00:00
|
|
|
r_cons_printf (j>0? ",{": "{");
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("\"offset\":%"PFMT64d, at);
|
2014-12-05 12:29:33 +00:00
|
|
|
if (f) {
|
|
|
|
r_cons_printf (",\"fcn_addr\":%"PFMT64d, f->addr);
|
|
|
|
r_cons_printf (",\"fcn_last\":%"PFMT64d, f->addr + f->size - oplen);
|
|
|
|
} else {
|
|
|
|
r_cons_printf (",\"fcn_addr\":0");
|
|
|
|
r_cons_printf (",\"fcn_last\":0");
|
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (",\"size\":%d", oplen);
|
2014-12-19 16:49:42 +00:00
|
|
|
{
|
2015-06-15 03:04:29 +00:00
|
|
|
char *escaped_str = r_str_escape (asmop.buf_asm);
|
|
|
|
r_cons_printf (",\"opcode\":\"%s\"", escaped_str);
|
|
|
|
free (escaped_str);
|
|
|
|
}
|
|
|
|
if (ds->use_esil) {
|
|
|
|
const char * esil = R_STRBUF_SAFEGET (&analop.esil);
|
|
|
|
r_cons_printf (",\"esil\":\"%s\"", esil);
|
2014-12-19 16:49:42 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (",\"bytes\":\"%s\"", asmop.buf_hex);
|
2015-10-08 15:02:22 +00:00
|
|
|
r_cons_printf (",\"family\":\"%s\"",
|
|
|
|
r_anal_op_family_to_string (analop.family));
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (",\"type\":\"%s\"", r_anal_optype_to_string (analop.type));
|
2014-08-10 03:39:50 +00:00
|
|
|
// wanted the numerical values of the type information
|
|
|
|
r_cons_printf (",\"type_num\":%"PFMT64d, analop.type);
|
|
|
|
r_cons_printf (",\"type2_num\":%"PFMT64d, analop.type2);
|
|
|
|
// handle switch statements
|
|
|
|
if (analop.switch_op && r_list_length (analop.switch_op->cases) > 0) {
|
2014-08-11 02:52:53 +00:00
|
|
|
// XXX - the java caseop will still be reported in the assembly,
|
|
|
|
// this is an artifact to make ensure the disassembly is properly
|
|
|
|
// represented during the analysis
|
2014-08-10 03:39:50 +00:00
|
|
|
RListIter *iter;
|
|
|
|
RAnalCaseOp *caseop;
|
|
|
|
int cnt = r_list_length (analop.switch_op->cases);
|
|
|
|
r_cons_printf (", \"switch\":[");
|
|
|
|
r_list_foreach (analop.switch_op->cases, iter, caseop ) {
|
|
|
|
cnt--;
|
|
|
|
r_cons_printf ("{");
|
|
|
|
r_cons_printf ("\"addr\":%"PFMT64d, caseop->addr);
|
|
|
|
r_cons_printf (", \"value\":%"PFMT64d, (st64) caseop->value);
|
|
|
|
r_cons_printf (", \"jump\":%"PFMT64d, caseop->jump);
|
|
|
|
r_cons_printf ("}");
|
|
|
|
if (cnt > 0) r_cons_printf (",");
|
|
|
|
}
|
|
|
|
r_cons_printf ("]");
|
|
|
|
}
|
|
|
|
if (analop.jump != UT64_MAX ) {
|
2014-11-20 00:14:47 +00:00
|
|
|
r_cons_printf (",\"jump\":%"PFMT64d, analop.jump);
|
2016-03-09 10:59:17 +00:00
|
|
|
if (analop.fail != UT64_MAX) {
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf (",\"fail\":%"PFMT64d, analop.fail);
|
2016-03-09 10:59:17 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-11-20 00:14:47 +00:00
|
|
|
/* add flags */
|
|
|
|
{
|
|
|
|
const RList *flags = r_flag_get_list (core->flags, at);
|
|
|
|
RFlagItem *flag;
|
|
|
|
RListIter *iter;
|
|
|
|
if (flags && !r_list_empty (flags)) {
|
|
|
|
r_cons_printf (",\"flags\":[");
|
|
|
|
r_list_foreach (flags, iter, flag) {
|
|
|
|
r_cons_printf ("%s\"%s\"", iter->p?",":"",flag->name);
|
|
|
|
}
|
|
|
|
r_cons_printf ("]");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* add comments */
|
|
|
|
{
|
|
|
|
// TODO: slow because we are decoding and encoding b64
|
|
|
|
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, at);
|
|
|
|
if (comment) {
|
|
|
|
char *b64comment = sdb_encode ((const ut8*)comment, -1);
|
|
|
|
r_cons_printf (",\"comment\":\"%s\"", b64comment);
|
|
|
|
free (comment);
|
|
|
|
free (b64comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* add xrefs */
|
|
|
|
{
|
|
|
|
RAnalRef *ref;
|
|
|
|
RListIter *iter;
|
|
|
|
RList *xrefs = r_anal_xref_get (core->anal, at);
|
|
|
|
if (xrefs && !r_list_empty (xrefs)) {
|
|
|
|
r_cons_printf (",\"xrefs\":[");
|
|
|
|
r_list_foreach (xrefs, iter, ref) {
|
|
|
|
r_cons_printf ("%s{\"addr\":%"PFMT64d",\"type\":\"%s\"}",
|
2014-12-05 12:29:33 +00:00
|
|
|
iter->p?",":"", ref->addr,
|
2014-11-20 00:14:47 +00:00
|
|
|
r_anal_xrefs_type_tostring (ref->type));
|
|
|
|
}
|
|
|
|
r_cons_printf ("]");
|
|
|
|
}
|
2015-01-15 23:56:54 +00:00
|
|
|
r_list_free (xrefs);
|
2014-11-20 00:14:47 +00:00
|
|
|
}
|
|
|
|
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("}");
|
2015-04-09 23:57:17 +00:00
|
|
|
i += oplen; // bytes
|
2016-03-09 10:59:17 +00:00
|
|
|
k += oplen; // delta from addr
|
|
|
|
j++; // instructions
|
2014-08-21 22:39:31 +00:00
|
|
|
line++;
|
2016-03-09 10:59:17 +00:00
|
|
|
|
|
|
|
end_nbopcodes = dis_opcodes == 1 && nb_opcodes > 0 && line>=nb_opcodes;
|
|
|
|
end_nbbytes = dis_opcodes == 0 && nb_bytes > 0 && i>=nb_bytes;
|
|
|
|
if (end_nbopcodes || end_nbbytes) break;
|
2014-12-17 23:27:12 +00:00
|
|
|
}
|
2014-01-16 17:04:42 +00:00
|
|
|
r_cons_printf ("]");
|
2014-08-23 05:23:55 +00:00
|
|
|
core->offset = old_offset;
|
2015-09-14 10:35:38 +00:00
|
|
|
return true;
|
2014-01-16 17:04:42 +00:00
|
|
|
}
|
2014-01-23 04:55:48 +00:00
|
|
|
|
|
|
|
R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int invbreak, int cbytes) {
|
2014-09-26 13:40:17 +00:00
|
|
|
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, R_ANAL_FCN_TYPE_NULL);
|
2015-04-22 22:46:28 +00:00
|
|
|
ut32 cur_buf_sz = 0;
|
|
|
|
ut8 *buf = NULL;
|
|
|
|
ut32 len = 0;
|
2014-01-23 04:55:48 +00:00
|
|
|
int ret, idx = 0, i;
|
|
|
|
RListIter *bb_iter;
|
|
|
|
RAnalBlock *bb = NULL;
|
|
|
|
RDisasmState *ds;
|
2015-04-22 22:46:28 +00:00
|
|
|
RList *bb_list = NULL;
|
|
|
|
|
|
|
|
if (!fcn)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
cur_buf_sz = fcn->size + 1;
|
|
|
|
buf = malloc (cur_buf_sz);
|
|
|
|
len = fcn->size;
|
|
|
|
bb_list = r_list_new();
|
2014-01-23 04:55:48 +00:00
|
|
|
//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);
|
|
|
|
|
2014-02-14 19:40:22 +00:00
|
|
|
// XXX - is there a better way to reset a the analysis counter so that
|
|
|
|
// when code is disassembled, it can actually find the correct offsets
|
2014-04-09 02:53:34 +00:00
|
|
|
if (core->anal->cur && core->anal->cur->reset_counter) {
|
2014-02-14 19:40:22 +00:00
|
|
|
core->anal->cur->reset_counter (core->anal, addr);
|
|
|
|
}
|
|
|
|
|
2014-01-23 04:55:48 +00:00
|
|
|
// 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;
|
2016-02-23 17:30:32 +00:00
|
|
|
ds->fcn = fcn;
|
2014-01-23 04:55:48 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
i = 0;
|
|
|
|
idx = 0;
|
2015-09-09 23:42:56 +00:00
|
|
|
r_cons_break (NULL, NULL);
|
|
|
|
handle_print_esil_anal_init (core, ds);
|
2015-10-01 17:32:30 +00:00
|
|
|
|
|
|
|
if (core->io && core->io->debug)
|
|
|
|
r_debug_map_sync (core->dbg);
|
2014-01-23 04:55:48 +00:00
|
|
|
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) {
|
2014-05-09 15:40:28 +00:00
|
|
|
free (buf);
|
2014-01-23 04:55:48 +00:00
|
|
|
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_comments_right (core, ds);
|
|
|
|
ret = perform_disassembly (core, ds, buf+idx, len - bb_size_consumed);
|
|
|
|
handle_atabs_option (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)
|
2014-02-20 02:08:12 +00:00
|
|
|
r_anal_op (core->anal, &ds->analop,
|
|
|
|
ds->at+bb_size_consumed, buf+idx,
|
|
|
|
len-bb_size_consumed);
|
2014-01-23 04:55:48 +00:00
|
|
|
|
|
|
|
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);
|
2014-09-23 07:35:37 +00:00
|
|
|
if (handle_print_labels (core, ds, fcn)) {
|
|
|
|
handle_show_functions (core, ds);
|
|
|
|
}
|
2014-12-13 17:06:01 +00:00
|
|
|
handle_show_xrefs (core, ds);
|
2014-01-23 04:55:48 +00:00
|
|
|
handle_show_flags_option (core, ds);
|
2016-04-27 20:17:19 +00:00
|
|
|
handle_setup_print_pre (core, ds, false);
|
2014-01-23 04:55:48 +00:00
|
|
|
handle_print_lines_left (core, ds);
|
|
|
|
handle_print_offset (core, ds);
|
|
|
|
handle_print_op_size (core, ds);
|
|
|
|
handle_print_trace (core, ds);
|
2014-02-25 23:03:42 +00:00
|
|
|
handle_print_cycles (core, ds);
|
2015-10-03 11:52:52 +00:00
|
|
|
handle_print_family (core, ds);
|
2014-01-23 04:55:48 +00:00
|
|
|
handle_print_stackptr (core, ds);
|
2014-02-20 02:08:12 +00:00
|
|
|
ret = handle_print_meta_infos (core, ds, buf, len, idx);
|
2014-01-23 04:55:48 +00:00
|
|
|
if (ds->mi_found) {
|
|
|
|
ds->mi_found = 0;
|
2014-09-23 09:55:11 +00:00
|
|
|
continue;
|
2014-01-23 04:55:48 +00:00
|
|
|
}
|
|
|
|
/* show cursor */
|
|
|
|
handle_print_show_cursor (core, ds);
|
|
|
|
handle_print_show_bytes (core, ds);
|
|
|
|
handle_print_lines_right (core, ds);
|
|
|
|
handle_build_op_str (core, ds);
|
|
|
|
handle_print_opstr (core, ds);
|
|
|
|
handle_print_fcn_name (core, ds);
|
2014-04-02 20:30:39 +00:00
|
|
|
handle_print_import_name (core, ds);
|
2014-02-20 02:08:12 +00:00
|
|
|
handle_print_color_reset (core, ds);
|
2014-01-23 04:55:48 +00:00
|
|
|
handle_print_dwarf (core, ds);
|
2014-09-03 08:25:29 +00:00
|
|
|
ret = handle_print_middle (core, ds, ret);
|
2014-01-23 04:55:48 +00:00
|
|
|
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;
|
2014-02-20 02:08:12 +00:00
|
|
|
r_asm_set_syntax (core->assembler,
|
|
|
|
R_ASM_SYNTAX_INTEL);
|
|
|
|
r_asm_disassemble (core->assembler, &ao,
|
|
|
|
buf+idx, len-bb_size_consumed);
|
2014-01-23 04:55:48 +00:00
|
|
|
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) {
|
2014-11-06 23:41:29 +00:00
|
|
|
handle_print_refptr (core, ds);
|
2014-01-23 04:55:48 +00:00
|
|
|
} else {
|
2014-11-06 23:41:29 +00:00
|
|
|
handle_print_ptr (core, ds, len, idx);
|
2014-01-23 04:55:48 +00:00
|
|
|
}*/
|
2014-11-06 23:41:29 +00:00
|
|
|
handle_print_ptr (core, ds, len, idx);
|
2014-01-23 04:55:48 +00:00
|
|
|
handle_print_comments_right (core, ds);
|
2015-09-09 22:34:21 +00:00
|
|
|
handle_print_esil_anal (core, ds);
|
2016-03-03 23:33:24 +00:00
|
|
|
if ( !(ds->show_comments && ds->show_comment_right && ds->comment)) {
|
2014-01-23 04:55:48 +00:00
|
|
|
r_cons_newline ();
|
2016-03-03 23:33:24 +00:00
|
|
|
}
|
2014-01-23 04:55:48 +00:00
|
|
|
if (ds->line) {
|
|
|
|
free (ds->line);
|
|
|
|
free (ds->refline);
|
|
|
|
free (ds->refline2);
|
|
|
|
ds->line = ds->refline = ds->refline2 = NULL;
|
|
|
|
}
|
2015-11-23 00:40:35 +00:00
|
|
|
handle_print_bbline (core, ds);
|
2016-03-03 23:33:24 +00:00
|
|
|
|
2014-01-23 04:55:48 +00:00
|
|
|
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 ();
|
2015-09-09 23:42:56 +00:00
|
|
|
handle_print_esil_anal_fini (core, ds);
|
2014-01-23 04:55:48 +00:00
|
|
|
|
|
|
|
if (ds->oldbits) {
|
2014-02-20 02:08:12 +00:00
|
|
|
r_config_set_i (core->config, "asm.bits", ds->oldbits);
|
|
|
|
ds->oldbits = 0;
|
2014-01-23 04:55:48 +00:00
|
|
|
}
|
|
|
|
r_anal_op_fini (&ds->analop);
|
|
|
|
handle_deinit_ds (core, ds);
|
|
|
|
r_list_free (bb_list);
|
2014-01-27 00:12:16 +00:00
|
|
|
return idx;
|
2014-01-23 04:55:48 +00:00
|
|
|
}
|