예제 #1
0
파일: core.c 프로젝트: josdiaz/radare2
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;
}
예제 #2
0
파일: core.c 프로젝트: 0x2F/radare2
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr, *out;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	switch (*str) {
	case '[':
{
		ut64 n = 0LL;
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = NULL;
		if (strlen (str)>5)
			p = strchr (str+5, ':');
		// TODO: honor LE
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			if (str[0] && str[1]) {
				const char *q;
				char *o = strdup (str+1);
				if (o) {
					q = r_num_calc_index (core->num, NULL);
					if (q) {
						if (r_str_replace_char (o, ']', 0)>0) {
							n = r_num_math (core->num, o);
							r_num_calc_index (core->num, q);
						}
					}
					free (o);
				}
			}
		}
		// pop state
		if (ok) *ok = 1;
		ut32 num = 0;
		switch (refsz) {
		case 8:
		case 4:
		case 2:
		case 1:
			(void)r_io_read_at (core->io, n, (ut8*)&num, refsz);
			r_mem_copyendian ((ut8*)&num, (ut8*)&num, refsz, !core->assembler->big_endian);
			return num;
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			return 0LL;
		}
}
		break;
	case '$':
		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 'k':
			if (str[2]!='{') {
				eprintf ("Expected '{' after 'k'.\n");
				break;
			}
			bptr = strdup (str+3);
			ptr = strchr (bptr, '}');
			if (ptr == NULL) {
				// invalid json
				free (bptr);
				break;
			}
			*ptr = '\0';
			ret = 0LL;
			out = sdb_querys (core->sdb, NULL, 0, bptr);
			if (out && *out) {
				if (strstr (out, "$k{")) {
					eprintf ("Recursivity is not permitted here\n");
				} else {
					ret = r_num_math (core->num, out);
				}
			}
			free (bptr);
			free (out);
			return ret;
			break;
		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;
			}
			free (bptr);
			break;
		case 'c': return r_cons_get_size (NULL);
		case 'r': { int rows; r_cons_get_size (&rows); return rows; }
		case 'e': return r_anal_op_is_eob (&op);
		case 'j': return op.jump;
		case 'p': return r_sys_getpid ();
		case 'P': return (core->dbg->pid>0)? core->dbg->pid: 0;
		case 'f': return op.fail;
		case 'm': return op.ptr; // memref
		case 'v': return op.val; // immediate value
		case 'l': return op.size;
		case 'b': return core->blocksize;
		case 's':
			if (core->file) {
				return r_io_desc_size (core->io, core->file->desc);
			}
			return 0LL;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_vget (core->io, core->offset);
			return s? (str[2]=='S'? s->size: s->vaddr): 3;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return r_io_section_vaddr_to_offset (core->io,
				core->offset);
		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_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
		break;
	default:
		if (*str>'A') {
			// NOTE: functions override flags
			RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, str);
			if (fcn) {
				if (ok) *ok = R_TRUE;
				return fcn->addr;
			}
#if 0
			ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str);
			if (addr != 0) {
				ret = addr;
			} else {
				...
			}
#endif
			if ((flag = r_flag_get (core->flags, str))) {
				ret = flag->offset;
				if (ok) *ok = R_TRUE;
			}
		}
		break;
	}
예제 #3
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
    RCore *core = (RCore *)userptr; // XXX ?
    RFlagItem *flag;
    RAnalOp op;
    ut64 ret = 0;
    *ok = 0;
    if (str[0]=='[') {
        int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
        const char *p = strchr (str+1, ':');
        ut64 n;
// TODO: honor endian
        if (p) {
            refsz = atoi (str+1);
            str = p;
        }
// push state
        {
            const char *q = r_num_calc_index (NULL);
            n = r_num_math (core->num, str+1);
            r_num_calc_index (q);
        }
// 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\n", refsz);
            break;
        }
    } else if (str[0]=='$') {
        *ok = 1;
        r_anal_op (core->anal, &op, core->offset, core->block, core->blocksize);
        switch (str[1]) {
        case '{':
        {
            char *ptr, *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;
            }
        }
        return 0;
        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 '?':
            return core->num->value;
        case '$':
            return core->offset;
        case 'o':
            return core->io->off;
        }
    } else if (*str>'A') {
        if ((flag = r_flag_get (core->flags, str))) {
            ret = flag->offset;
            *ok = R_TRUE;
        } else *ok = ret = 0;
    }
    return ret;
}