mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 23:20:40 +00:00
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:
parent
a2693f982c
commit
cde83cfd0c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 = '-';
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 '/':
|
||||
|
Loading…
Reference in New Issue
Block a user