Exemple #1
0
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 program counter register\n");
    } else if (*input) {
        const char *inputnum = strchr (input+1, ' ');
        int sign = 1;
        inputnum = inputnum? inputnum+1: input+1;
        off = r_num_math (core->num, inputnum);
        if (*inputnum== '-') off = -off;
#if 0
        if (input[0]!='/' && inputnum && isalpha (inputnum[0]) && off == 0) {
            if (!r_flag_get (core->flags, inputnum)) {
                eprintf ("Cannot find address for '%s'\n", inputnum);
                return R_FALSE;
            }
        }
#endif
        if (input[0]==' ') {
            switch (input[1]) {
            case '-':
                sign=-1;
            case '+':
                input++;
                break;
            }
        }

        switch (*input) {
        case 'C':
            if (input[1]=='*') {
                r_core_cmd0 (core, "C*~^\"CC");
            } else if (input[1]==' ') {
                typedef struct {
                    ut64 addr;
                    char *str;
                } MetaCallback;
                int count = 0;
                MetaCallback cb = { 0, NULL };
                ut64 addr;
                char key[128];
                const char *val, *comma;
                char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
                char *str, *next, *cur = list;
                if (list) {
                    for (;;) {
                        cur = sdb_anext (cur, &next);
                        addr = sdb_atoi (cur);
                        snprintf (key, sizeof (key)-1, "meta.C.0x%"PFMT64x, addr);
                        val = sdb_const_get (core->anal->sdb_meta, key, 0);
                        if (val) {
                            comma = strchr (val, ',');
                            if (comma) {
                                str = (char *)sdb_decode (comma+1, 0);
                                if (strstr (str, input+2)) {
                                    r_cons_printf ("0x%08"PFMT64x"  %s\n", addr, str);
                                    count++;
                                    cb.addr = addr;
                                    free (cb.str);
                                    cb.str = str;
                                } else free (str);
                            }
                        } else eprintf ("sdb_const_get key not found '%s'\n", key);
                        if (!next)
                            break;
                        cur = next;
                    }
                }

                switch (count) {
                case 0:
                    eprintf ("No matching comments\n");
                    break;
                case 1:
                    off = cb.addr;
                    r_io_sundo_push (core->io, core->offset);
                    r_core_seek (core, off, 1);
                    r_core_block_read (core, 0);
                    break;
                default:
                    eprintf ("Too many results\n");
                    break;
                }
                free (cb.str);
            } else eprintf ("Usage: sC[?*] comment-grep\n"
                                "sC*        list all comments\n"
                                "sC const   seek to comment matching 'const'\n");
            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");
//kwidx cfg var is ignored
            int kwidx = core->search->n_kws; //(int)r_config_get_i (core->config, "search.kwidx")-1;
            if (kwidx<0) kwidx = 0;
            switch (input[1]) {
            case ' ':
            case 'x':
                r_config_set_i (core->config, "search.count", 1);
                r_core_cmdf (core, "s+1; p8 ; .%s;s-1;s %s%d_0;f-%s%d_0",
                             input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
                r_config_set_i (core->config, "search.count", 0);
                break;
            default:
                eprintf ("unknown search method\n");
                break;
            }
        }
        break;
        case '.':
            for (input++; *input=='.'; input++);
            r_core_seek_base (core, input);
            break;
        case '*':
            r_io_sundo_list (core->io);
            break;
        case '+':
            if (input[1]!='\0') {
                int 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') {
                int 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 (core->io, core->offset);
                if (off != UT64_MAX)
                    r_core_seek (core, off, 0);
            }
            break;
        case 'n':
            r_io_sundo_push (core->io, core->offset);
            r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
            break;
        case 'p':
            r_io_sundo_push (core->io, core->offset);
            r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
            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
                r_cmd_call (core->rcmd, cmd);
                free (cmd);
            }
            r_io_sundo_push (core->io, core->offset);
            r_core_seek_align (core, off, 0);
            break;
        case 'b':
            if (off == 0)
                off = core->offset;
            r_io_sundo_push (core->io, core->offset);
            r_core_anal_bb_seek (core, off);
            break;
        case 'f':
        {
            RAnalFunction *fcn = r_anal_fcn_find (core->anal, core->offset, 0);
            if (fcn)
                r_core_seek (core, fcn->addr+fcn->size, 1);
        }
        break;
        case 'o':
        {
            RAnalOp op;
            int val=0, ret, i, n = r_num_math (core->num, input+1);
            if (n==0) n = 1;
            if (n<0) {
                int ret = prevopsz (core, n);
                ret = r_anal_op (core->anal, &op,
                                 core->offset, core->block, core->blocksize);
                val += ret;
            } else
                for (val=i=0; i<n; i++) {
                    ret = r_anal_op (core->anal, &op,
                                     core->offset, core->block, core->blocksize);
                    if (ret<1)
                        break;
                    r_core_seek_delta (core, ret);
                    val += ret;
                }
            core->num->value = val;
        }
        break;
        case 'g':
        {
            RIOSection *s = r_io_section_get (core->io,
                                              r_io_section_vaddr_to_offset (core->io,
                                                      core->offset));
            if (s) r_core_seek (core, s->vaddr, 1);
            else r_core_seek (core, 0, 1);
        }
        break;
        case 'G':
        {
            RIOSection *s = r_io_section_get (core->io,
                                              r_io_section_vaddr_to_offset (core->io,
                                                      core->offset));
            // XXX: this +2 is a hack. must fix gap between sections
            if (s) r_core_seek (core, s->vaddr+s->size+2, 1);
            else r_core_seek (core, core->file->size, 1);
        }
        break;
        case '?':
            r_cons_printf (
                "|Usage: s[+-] [addr]\n"
                "| s                 print current address\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"
                "| sg/sG             seek begin (sg) or end (sG) of section or file\n"
                "| s.hexoff          Seek honoring a base from core->offset\n"
                "| sa [[+-]a] [asz]  seek asz (or bsize) aligned to addr\n"
                "| sn/sp             seek next/prev scr.nkey\n"
                "| s/ DATA           search for next occurrence of 'DATA'\n"
                "| s/x 9091          search for next occurrence of \\x90\\x91\n"
                "| sb                seek aligned to bb start\n"
                //"| sp [page]  seek page N (page = block)\n"
                "| so [num]          seek to N next opcode(s)\n"
                "| sf                seek to next function (f->addr+f->size)\n"
                "| 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;
}
Exemple #2
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	if (*str=='[') {
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = strchr (str+5, ':');
		ut64 n;
		// TODO: honor endian
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			char *o = strdup (str+1);
			const char *q = r_num_calc_index (core->num, NULL);
			r_str_replace_char (o, ']', 0);
			n = r_num_math (core->num, o);
			r_num_calc_index (core->num, q);
			free (o);
		}
		// pop state
		switch (refsz) {
		case 8: {
			ut64 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 4: {
			ut32 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 2: {
			ut16 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 1: {
			ut8 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			break;
		}
	} else
	if (str[0]=='$') {
		if (ok) *ok = 1;
		// TODO: group analop-dependant vars after a char, so i can filter
		r_anal_op (core->anal, &op, core->offset,
			core->block, core->blocksize);
		switch (str[1]) {
		case '.': // can use pc, sp, a0, a1, ...
			return r_debug_reg_get (core->dbg, str+2);
		case '{':
			bptr = strdup (str+2);
			ptr = strchr (bptr, '}');
			if (ptr != NULL) {
				ut64 ret;
				ptr[0] = '\0';
				ret = r_config_get_i (core->config, bptr);
				free (bptr);
				return ret;
			}
			break;
		case 'h': {
			int rows;
			r_cons_get_size (&rows);
			return rows;
			}
		case 'e': return op.eob;
		case 'j': return op.jump;
		case 'f': return op.fail;
		case 'r': return op.ref;
		case 'l': return op.length;
		case 'b': return core->blocksize;
		case 's': return core->file->size;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_get (core->io, 
				r_io_section_vaddr_to_offset (core->io,
				core->offset));
			return s? (str[2]=='S'? s->size: s->offset): 0;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return core->io->off;
		case 'C': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CALL);
		case 'J': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CODE);
		case 'D': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_DATA);
		case 'X': return getref (core, atoi (str+2), 'x',
				R_ANAL_REF_TYPE_CALL);
		case 'I':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
	} else
	if (*str>'A') {
		if ((flag = r_flag_get (core->flags, str))) {
			ret = flag->offset;
			if (ok) *ok = R_TRUE;
		}
	}
	return ret;
}