Fully configurable console palette for disassembly, hexdump and prompt

- Fix overflow in r_cons
This commit is contained in:
pancake 2013-05-23 02:26:48 +02:00
parent d31a0333d4
commit e5cdab6d20
10 changed files with 204 additions and 64 deletions

View File

@ -88,7 +88,7 @@ int main(int argc, char **argv) {
// TODO: use r_sys api to get pid when running in bg
pid = r_sys_cmdbg (cmd);
free (cmd);
result = result_heap = malloc (80+filename_len);
result = result_heap = malloc (1024+filename_len);
if (!result) {
perror ("malloc");
return 1;

View File

@ -133,7 +133,7 @@ R_API int r_cons_fgets(char *buf, int len, int argc, const char **argv) {
*buf = '\0';
fflush (cons->fdin);
if (color) {
printf (cons->pal.input);
printf ("%s", cons->pal.input);
fflush (stdout);
}
if (fgets (buf, len, cons->fdin) == NULL) {

View File

@ -4,10 +4,16 @@
R_API void r_cons_pal_init(const char *foo) {
RCons *cons = r_cons_singleton ();
memset (&cons->pal, 0, sizeof (cons->pal));
cons->pal.prompt = Color_YELLOW;
cons->pal.offset = Color_GREEN;
cons->pal.input = Color_WHITE;
cons->pal.comment = Color_TURQOISE;
cons->pal.b0x00 = Color_GREEN;
cons->pal.b0x7f = Color_YELLOW;
cons->pal.b0xff = Color_RED;
cons->pal.btext = Color_MAGENTA;
cons->pal.push = Color_YELLOW;
cons->pal.reset = "\x1b[0m";
}
@ -24,8 +30,8 @@ struct {
{ "yellow", Color_YELLOW, Color_BGYELLOW },
{ "turqoise", Color_TURQOISE, Color_BGTURQOISE },
{ "blue", Color_BLUE, Color_BGBLUE },
{ "gray", Color_GRAY Color_BGGRAY },
{ NULL, NULL }
{ "gray", Color_GRAY, Color_BGGRAY },
{ NULL, NULL, NULL }
};
static inline ut8 rgbnum (const char ch) {
@ -72,6 +78,19 @@ struct {
{ "prompt", r_offsetof (RConsPalette, prompt) },
{ "offset", r_offsetof (RConsPalette, offset) },
{ "input", r_offsetof (RConsPalette, input) },
{ "b0x00", r_offsetof (RConsPalette, b0x00) },
{ "b0x7f", r_offsetof (RConsPalette, b0x7f) },
{ "b0xff", r_offsetof (RConsPalette, b0xff) },
{ "btext", r_offsetof (RConsPalette, btext) },
{ "push", r_offsetof (RConsPalette, push) },
{ "pop", r_offsetof (RConsPalette, pop) },
{ "jmp", r_offsetof (RConsPalette, jmp) },
{ "call", r_offsetof (RConsPalette, call) },
{ "nop", r_offsetof (RConsPalette, nop) },
{ "ret", r_offsetof (RConsPalette, ret) },
{ "trap", r_offsetof (RConsPalette, trap) },
{ "swi", r_offsetof (RConsPalette, swi) },
{ "cmp", r_offsetof (RConsPalette, cmp) },
{ NULL, 0 }
};
@ -85,7 +104,64 @@ R_API void r_cons_pal_load(const char *sdbfile) {
R_API void r_cons_pal_save(const char *sdbfile) {
}
R_API void r_cons_pal_set (const char *key, const char *val) {
R_API void r_cons_pal_show () {
const int inc = 3;
int i, j, k, n = 0;
for (i=0; colors[i].name; i++) {
r_cons_printf ("%s%s__"Color_RESET" %s\n",
colors[i].code,
colors[i].bgcode,
colors[i].name);
}
r_cons_printf ("\nGreyscale:\n");
for (i=n=0; i<=0xf; i+=1) {
char fg[32], bg[32];
int r = i*16;
if (i<2) strcpy (fg, Color_WHITE);
else r_cons_rgb_str (fg, 0, 0, 0, 0);
r_cons_rgb_str (bg, r, r, r, 1);
r_cons_printf ("%s%s rgb:%x%x%x "Color_RESET, fg, bg, i, i, i);
if (n++==5) {
n = 0;
r_cons_newline();
}
}
r_cons_printf ("\n\nRGB:\n");
for (i=n=0; i<=0xf; i+=inc) {
for (j=0; j<=0xf; j+=inc) {
for (k=0; k<=0xf; k+=inc) {
char fg[32], bg[32];
int r = i*16;
int g = j*16;
int b = k*16;
if (i<2 && j<6 && k<13) strcpy (fg, Color_WHITE);
else r_cons_rgb_str (fg, 0, 0, 0, 0);
r_cons_rgb_str (bg, r, g, b, 1);
r_cons_printf ("%s%s rgb:%x%x%x "Color_RESET,
fg, bg, i, j, k);
//if (n++==7) {
if (n++==5) {
n = 0;
r_cons_newline();
}
}
}
}
}
R_API void r_cons_pal_list () {
RConsPalette *pal = &(r_cons_singleton ()->pal);
ut8 *p = (ut8*)pal;
char *color;
int i;
for (i=0; keys[i].name; i++) {
color = *(p+keys[i].off);
r_cons_printf ("%s\\/"Color_RESET" %s\n",
color, keys[i].name);
}
}
R_API int r_cons_pal_set (const char *key, const char *val) {
int i;
char **p;
for (i=0; keys[i].name; i++) {
@ -93,7 +169,8 @@ R_API void r_cons_pal_set (const char *key, const char *val) {
p = (char **)((char *)&(r_cons_singleton()->pal) + keys[i].off);
// free (*p);
*p = r_cons_pal_parse (val);
break;
return R_TRUE;
}
}
return R_FALSE;
}

View File

@ -438,20 +438,29 @@ static int cmd_eval(void *data, const char *input) {
r_config_list (core->config, NULL, 0);
break;
case 'c':
{
if (input[1] == '?') {
r_cons_printf ("Usage: ec[s?] [key][[=| ]fg] [bg]\n");
r_cons_printf (" ec list all color keys\n");
r_cons_printf (" ecs show a colorful palette\n");
r_cons_printf (" ec prompt red change coloro of prompt\n");
r_cons_printf ("Available colors:\n");
r_cons_printf (" rgb:000 24 bit hexadecimal rgb color\n");
r_cons_printf (" red|green|blue|. well known ansi colors\n");
} else if (input[1] == 's') {
r_cons_pal_show ();
} else if (input[1] == '\0') {
r_cons_pal_list ();
} else {
char *p = strdup (input+2);
char *q = strchr (p, ' ');
if (p) {
if (q) {
// set
*q++ = 0;
r_cons_pal_set (p, q);
} else {
// get
eprintf ("(%s)(%s)\n", p, q);
}
char *q = strchr (p, '=');
if (!q) q = strchr (p, ' ');
if (q) {
// set
*q++ = 0;
r_cons_pal_set (p, q);
} else {
eprintf ("TODO: ec list\n");
// get
eprintf ("(%s)(%s)\n", p, q);
}
}
break;
@ -493,17 +502,17 @@ static int cmd_eval(void *data, const char *input) {
case 0:
r_cons_printf (
"Usage: e[?] [var[=value]]\n"
" e? ; show this help\n"
" e?asm.bytes ; show description\n"
" e?? ; list config vars with description\n"
" e ; list config vars\n"
" e- ; reset config vars\n"
" e* ; dump config vars in r commands\n"
" e!a ; invert the boolean value of 'a' var\n"
" er [key] ; set config key as readonly. no way back\n"
" ec [k] [color] ; set color for given key (prompt, offset, ...)\n"
" e a ; get value of var 'a'\n"
" e a=b ; set var 'a' the 'b' value\n");
" e? ; show this help\n"
" e?asm.bytes ; show description\n"
" e?? ; list config vars with description\n"
" e ; list config vars\n"
" e- ; reset config vars\n"
" e* ; dump config vars in r commands\n"
" e!a ; invert the boolean value of 'a' var\n"
" er [key] ; set config key as readonly. no way back\n"
" ec [k] [color] ; set color for given key (prompt, offset, ...)\n"
" e a ; get value of var 'a'\n"
" e a=b ; set var 'a' the 'b' value\n");
}
break;
case 'r':

View File

@ -494,6 +494,7 @@ R_API int r_core_init(RCore *core) {
r_line_hist_load (".radare2_history");
singleton = R_FALSE;
}
core->print->cons = core->cons;
core->cons->num = core->num;
core->blocksize = R_CORE_BLOCKSIZE;
core->block = (ut8*)malloc (R_CORE_BLOCKSIZE);

View File

@ -69,6 +69,7 @@ static void printoffset(ut64 off, int show_color, int invert, int opt) {
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
/* hints */
RAnalHint *hint = NULL;
const char *pal_comment = core->cons->pal.comment;
/* other */
int ret, idx = 0, i, j, k, lines, ostackptr = 0, stackptr = 0;
char *line = NULL, *comment = NULL, *opstr, *osl = NULL; // old source line
@ -131,6 +132,20 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
int ocols = 0;
int lcols = 0;
/* color palette */
#define P(x) (core->cons && core->cons->pal.x)? core->cons->pal.x
// TODO: only if show_color?
const char *color_comment = P(comment): Color_TURQOISE;
const char *color_nop = P(nop): Color_BLUE;
const char *color_jmp = P(jmp): Color_GREEN;
const char *color_call = P(call): Color_BGREEN;
const char *color_cmp = P(cmp): Color_MAGENTA;
const char *color_swi = P(swi): Color_MAGENTA;
const char *color_trap = P(trap): Color_BRED;
const char *color_ret = P(ret): Color_RED;
const char *color_push = P(push): Color_YELLOW;
const char *color_pop = P(pop): Color_BYELLOW;
if (show_lines) ocols += 10; // XXX
if (show_offset) ocols += 14;
lcols = ocols+2;
@ -236,8 +251,8 @@ toro:
r_cons_printf ("%c %s", ((f&&f->type==R_ANAL_FCN_TYPE_FCN)
&&f->addr==at)?' ':'|',refline);
if (show_color)
r_cons_printf (Color_TURQOISE"; %s XREF 0x%08"PFMT64x" (%s)"Color_RESET"\n",
refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
r_cons_printf ("%s; %s XREF 0x%08"PFMT64x" (%s)"Color_RESET"\n",
pal_comment, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
fun?fun->name:"unk");
else r_cons_printf ("; %s XREF 0x%08"PFMT64x" (%s)\n",
@ -277,7 +292,7 @@ toro:
if (mycols + linelen + 10 > core->cons->columns)
mycols = 0;
mycols /= 2;
if (show_color) r_cons_strcat (Color_TURQOISE);
if (show_color) r_cons_strcat (pal_comment);
r_cons_strcat (" ; ");
// XXX: always prefix with ; the comments
// if (*comment != ';') r_cons_strcat (" ; ");
@ -289,7 +304,7 @@ toro:
/* flag one */
if (item && item->comment && ocomment != item->comment) {
if (show_color) r_cons_strcat (Color_TURQOISE);
if (show_color) r_cons_strcat (pal_comment);
r_cons_newline ();
r_cons_strcat (" ; ");
r_cons_strcat_justify (item->comment, mycols, ';');
@ -408,7 +423,7 @@ toro:
{
RFlagItem *item = r_flag_get_i (core->flags, analop.jump);
if (item && item->comment) {
if (show_color) r_cons_strcat (Color_TURQOISE);
if (show_color) r_cons_strcat (pal_comment);
r_cons_printf (" ; ref to %s: %s\n", item->name, item->comment);
if (show_color) r_cons_strcat (Color_RESET);
}
@ -592,38 +607,38 @@ toro:
if (show_color) {
switch (analop.type) {
case R_ANAL_OP_TYPE_NOP:
r_cons_printf (Color_BLUE);
r_cons_printf (color_nop);
break;
case R_ANAL_OP_TYPE_JMP:
case R_ANAL_OP_TYPE_CJMP:
case R_ANAL_OP_TYPE_UJMP:
r_cons_printf (Color_GREEN);
r_cons_printf (color_jmp);
break;
case R_ANAL_OP_TYPE_CMP:
r_cons_printf (Color_BMAGENTA);
r_cons_printf (color_cmp);
break;
case R_ANAL_OP_TYPE_UCALL:
case R_ANAL_OP_TYPE_CALL:
r_cons_printf (Color_BGREEN);
r_cons_printf (color_call);
break;
case R_ANAL_OP_TYPE_SWI:
r_cons_printf (Color_MAGENTA);
r_cons_printf (color_swi);
break;
case R_ANAL_OP_TYPE_ILL:
case R_ANAL_OP_TYPE_TRAP:
r_cons_printf (Color_BRED);
r_cons_printf (color_trap);
break;
case R_ANAL_OP_TYPE_RET:
r_cons_printf (Color_RED);
r_cons_printf (color_ret);
break;
case R_ANAL_OP_TYPE_PUSH:
case R_ANAL_OP_TYPE_UPUSH:
case R_ANAL_OP_TYPE_LOAD:
r_cons_printf (Color_YELLOW);
r_cons_printf (color_push);
break;
case R_ANAL_OP_TYPE_POP:
case R_ANAL_OP_TYPE_STORE:
r_cons_printf (Color_BYELLOW);
r_cons_printf (color_pop);
break;
}
}
@ -709,8 +724,8 @@ toro:
while (len--)
r_cons_strcat (" ");
if (show_color)
r_cons_printf (Color_TURQOISE
" ; %s"Color_RESET"%s", sl, pre);
r_cons_printf ("%s ; %s"Color_RESET"%s",
pal_comment, l, pre);
else r_cons_printf (" ; %s\n%s", sl, pre);
free (osl);
osl = sl;
@ -753,8 +768,10 @@ toro:
if (ccstr) {
RFlagItem *flag = r_flag_get_at (core->flags, cc.jump);
if (show_color)
r_cons_printf ("\n%s%s "Color_TURQOISE"; %s (%s+%d)"Color_RESET,
f?pre:"", refline, ccstr, flag? flag->name: "", (f&&flag)? cc.jump-flag->offset: 0);
r_cons_printf ("\n%s%s %s; %s (%s+%d)"Color_RESET,
f?pre:"", refline, ccstr, flag?
flag->name: "", (f&&flag)?
cc.jump-flag->offset: 0);
else r_cons_printf ("\n%s%s ; %s (%s+%d)",
pre, refline, ccstr,
flag?flag->name:"", flag? cc.jump-flag->offset: 0);
@ -822,7 +839,7 @@ toro:
int c = r_cons_get_column ();
if (c<ocols)
r_cons_memset (' ',ocols-c);
if (show_color) r_cons_strcat (Color_TURQOISE);
if (show_color) r_cons_strcat (color_comment);
r_cons_strcat (" ; ");
// r_cons_strcat_justify (comment, strlen (refline) + 5, ';');
r_cons_strcat (comment);

View File

@ -55,6 +55,19 @@ typedef struct r_cons_palette_t {
char *comment;
char *input;
char *reset;
char *b0x00;
char *b0x7f;
char *b0xff;
char *btext;
char *push;
char *pop;
char *jmp;
char *call;
char *nop;
char *ret;
char *trap;
char *swi;
char *cmp;
} RConsPalette;
typedef void (*RConsEvent)(void *);
@ -241,6 +254,8 @@ R_API void r_cons_any_key();
R_API int r_cons_eof();
R_API int r_cons_palette_init(const unsigned char *pal);
R_API int r_cons_pal_set (const char *key, const char *val);
R_API void r_cons_pal_list ();
R_API int r_cons_get_size(int *rows);
R_API int r_cons_arrow_to_hjkl(int ch);
R_API int r_cons_html_print(const char *ptr);

View File

@ -3,6 +3,7 @@
#include "r_types.h"
#include "r_util.h"
#include "r_cons.h"
#include "r_io.h"
#define R_PRINT_FLAGS_COLOR 0x00000001
@ -47,6 +48,7 @@ typedef struct r_print_t {
RPrintZoom *zoom;
RPrintNameCallback offname;
RStrHT *formats;
RCons *cons;
} RPrint;
#ifdef R_API

View File

@ -355,7 +355,7 @@ R_API int r_socket_block_time (RSocket *s, int block, int sec) {
ioctlsocket (s->fd, FIONBIO, (u_long FAR*)&block);
#endif
if (sec > 0) {
struct timeval tv;
struct timeval tv = {0};
tv.tv_sec = sec;
tv.tv_usec = 0;
if (setsockopt (s->fd, SOL_SOCKET, SO_RCVTIMEO,

View File

@ -102,11 +102,14 @@ R_API void r_print_addr(RPrint *p, ut64 addr) {
p->printf ("%04x:%04x", s, a);
} else
if (p->flags & R_PRINT_FLAGS_COLOR) {
#define P(x) (p->cons &&p->cons->pal.x)?p->cons->pal.x
const char *pre = P(offset): Color_GREEN;
const char *fin = Color_RESET;
#if 0
p->printf("%s0x%08"PFMT64x""Color_RESET"%c ",
r_cons_singleton ()->palette[PAL_ADDRESS], addr, ch);
#endif
p->printf ("0x%08"PFMT64x"%c", addr, ch);
p->printf ("%s0x%08"PFMT64x"%c%s", pre, addr, ch, fin);
} else p->printf ("0x%08"PFMT64x"%c", addr, ch);
}
@ -116,12 +119,20 @@ R_API char *r_print_hexpair(RPrint *p, const char *str, int n) {
const char *s, *lastcol = Color_WHITE;
char *d, *dst = (char *)malloc ((strlen (str)+2)*32);
int colors = p->flags & R_PRINT_FLAGS_COLOR;
const char *color_0x00, *color_0x7f, *color_0xff, *color_text;
/* XXX That's hacky as shit.. but partially works O:) */
/* TODO: Use r_print_set_cursor for win support */
int cur = R_MIN (p->cur, p->ocur);
int ocur = R_MAX (p->cur, p->ocur);
int ch, i;
if (colors) {
#define P(x) (p->cons &&p->cons->pal.x)?p->cons->pal.x
color_0x00 = P(b0x00): Color_GREEN;
color_0x7f = P(b0x7f): Color_YELLOW;
color_0xff = P(b0xff): Color_RED;
color_text = P(btext): Color_MAGENTA;
}
if (p->cur_enabled && cur==-1)
cur = ocur;
ocur++;
@ -146,14 +157,14 @@ R_API char *r_print_hexpair(RPrint *p, const char *str, int n) {
memcat (d, "\x1b[7m");
}
if (colors) {
if (s[0]=='0' && s[1]=='0') lastcol = Color_GREEN;
else if (s[0]=='7' && s[1]=='f') lastcol = Color_YELLOW;
else if (s[0]=='f' && s[1]=='f') lastcol = Color_RED;
if (s[0]=='0' && s[1]=='0') lastcol = color_0x00;
else if (s[0]=='7' && s[1]=='f') lastcol = color_0x7f;
else if (s[0]=='f' && s[1]=='f') lastcol = color_0xff;
else {
ch = r_hex_pair2bin(s);
//sscanf (s, "%02x", &ch); // XXX can be optimized
if (IS_PRINTABLE (ch))
lastcol = Color_MAGENTA;
lastcol = color_text;
}
memcat (d, lastcol);
}
@ -172,14 +183,19 @@ R_API void r_print_byte(RPrint *p, const char *fmt, int idx, ut8 ch) {
r_print_cursor (p, idx, 1);
//if (p->flags & R_PRINT_FLAGS_CURSOR && idx == p->cur) {
if (p->flags & R_PRINT_FLAGS_COLOR) {
#define P(x) (p->cons &&p->cons->pal.x)?p->cons->pal.x
const char *color_0x00 = P(b0x00): Color_GREEN;
const char *color_0x7f = P(b0x7f): Color_YELLOW;
const char *color_0xff = P(b0xff): Color_RED;
const char *color_text = P(btext): Color_MAGENTA;
char *pre = NULL;
switch (ch) {
case 0x00: pre = Color_GREEN; break;
case 0x7F: pre = Color_YELLOW; break;
case 0xFF: pre = Color_RED; break;
case 0x00: pre = color_0x00; break;
case 0x7F: pre = color_0x7f; break;
case 0xFF: pre = color_0xff; break;
default:
if (IS_PRINTABLE (ch))
pre = Color_MAGENTA;
pre = color_text;
}
if (pre) p->printf (pre);
p->printf (fmt, rch);
@ -220,8 +236,7 @@ R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang) {
case 'p':
p->printf ("import struct\nbuf = struct.pack (\"%dB\", ", len);
for (i=0; !p->interrupt && i<len; i++) {
if (!(i%w))
p->printf ("\n");
if (!(i%w)) p->printf ("\n");
r_print_cursor (p, i, 1);
p->printf ("0x%02x%c", buf[i], (i+1<len)?',':')');
r_print_cursor (p, i, 0);
@ -230,7 +245,7 @@ R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang) {
break;
case 'w':
{
ut32 *pbuf = buf;
ut32 *pbuf = (ut32*)buf;
w = 5;
ws = 4;
len /= ws;
@ -248,7 +263,7 @@ R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang) {
break;
case 'd':
{
ut64 *pbuf = buf;
ut64 *pbuf = (ut64*)buf;
w = 3;
ws = 8;
len /= ws;
@ -352,6 +367,10 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
inc = p->cols;
//if (base==64) inc = p->cols/1.2;
k = "";
if (p->flags & R_PRINT_FLAGS_COLOR) {
k = (p->cons && p->cons->pal.offset)? p->cons->pal.offset: "";
}
if (base<32)
if (p->flags & R_PRINT_FLAGS_HEADER) {
ut32 opad = (ut32)(addr >> 32);
@ -364,9 +383,9 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
ut32 s, a;
a = addr & 0xffff;
s = (addr-a)>>4;
snprintf (soff, sizeof (soff), "%04x:%04x", s, a);
snprintf (soff, sizeof (soff), "%s%04x:%04x", p, s, a);
} else {
snprintf (soff, sizeof (soff), "0x%08"PFMT64x, addr);
snprintf (soff, sizeof (soff), "%s0x%08"PFMT64x, p, addr);
}
delta = strlen (soff) - 10;
for (i=0; i<delta; i++)