2009-02-05 21:08:46 +00:00
|
|
|
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
|
|
|
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
2009-02-18 00:43:57 +00:00
|
|
|
#define NPF 6
|
2009-02-09 00:54:09 +00:00
|
|
|
static int printidx = 0;
|
2009-02-18 00:43:57 +00:00
|
|
|
const char *printfmt[] = { "x", "pd", "p8", "pc", "ps", "s esp&&x 64&&dr&&s eip&&pd" };
|
2009-02-09 11:42:54 +00:00
|
|
|
|
|
|
|
static int curset = 0, cursor = -1, ocursor=-1;
|
|
|
|
static int color = 1;
|
|
|
|
static int flags = R_PRINT_FLAGS_ADDRMOD;
|
2009-02-09 00:54:09 +00:00
|
|
|
|
2009-02-18 00:43:57 +00:00
|
|
|
static int marks_init = 0;
|
|
|
|
static u64 marks[256];
|
|
|
|
|
|
|
|
static void r_core_visual_mark(struct r_core_t *core, u8 ch)
|
|
|
|
{
|
|
|
|
if (marks_init==0) {
|
|
|
|
int i;
|
|
|
|
for(i=0;i<255;i++)
|
|
|
|
marks[i] = 0;
|
|
|
|
marks_init = 1;
|
|
|
|
}
|
|
|
|
marks[ch] = core->seek;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void r_core_visual_mark_seek(struct r_core_t *core, u8 ch)
|
|
|
|
{
|
|
|
|
if (marks_init==0) {
|
|
|
|
int i;
|
|
|
|
for(i=0;i<255;i++)
|
|
|
|
marks[i] = 0;
|
|
|
|
marks_init = 1;
|
|
|
|
}
|
|
|
|
if (marks[ch])
|
|
|
|
r_core_seek(core, marks[ch]);
|
|
|
|
}
|
|
|
|
|
2009-02-09 00:54:09 +00:00
|
|
|
/* TODO: use r_cmd here in core->vcmd..optimize over 255 table */
|
|
|
|
int r_core_visual_cmd(struct r_core_t *core, int ch)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-02-09 00:54:09 +00:00
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
switch(ch) {
|
|
|
|
case 'c':
|
2009-02-09 11:42:54 +00:00
|
|
|
curset ^= 1;
|
|
|
|
if (curset) flags|=R_PRINT_FLAGS_CURSOR; // XXX dupped flag imho
|
2009-02-09 00:54:09 +00:00
|
|
|
else flags &= !(flags&R_PRINT_FLAGS_CURSOR);
|
2009-03-11 11:42:11 +00:00
|
|
|
r_print_set_flags(&core->print, flags);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case 'C':
|
2009-02-09 11:42:54 +00:00
|
|
|
color ^= 1;
|
|
|
|
if (color) flags|=R_PRINT_FLAGS_COLOR;
|
2009-02-09 00:54:09 +00:00
|
|
|
else flags &= !(flags&R_PRINT_FLAGS_COLOR);
|
2009-03-11 11:42:11 +00:00
|
|
|
r_print_set_flags(&core->print, flags);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
2009-02-09 11:42:54 +00:00
|
|
|
/* select */
|
2009-02-09 00:54:09 +00:00
|
|
|
case 'H':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
if (ocursor ==-1) ocursor=cursor;
|
|
|
|
cursor--;
|
|
|
|
} else
|
2009-03-12 02:03:18 +00:00
|
|
|
r_core_cmd(core, "s-2", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
2009-02-09 11:42:54 +00:00
|
|
|
case 'J':
|
|
|
|
if (curset) {
|
|
|
|
if (ocursor ==-1) ocursor=cursor;
|
|
|
|
cursor+=16;
|
|
|
|
} else
|
|
|
|
r_core_cmd(core, "s++", 0);
|
|
|
|
break;
|
2009-03-20 21:05:12 +00:00
|
|
|
case 'g':
|
|
|
|
r_core_cmd(core, "s 0", 0);
|
|
|
|
break;
|
|
|
|
case 'G':
|
|
|
|
// TODO: seek to file size
|
|
|
|
//r_core_cmd(core, "s 0", 0);
|
|
|
|
break;
|
2009-02-09 11:42:54 +00:00
|
|
|
case 'K':
|
|
|
|
if (curset) {
|
|
|
|
if (ocursor ==-1) ocursor=cursor;
|
|
|
|
cursor-=16;
|
|
|
|
} else
|
|
|
|
r_core_cmd(core, "s--", 0);
|
|
|
|
break;
|
2009-02-09 00:54:09 +00:00
|
|
|
case 'L':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
if (ocursor ==-1) ocursor=cursor;
|
|
|
|
cursor++;
|
|
|
|
} else
|
2009-03-12 02:03:18 +00:00
|
|
|
r_core_cmd(core, "s+2", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
2009-02-09 11:42:54 +00:00
|
|
|
/* move */
|
2009-02-09 00:54:09 +00:00
|
|
|
case 'h':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
cursor--;
|
|
|
|
ocursor=-1;
|
2009-03-12 02:03:18 +00:00
|
|
|
} else r_core_cmd(core, "s-1", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case 'l':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
cursor++;
|
|
|
|
ocursor=-1;
|
2009-03-12 02:03:18 +00:00
|
|
|
} else r_core_cmd(core, "s+1", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case 'j':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
cursor+=16;
|
|
|
|
ocursor=-1;
|
2009-03-12 02:03:18 +00:00
|
|
|
} else r_core_cmd(core, "s+16", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case 'k':
|
2009-02-09 11:42:54 +00:00
|
|
|
if (curset) {
|
|
|
|
cursor-=16;
|
|
|
|
ocursor=-1;
|
|
|
|
} else r_core_cmd(core, "s- 16", 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
2009-02-18 00:43:57 +00:00
|
|
|
case 's':
|
|
|
|
r_core_cmd(core, "ds", 0);
|
|
|
|
r_core_cmd(core, ".dr", 0);
|
|
|
|
r_core_cmd(core, "s eip", 0);
|
|
|
|
break;
|
2009-02-09 00:54:09 +00:00
|
|
|
case 'p':
|
|
|
|
printidx++;
|
|
|
|
break;
|
|
|
|
case 'P':
|
|
|
|
printidx--;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
r_core_block_size( core, core->blocksize-1);
|
|
|
|
break;
|
2009-02-18 00:43:57 +00:00
|
|
|
case 'm':
|
|
|
|
r_core_visual_mark(core, r_cons_readchar());
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
r_core_visual_mark_seek(core, r_cons_readchar());
|
|
|
|
break;
|
2009-02-09 00:54:09 +00:00
|
|
|
case '+':
|
2009-03-12 12:30:32 +00:00
|
|
|
r_core_block_size(core, core->blocksize+1);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case '/':
|
2009-03-12 12:30:32 +00:00
|
|
|
r_core_block_size(core, core->blocksize-=16);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case '*':
|
2009-03-12 12:30:32 +00:00
|
|
|
r_core_block_size(core, core->blocksize+=16);
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
r_core_seek_align(core, core->blocksize, 1);
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
r_core_seek_align(core, core->blocksize, -1);
|
2009-02-09 00:54:09 +00:00
|
|
|
break;
|
|
|
|
case ':':
|
|
|
|
r_cons_fgets(buf, 1023, 0, NULL);
|
|
|
|
r_core_cmd(core, buf, 0);
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
r_cons_clear00();
|
|
|
|
r_cons_printf(
|
|
|
|
"\nVisual mode help:\n\n"
|
2009-03-12 12:30:32 +00:00
|
|
|
" >||< - seek aligned to block size\n"
|
2009-02-09 00:54:09 +00:00
|
|
|
" hjkl - move around\n"
|
|
|
|
" HJKL - move around faster\n"
|
|
|
|
" P||p - rotate print modes\n"
|
|
|
|
" /*+- - change block size\n"
|
|
|
|
" :cmd - run radare command\n"
|
|
|
|
" q - back to radare shell\n");
|
|
|
|
r_cons_flush();
|
|
|
|
r_cons_any_key();
|
|
|
|
break;
|
|
|
|
case 'q':
|
2009-02-09 11:42:54 +00:00
|
|
|
case 'Q':
|
2009-02-09 00:54:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-02-09 11:42:54 +00:00
|
|
|
void r_core_visual_prompt(struct r_core_t *core)
|
|
|
|
{
|
|
|
|
r_cons_printf("[0x%08llx] %s\n", core->seek, printfmt[printidx%NPF]);
|
|
|
|
}
|
|
|
|
|
2009-02-09 00:54:09 +00:00
|
|
|
int r_core_visual(struct r_core_t *core, const char *input)
|
|
|
|
{
|
2009-03-27 00:16:27 +00:00
|
|
|
const char *cmdprompt;
|
|
|
|
const char *vi;
|
|
|
|
u64 scrseek;
|
2009-02-09 00:54:09 +00:00
|
|
|
int ch;
|
|
|
|
|
2009-03-27 00:16:27 +00:00
|
|
|
vi = r_config_get(&core->config, "cmd.visual");
|
2009-03-12 02:03:18 +00:00
|
|
|
if (vi) r_core_cmd(core, vi, 0);
|
|
|
|
|
2009-02-09 00:54:09 +00:00
|
|
|
while(input[0]) {
|
|
|
|
if (!r_core_visual_cmd(core, input[0])) {
|
|
|
|
r_cons_clear00();
|
2009-02-09 11:42:54 +00:00
|
|
|
r_core_cmd(core, printfmt[printidx%NPF], 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
r_cons_flush();
|
|
|
|
r_cons_any_key();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
input = input + 1;
|
|
|
|
}
|
|
|
|
|
2009-02-09 11:42:54 +00:00
|
|
|
color = r_config_get_i(&core->config, "scr.color");
|
2009-02-09 00:54:09 +00:00
|
|
|
do {
|
2009-03-27 00:16:27 +00:00
|
|
|
scrseek = r_num_math(&core->num,
|
|
|
|
r_config_get(&core->config, "scr.seek"));
|
|
|
|
if (scrseek != 0LL) {
|
|
|
|
r_core_seek (core, scrseek);
|
|
|
|
// TODO: read?
|
|
|
|
}
|
|
|
|
cmdprompt = r_config_get (&core->config, "cmd.vprompt");
|
2009-02-18 00:43:57 +00:00
|
|
|
if (cmdprompt && cmdprompt[0])
|
|
|
|
r_core_cmd(core, cmdprompt, 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
r_cons_clear00();
|
2009-03-11 11:42:11 +00:00
|
|
|
r_print_set_cursor(&core->print, curset, ocursor, cursor);
|
2009-02-09 11:42:54 +00:00
|
|
|
r_core_visual_prompt(core);
|
|
|
|
r_core_cmd(core, printfmt[printidx%NPF], 0);
|
2009-02-09 00:54:09 +00:00
|
|
|
r_cons_flush();
|
|
|
|
ch = r_cons_readchar();
|
|
|
|
} while (r_core_visual_cmd(core, ch));
|
2009-02-18 00:43:57 +00:00
|
|
|
|
2009-02-05 21:08:46 +00:00
|
|
|
return 0;
|
|
|
|
}
|