2012-02-27 01:40:27 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2012 // pancake<nopcode.org> */
|
|
|
|
|
|
|
|
static int cmd_seek(void *data, const char *input) {
|
|
|
|
RCore *core = (RCore *)data;
|
|
|
|
char *cmd, *p;
|
|
|
|
ut64 off;
|
|
|
|
|
|
|
|
if (*input=='r') {
|
|
|
|
if (input[1] && input[2]) {
|
|
|
|
if (core->io->debug) {
|
|
|
|
off = r_debug_reg_get (core->dbg, input+2);
|
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek (core, off, 1);
|
|
|
|
}// else eprintf ("cfg.debug is false\n");
|
|
|
|
} else eprintf ("Usage: 'sr pc' ; seek to register\n");
|
|
|
|
} else
|
|
|
|
if (*input) {
|
|
|
|
int sign = 1;
|
|
|
|
st32 delta = (input[1]==' ')? 2: 1;
|
|
|
|
off = r_num_math (core->num, input + delta);
|
2012-08-03 00:05:50 +00:00
|
|
|
if ((st64)off<0) off = -off; // hack to fix s-2;s -2
|
2012-02-27 01:40:27 +00:00
|
|
|
if (isalpha (input[delta]) && off == 0) {
|
2012-07-12 02:21:56 +00:00
|
|
|
if (delta==1 && !r_flag_get (core->flags, input+delta)) {
|
2012-08-02 00:44:46 +00:00
|
|
|
eprintf ("Cannot find address for '%s'\n", input+delta);
|
2012-02-27 01:40:27 +00:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (input[0]==' ') {
|
|
|
|
switch (input[1]) {
|
|
|
|
case '-': sign=-1;
|
|
|
|
case '+': input++; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (*input) {
|
|
|
|
case 'C':
|
2012-07-12 02:21:56 +00:00
|
|
|
if (input[1]=='*') {
|
|
|
|
r_core_cmd0 (core, "C*~^CC");
|
|
|
|
} else
|
2012-02-27 01:40:27 +00:00
|
|
|
if (input[1]==' ') {
|
|
|
|
int n = 0;
|
|
|
|
RListIter *iter;
|
|
|
|
RMetaItem *d, *item = NULL;
|
|
|
|
/* seek to comment */
|
|
|
|
r_list_foreach (core->anal->meta->data, iter, d) {
|
|
|
|
if (d->type == R_META_TYPE_COMMENT) {
|
|
|
|
if (strstr (d->str, input+2)) {
|
|
|
|
if (n==1) {
|
|
|
|
r_cons_printf ("0x%08"PFMT64x" %s\n", item->from, item->str);
|
|
|
|
r_cons_printf ("0x%08"PFMT64x" %s\n", d->from, d->str);
|
|
|
|
} else if (n>1) {
|
|
|
|
r_cons_printf ("0x%08"PFMT64x" %s\n", d->from, d->str);
|
|
|
|
}
|
|
|
|
item = d;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (n) {
|
|
|
|
case 0:
|
|
|
|
eprintf ("No matching comments\n");
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
r_cons_printf ("0x%08"PFMT64x" %s\n", item->from, item->str);
|
2012-07-12 02:21:56 +00:00
|
|
|
off = item->from;
|
2012-02-27 01:40:27 +00:00
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek (core, off, 1);
|
|
|
|
r_core_block_read (core, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-07-12 02:21:56 +00:00
|
|
|
} else eprintf ("Usage: sC[?*] comment-grep\n"
|
|
|
|
"sC* list all comments\n"
|
|
|
|
"sC const seek to comment matching 'const'\n");
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
|
|
|
case ' ':
|
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek (core, off*sign, 1);
|
|
|
|
r_core_block_read (core, 0);
|
|
|
|
break;
|
|
|
|
case '/':
|
|
|
|
{
|
|
|
|
const char *pfx = r_config_get (core->config, "search.prefix");
|
|
|
|
int kwidx = (int)r_config_get_i (core->config, "search.kwidx")-1;
|
|
|
|
if (kwidx<0) kwidx = 0;
|
2012-06-10 21:58:34 +00:00
|
|
|
switch (input[1]) {
|
|
|
|
case 'x':
|
|
|
|
//r_core_seek (core, off+1, 0);
|
|
|
|
eprintf ("s+1;.%s ; ? %s%d_0 ; ?! s %s%d_0\n", input, pfx, kwidx, pfx, kwidx);
|
|
|
|
r_core_cmdf (core, "s+1;.%s ; ? %s%d_0 ; ?! s %s%d_0", input, pfx, kwidx, pfx, kwidx);
|
|
|
|
break;
|
|
|
|
case ' ':
|
|
|
|
//r_core_seek (core, off+1, 0);
|
|
|
|
eprintf ("s+1;.%s ; ? %s%d_0 ; ?! s %s%d_0\n", input, pfx, kwidx, pfx, kwidx);
|
|
|
|
r_core_cmdf (core, "s+1;.%s ; ? %s%d_0 ; ?! s %s%d_0", input, pfx, kwidx, pfx, kwidx);
|
|
|
|
break;
|
|
|
|
}
|
2012-02-27 01:40:27 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '*':
|
|
|
|
r_io_sundo_list (core->io);
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
if (input[1]!='\0') {
|
|
|
|
delta = (input[1]=='+')? core->blocksize: off;
|
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek_delta (core, delta);
|
|
|
|
} else {
|
|
|
|
off = r_io_sundo_redo (core->io);
|
|
|
|
if (off != UT64_MAX)
|
|
|
|
r_core_seek (core, off, 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
if (input[1]!='\0') {
|
|
|
|
if (input[1]=='-') delta = -core->blocksize; else delta = -off;
|
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek_delta (core, delta);
|
|
|
|
} else {
|
|
|
|
off = r_io_sundo (core->io, core->offset);
|
|
|
|
if (off != UT64_MAX)
|
|
|
|
r_core_seek (core, off, 0);
|
|
|
|
}
|
|
|
|
break;
|
2012-09-28 00:20:52 +00:00
|
|
|
case 'n':
|
2012-02-27 01:40:27 +00:00
|
|
|
r_io_sundo_push (core->io, core->offset);
|
2012-09-28 00:20:52 +00:00
|
|
|
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
2012-09-28 00:20:52 +00:00
|
|
|
case 'N':
|
2012-02-27 01:40:27 +00:00
|
|
|
r_io_sundo_push (core->io, core->offset);
|
2012-09-28 00:20:52 +00:00
|
|
|
r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
|
2012-02-27 01:40:27 +00:00
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
off = core->blocksize;
|
|
|
|
if (input[1]&&input[2]) {
|
|
|
|
cmd = strdup (input);
|
|
|
|
p = strchr (cmd+2, ' ');
|
|
|
|
if (p) {
|
|
|
|
off = r_num_math (core->num, p+1);;
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
cmd[0] = 's';
|
|
|
|
// perform real seek if provided
|
2012-09-19 12:08:44 +00:00
|
|
|
r_cmd_call (core->rcmd, cmd);
|
2012-02-27 01:40:27 +00:00
|
|
|
free (cmd);
|
|
|
|
}
|
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_seek_align (core, off, 0);
|
|
|
|
break;
|
|
|
|
case 'b':
|
2012-08-03 00:05:50 +00:00
|
|
|
if (off == 0)
|
|
|
|
off = core->offset;
|
2012-02-27 01:40:27 +00:00
|
|
|
r_io_sundo_push (core->io, core->offset);
|
|
|
|
r_core_anal_bb_seek (core, off);
|
|
|
|
break;
|
2012-09-28 00:20:52 +00:00
|
|
|
case 'o':
|
2012-02-27 01:40:27 +00:00
|
|
|
{
|
|
|
|
RAnalOp op;
|
|
|
|
int ret = r_anal_op (core->anal, &op,
|
|
|
|
core->offset, core->block, core->blocksize);
|
|
|
|
r_core_seek_delta (core, ret);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
r_cons_printf (
|
|
|
|
"Usage: s[+-] [addr]\n"
|
|
|
|
" s 0x320 ; seek to this address\n"
|
|
|
|
" s- ; undo seek\n"
|
|
|
|
" s+ ; redo seek\n"
|
|
|
|
" s* ; list undo seek history\n"
|
|
|
|
" s++ ; seek blocksize bytes forward\n"
|
|
|
|
" s-- ; seek blocksize bytes backward\n"
|
|
|
|
" s+ 512 ; seek 512 bytes forward\n"
|
|
|
|
" s- 512 ; seek 512 bytes backward\n"
|
|
|
|
" sa [[+-]a] [asz] ; seek asz (or bsize) aligned to addr\n"
|
2012-09-28 00:20:52 +00:00
|
|
|
" sn|sN ; seek next/prev scr.nkey\n"
|
2012-02-27 01:40:27 +00:00
|
|
|
" s/ DATA ; search for next occurrence of 'DATA'\n"
|
2012-07-12 01:55:09 +00:00
|
|
|
" s/x 9091 ; search for next occurrence of \\x90\\x91\n"
|
2012-02-27 01:40:27 +00:00
|
|
|
" sb ; seek aligned to bb start\n"
|
2012-08-03 00:05:50 +00:00
|
|
|
//" sp [page] ; seek page N (page = block)\n"
|
2012-09-28 00:20:52 +00:00
|
|
|
" so ; seek to next opcode\n"
|
2012-02-27 01:40:27 +00:00
|
|
|
" sC str ; seek to comment matching given string\n"
|
|
|
|
" sr pc ; seek to register\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
|
|
|
|
return 0;
|
|
|
|
}
|