Add many experimental enhancements for the visual debugger

- V@ is an alias to set cmd.vprompt
- New config variables!
  stack.size = size of stack displayed in Vpp
  stack.delta = substract that delta to the stack address
  stack.anotated = use pxa instead of pxw
  scr.highlight = word to highlight by RCons
  hex.flagsz = override flag size in pxa
- Fix x86 udis anal plugin size of invalid instructions
- Fix 'hud file not found' issue
- Add 'Vdh' to set scr.highlight
- Fix V: wheel scroll issue
- Realign pxa marks if addr > UT32_MAX
- Set hex.flagsz = 9999 to cover the whole area instead of just 1 byte
This commit is contained in:
pancake 2014-09-27 03:48:54 +02:00
parent a2693f982c
commit cde83cfd0c
11 changed files with 143 additions and 11 deletions

View File

@ -60,9 +60,9 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
opsize = ud_disassemble (&d);
strncpy (op->buf_asm, ud_insn_asm (&d), R_ASM_BUFSIZE-1);
op->buf_asm[R_ASM_BUFSIZE-1] = 0;
op->size = opsize;
if (opsize<1 || strstr (op->buf_asm, "invalid"))
opsize = -1;
opsize = 0;
op->size = opsize;
return opsize;
}

View File

@ -151,7 +151,7 @@ R_API int r_cons_enable_mouse (const int enable) {
write (2, code, strlen (code));
} else {
//r_cons_memcat ("\x1b[?1001r", 8);
const char *code = "\x1b[?1001r" "\x1b[?1000l";
const char *code = "\x1b[?1001r" "\x1b[?1000l\x1b[32m";
write (2, code, strlen (code));
}
return enabled;
@ -373,6 +373,7 @@ R_API void r_cons_flush() {
fclose (d);
} else eprintf ("Cannot write on '%s'\n", tee);
}
r_cons_highlight (I.highlight);
// is_html must be a filter, not a write endpoint
if (I.is_html) r_cons_html_print (I.buffer);
else r_cons_write (I.buffer, I.buffer_len);
@ -387,6 +388,7 @@ R_API void r_cons_flush() {
R_API void r_cons_visual_flush() {
if (I.noflush)
return;
r_cons_highlight (I.highlight);
if (!I.null) {
/* TODO: this ifdef must go in the function body */
#if __WINDOWS__
@ -737,3 +739,21 @@ R_API void r_cons_set_title(const char *str) {
R_API void r_cons_zero() {
write (1, "", 1);
}
R_API void r_cons_highlight (const char *word) {
char *rword, *res;
free (I.highlight);
if (word) {
I.highlight = strdup (word);
rword = malloc (strlen (word)+32);
strcpy (rword, "\x1b[7m");
strcpy (rword+4, word);
strcpy (rword+4+strlen(word), "\x1b[0m");
res = r_str_replace (I.buffer, word, rword, 1);
if (res) {
I.buffer = res;
}
} else {
I.highlight = NULL;
}
}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2008-2013 - pancake */
/* radare - LGPL - Copyright 2008-2014 - pancake */
#include <r_cons.h>
#include <ctype.h>
@ -20,6 +20,8 @@ R_API char *r_cons_hud_file(const char *f) {
if (s) {
char *ret = r_cons_hud_string (s);
free (s);
if (!ret)
ret = strdup ("");
return ret;
}
return NULL;

View File

@ -119,6 +119,7 @@ static int process_input(RCore *core, const char *input, ut64* blocksize, char *
static void annotated_hexdump(RCore *core, const char *str, int len) {
const int usecolor = r_config_get_i (core->config, "scr.color");
int nb_cols = r_config_get_i (core->config, "hex.cols");
int flagsz = r_config_get_i (core->config, "hex.flagsz");
const ut8 *buf = core->block;
ut64 addr = core->offset;
int color_idx = 0;
@ -166,9 +167,19 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
return;
}
#if 1
int addrpadlen = strlen (sdb_fmt (0, "%08"PFMT64x, addr))-8;
char addrpad[32];
if (addrpadlen>0) {
memset (addrpad, ' ', addrpadlen);
addrpad[addrpadlen] = 0;
//Compute, then show the legend
strcpy (bytes, "- offset - ");
j = strlen ("- offset - ");
strcpy (bytes, addrpad);
} else addrpadlen = 0;
strcpy (bytes+addrpadlen, "- offset - ");
#endif
j = strlen (bytes);
for (i=0; i<nb_cols; i+=2) {
sprintf (bytes+j, " %X %X ", (i&0xf), (i+1)&0xf);
j += 5;
@ -210,7 +221,11 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
// collect flags
flag = r_flag_get_i (core->flags, addr+j);
if (flag) { // Begining of a flag
fend = addr + j + flag->size;
if (flagsz) {
fend = addr + flagsz; //core->blocksize;
} else {
fend = addr + j + flag->size;
}
note[j] = r_str_prefix (strdup (flag->name), "/");
marks = R_TRUE;
color_idx++;
@ -309,11 +324,12 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
out[off+sz-1] = '.';
}
hasline = (out[off] != ' ');
free (note[j]);
R_FREE (note[j]);
}
}
out[out_sz-1] = 0;
if (hasline) {
r_cons_strcat (addrpad);
r_cons_strcat (out);
r_cons_newline ();
}

View File

@ -560,6 +560,12 @@ static int cb_scrhtml(void *user, void *data) {
return R_TRUE;
}
static int cb_scrhighlight(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_highlight (node->value);
return R_TRUE;
}
static int cb_scrint(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->is_interactive = node->i_value;
@ -829,6 +835,10 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("dir.types", "/usr/include", "Default path to look for cparse type files");
SETPREF("dir.projects", "~/"R2_HOMEDIR"/projects", "Default path for projects");
SETPREF("stack.anotated", "false", "Show anotated hexdump in visual debug");
SETI("stack.size", 64, "Define size of anotated hexdump in visual debug");
SETI("stack.delta", 0, "Define a delta for the stack dump");
SETCB("dbg.profile", "", &cb_runprofile, "Path to RRunProfile file");
/* debug */
SETCB("dbg.status", "false", &cb_dbgstatus, "Set cmd.prompt to '.dr*' or '.dr*;drd;sr pc;pi 1;s-'");
@ -869,6 +879,7 @@ R_API int r_core_config_init(RCore *core) {
r_config_desc (cfg, "cmd.graph", "Command executed by 'agv' command to view graphs");
SETICB("cmd.depth", 10, &cb_cmddepth, "Maximum command depth");
SETPREF("cmd.bp", "", "Command to executed every breakpoint hit");
SETPREF("cmd.stack", "", "Command to display the stack in visual debug mode");
SETPREF("cmd.cprompt", "", "Column visual prompt commands");
SETPREF("cmd.hit", "", "Command to execute on every search hit");
SETPREF("cmd.open", "", "Command executed when file its opened");
@ -882,6 +893,7 @@ R_API int r_core_config_init(RCore *core) {
/* hexdump */
SETCB("hex.pairs", "true", &cb_hexpairs, "Show bytes paired in 'px' hexdump");
SETI("hex.flagsz", 0, "if != 0 overrides the flag size in pxa");
SETICB("hex.cols", 16, &cb_hexcols, "Configure the number of columns in hexdump");
SETICB("hex.stride", 0, &cb_hexstride, "Define the line stride in hexdump (default is 0)");
@ -952,6 +964,7 @@ R_API int r_core_config_init(RCore *core) {
SETCB("scr.fps", "false", &cb_fps, "Show FPS indicator in Visual");
SETICB("scr.fix_rows", 0, &cb_fixrows, "Workaround for Linux TTY");
SETICB("scr.fix_columns", 0, &cb_fixcolumns, "Workaround for Prompt iOS ssh client");
SETCB("scr.highlight", "", &cb_scrhighlight, "Highligh that word at RCons level");
SETCB("scr.interactive", "true", &cb_scrint, "Start in interractive mode");
SETCB("scr.html", "false", &cb_scrhtml, "If enabled disassembly uses HTML syntax");
SETCB("scr.nkey", "hit", &cb_scrnkey, "Select the seek mode in visual");

View File

@ -859,14 +859,49 @@ static void handle_update_ref_lines (RCore *core, RDisasmState *ds) {
ds->line = NULL;
}
}
static int highlight (const char *word, char *op, int size) {
char *res, *rword, *opstr = strdup (op);
rword = malloc (strlen (word)+32);
strcpy (rword, "\x1b[7m");
strcpy (rword+4, word);
strcpy (rword+4+strlen(word), "\x1b[0m");
res = r_str_replace (opstr, word, rword, 1);
if (!res) {
free (rword);
free (opstr);
return R_FALSE;
}
opstr = res;
if (strlen (opstr)+1>=size) {
free (rword);
free (opstr);
return R_FALSE;
}
strcpy (op, opstr);
free (opstr);
free (rword);
return R_TRUE;
}
static int perform_disassembly(RCore *core, RDisasmState *ds, ut8 *buf, int len) {
int ret;
// TODO : line analysis must respect data types! shouldnt be interpreted as code
ret = r_asm_disassemble (core->assembler, &ds->asmop, buf, len);
if (ds->asmop.size<1) ds->asmop.size = 1;
if (ds->asmop.size<1) {
ut32 *n32 = (ut32*)buf;
ut64 *n64 = (ut64*)buf;
// if arm or mips.. 32 or 64
snprintf (ds->asmop.buf_asm,
sizeof (ds->asmop.buf_asm),
"0x%08x", *n32);
snprintf (ds->asmop.buf_asm,
sizeof (ds->asmop.buf_asm),
"0x%08"PFMT64x, *n64);
ds->asmop.size = 1;
}
ds->oplen = ds->asmop.size;
// replace buf_asm to highlight shit
if (ret<1) { // XXX: move to r_asm_disassemble ()
ret = -1;
@ -900,6 +935,8 @@ static int perform_disassembly(RCore *core, RDisasmState *ds, ut8 *buf, int len)
ds->opstr = strdup (ds->str);
}
//highlight ("eax", ds->asmop.buf_asm, sizeof (ds->asmop.buf_asm));
if (ds->acase)
r_str_case (ds->asmop.buf_asm, 1);

View File

@ -5,7 +5,7 @@
static void showfile(const int nth, const char *name, int minusl) {
struct stat sb;
const char *n = name;
char *nn, *u_rwx;
char *nn, *u_rwx = "";
int sz = r_file_size (n);
int perm, isdir, uid = 0, gid = 0;
int fch = '-';

View File

@ -7,7 +7,7 @@ static int blocksize = 0;
static ut64 last_printed_address = 0LL;
static void r_core_visual_refresh (RCore *core);
static const char *printfmt[] = {
"x", "pd $r",
"x", "pd $r",
"f tmp;sr sp;pxw 64;dr=;s-;s tmp;f-tmp;pd $r",
"pxw", "pc", "pxa"
};
@ -89,6 +89,7 @@ static void visual_help() {
"Visual mode help:\n"
" ? show this help or manpage in cursor mode\n"
" & rotate asm.bits between supported 8, 16, 32, 64\n"
" @ set cmd.vprompt to run commands before the visual prompt\n"
" ! run r2048 game\n"
" _ enter the hud\n"
" . seek to program counter\n"
@ -609,6 +610,9 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case 'c':
setcursor (core, curset?0:1);
break;
case '@':
r_core_cmd0 (core, "?i vmprompt;\"e cmd.vprompt=`?y`\"");
break;
case 'C':
color = color? 0: 1;
r_config_set_i (core->config, "scr.color", color);
@ -1124,10 +1128,14 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case 'N': r_core_seek_delta (core, 0-(int)core->blocksize); break;
#endif
case ':':
core->vmode = R_FALSE;
r_core_visual_prompt_input (core);
core->vmode = R_TRUE;
break;
case '_':
core->vmode = R_FALSE;
r_core_visual_hud (core);
core->vmode = R_TRUE;
break;
case ';':
r_cons_printf ("Enter a comment: ('-' to remove, '!' to use $EDITOR)\n");
@ -1418,6 +1426,26 @@ R_API int r_core_visual(RCore *core, const char *input) {
core->print->flags |= R_PRINT_FLAGS_ADDRMOD;
do {
if (core->printidx == 2) {
static char debugstr[512];
const char *cmdvhex = r_config_get (core->config, "cmd.stack");
const int pxa = r_config_get_i (core->config, "stack.anotated"); // stack.anotated
const int size = r_config_get_i (core->config, "stack.size"); // stack.size
const int delta = r_config_get_i (core->config, "stack.delta"); // stack.delta
if (cmdvhex && *cmdvhex) {
snprintf (debugstr, sizeof(debugstr),
"f tmp;sr sp;%s;dr=;s-;"
"s tmp;f-tmp;pd $r", cmdvhex);
debugstr[sizeof(debugstr)-1]=0;
} else {
snprintf (debugstr, sizeof(debugstr),
"f tmp;sr sp;%s %d@$$-%d;dr=;s-;"
"s tmp;f-tmp;pd $r",
pxa?"pxa":"pxw", size,
delta);
}
printfmt[2] = debugstr;
}
wheel = r_config_get_i (core->config, "scr.wheel");
r_cons_show_cursor (R_FALSE);
if (wheel)

View File

@ -1269,6 +1269,7 @@ R_API void r_core_visual_define (RCore *core) {
," e end of function"
," f analyze function"
," F format"
," h highlight word"
," q quit/cancel operation"
," r rename function"
," s set string"
@ -1391,6 +1392,9 @@ R_API void r_core_visual_define (RCore *core) {
}
}
break;
case 'h':
r_core_cmd0 (core, "?i highlight;e scr.highlight=`?y`");
break;
case 'r':
r_core_cmd0 (core, "?i new function name;afn `?y`");
break;

View File

@ -147,6 +147,7 @@ typedef struct r_cons_t {
char *pager;
int blankline;
int truecolor; // 0 = ansi, 1 = rgb 256), 2 = truecolor (16M)
char *highlight;
int null; // if set, does not show anything
int mouse;
RConsPalette pal;
@ -292,6 +293,7 @@ R_API void r_cons_reset();
R_API void r_cons_reset_colors();
R_API void r_cons_print_clear();
R_API void r_cons_zero();
R_API void r_cons_highlight (const char *word);
R_API void r_cons_clear();
R_API void r_cons_clear00();
R_API void r_cons_clear_line(int err);

View File

@ -957,11 +957,21 @@ R_API char * r_print_colorize_opcode (char *p, const char *reg, const char *num)
return strdup (p);
}
switch (p[i]) {
// We dont need to skip ansi codes.
// original colors must be preserved somehow
case 0x1b:
#define STRIP_ANSI 1
#if STRIP_ANSI
/* skip until 'm' */
for (++i;p[i] && p[i]!='m'; i++)
o[j] = p[i];
continue;
#else
/* copy until 'm' */
for (;p[i] && p[i]!='m'; i++)
o[j++] = p[i];
o[j++] = p[i++];
#endif
case '+':
case '-':
case '/':