Example #1
0
R_API int r_anal_xrefs_from (RAnal *anal, RList *list, const char *kind, const RAnalRefType type, ut64 addr) {
	char *next, *s, *str, *ptr, key[256];
	RAnalRef *ref = NULL;
	if (addr == UT64_MAX) {
		_type = type;
		_list = list;
		_kpfx = r_str_newf ("xref.%s", analref_toString (type));
		sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_any, anal);
		free (_kpfx);
		return true;
	}
	XREFKEY(key, sizeof (key), kind, type, addr);
	str = sdb_get (DB, key, 0);
	if (!str) {
		return false;
	}
	for (next = ptr = str; next; ptr = next) {
		s = sdb_anext (ptr, &next);
		if (!(ref = r_anal_ref_new ())) {
			return false;
		}
		ref->addr = r_num_get (NULL, s);
		ref->at = addr;
		ref->type = type;
		r_list_append (list, ref);
	}
	free (str);
	return true;
}
Example #2
0
File: fmt.c Project: a0zy/radare2
// TODO: return false if array length != fmt length
SDB_API int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru) {
	int n, idx = 0;
	char *next, *str, *ptr, *word, *e_str;
	if (!_str || !*_str || !fmt)
		return 0;
	str = ptr = strdup (_str);
	for (; *fmt; fmt++) {
		word = sdb_anext (ptr, &next);
		if (!word || !*word)
			break;
		n = 4; // ALIGN
		switch (*fmt) {
		case 'b': *((ut8*)(stru + idx)) = (ut8)sdb_atoi (word); break;
		case 'd': *((int*)(stru + idx)) = (int)sdb_atoi (word); break;
		case 'q': *((ut64*)(stru + idx)) = sdb_atoi (word); n=8; break;
		case 'h': *((short*)(stru + idx)) = (short)sdb_atoi (word); break;
		case 's':
			e_str = (char*)sdb_decode (word, 0);
			*((char**)(stru + idx)) = (char*)strdup (e_str?e_str:word);
			free (e_str);
			break;
		case 'z':
			*((char**)(stru + idx)) = (char*)strdup (word);
			break;
		case 'p': *((void**)(stru + idx)) = (void*)(size_t)sdb_atoi (word);
			break;
		}
		idx += R_MAX((long)sizeof (void*), n); // align
		if (!next)
			break;
		ptr = next;
	}
	free (str);
	return 1;
}
Example #3
0
R_API RAnalHint *r_anal_hint_from_string(RAnal *a, ut64 addr, const char *str) {
	char *r, *nxt, *nxt2;
	int token = 0;
	RAnalHint *hint = R_NEW0 (RAnalHint);
	if (!hint) {
		return NULL;
	}
	hint->jump = UT64_MAX;
	hint->fail = UT64_MAX;
	char *s = strdup (str);
	if (!s) {
		free (hint);
		return NULL;
	}
	hint->addr = addr;
	token = *s;
	for (r = s; ; r = nxt2) {
		r = sdb_anext (r, &nxt);
		if (!nxt) {
			break;
		}
		sdb_anext (nxt, &nxt2); // tokenize value
		if (token) {
			switch (token) {
			case 'i': hint->immbase = sdb_atoi (nxt); break;
			case 'j': hint->jump = sdb_atoi (nxt); break;
			case 'f': hint->fail = sdb_atoi (nxt); break;
			case 'p': hint->ptr  = sdb_atoi (nxt); break;
			case 'b': hint->bits = sdb_atoi (nxt); break;
			case 's': hint->size = sdb_atoi (nxt); break;
			case 'S': hint->syntax = (char*)sdb_decode (nxt, 0); break;
			case 'o': hint->opcode = (char*)sdb_decode (nxt, 0); break;
			case 'O': hint->offset = (char*)sdb_decode (nxt, 0); break;
			case 'e': hint->esil = (char*)sdb_decode (nxt, 0); break;
			case 'a': hint->arch = (char*)sdb_decode (nxt, 0); break;
			case 'h': hint->high = sdb_atoi (nxt); break;
			}
		}
		if (!nxt || !nxt2) {
			break;
		}
		token = *nxt2;
	}
	free (s);
	return hint;
}
Example #4
0
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size, const char *str) {
	char key[100], *dtr, *s, *p, *next;
#if 0
	char key2[100];
#endif
	const char *ptr;
	int i;
	if (size == UT64_MAX) {
		// FULL CLEANUP
		// XXX: this thing ignores the type
		if (type == R_META_TYPE_ANY) {
			sdb_reset (DB);
		} else {
			snprintf (key, sizeof (key)-1, "meta.%c.count", type);
			int last = (ut64)sdb_num_get (DB, key, NULL)/K;
			for (i=0; i<last; i++) {
				snprintf (key, sizeof (key)-1, "meta.%c.%d", type, i);
				dtr = sdb_get (DB, key, 0);
				for (p = dtr; p; p = next) {
					s = sdb_anext (p, &next);
					snprintf (key, sizeof (key)-1,
						"meta.%c.0x%"PFMT64x,
						type, sdb_atoi (s));
					eprintf ("--> %s\n", key);
					sdb_unset (DB, key, 0);
					if (!next) break;
				}
				free (dtr);
			}
		}
		return false;
	}
	meta_inrange_del (a, addr, size);
	snprintf (key, sizeof (key)-1, type == R_META_TYPE_COMMENT ?
		"meta.C.0x%"PFMT64x : "meta.0x%"PFMT64x, addr);
	ptr = sdb_const_get (DB, key, 0);
	if (ptr) {
		sdb_unset (DB, key, 0);
		#if 0
		// This code is wrong, but i guess it's necessary in case type is ANY
		for (i=0; ptr[i]; i++) {
			if (ptr[i] != SDB_RS) {
				snprintf (key2, sizeof (key2)-1,
					"meta.%c.0x%"PFMT64x, ptr[i], addr);
					printf ("UNSET (%s)\n", key2);
				sdb_unset (DB, key2, 0);
			}
		}
		#endif
	}
	sdb_unset (DB, key, 0);
	return false;
}
Example #5
0
R_API int r_anal_xrefs_from (RAnal *anal, RList *list, const char *kind, const char *type, ut64 addr) {
	char *s, *str, *ptr, key[256];
	RAnalRef *ref = NULL;
	int hasnext = 1;
	snprintf (key, sizeof (key), "%s.%s.0x%"PFMT64x, kind, type, addr);
	str = sdb_get (DB, key, 0);
	if (!str) return R_FALSE;
	for (ptr=str; hasnext; ptr = (char *)sdb_anext (s)) {
		s = sdb_astring (ptr, &hasnext);
		if (!(ref = r_anal_ref_new ()))
			return R_FALSE;
		ref->addr = addr;
		ref->at = r_num_get (NULL, s);
		ref->type = (!strcmp (type, "code"))?'C':'d'; // XXX
		r_list_append (list, ref);
	}
	free (str);
	return R_TRUE;
}
Example #6
0
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size, const char *str) {
	char key[100], key2[100], *dtr, *s, *p, *next;
	const char *ptr;
	int i;
	if (size == UT64_MAX) {
		// FULL CLEANUP
		// XXX: this thing ignores the type
		if (type == R_META_TYPE_ANY) {
			sdb_reset (DB);
		} else {
			snprintf (key, sizeof (key)-1, "meta.%c", type);
			dtr = sdb_get (DB, key, 0);
			for (p = dtr; p; p = next) {
				s = sdb_anext (p, &next);
				snprintf (key, sizeof (key)-1,
					"meta.%c.0x%"PFMT64x,
					type, sdb_atoi (s));
				eprintf ("--> %s\n", key);
				sdb_unset (DB, key, 0);
				if (!next) break;
			}
			free (dtr);
		}
		return R_FALSE;
	}
	meta_inrange_del (a, addr, size);
	snprintf (key, sizeof (key)-1, type==R_META_TYPE_COMMENT ? "meta.C.0x%"PFMT64x : "meta.0x%"PFMT64x, addr);
	ptr = sdb_const_get (DB, key, 0);
	if (ptr) {
		for (i=0; ptr[i]; i++) {
			if (ptr[i] != SDB_RS) {
				snprintf (key2, sizeof (key2)-1,
					"meta.%c.0x%"PFMT64x, ptr[i], addr);
				sdb_unset (DB, key2, 0);
			}
		}
	}
	sdb_unset (DB, key, 0);
	return R_FALSE;
}
Example #7
0
R_API RAnalHint *r_anal_hint_from_string(RAnal *a, ut64 addr, const char *str) {
	char *r, *nxt;
	int token = 0;
	RAnalHint *hint = R_NEW0 (RAnalHint);
	char *s;
	if (!hint)
		return NULL;
	
	s = strdup (str);
	if (!s) {
		R_FREE (hint);
		return NULL;
	}

	hint->addr = addr;
	for (r = s; ; r = nxt) {
		r = sdb_anext (r, &nxt);
		if (token) {
			switch (token) {
			case 'j': hint->jump = sdb_atoi (r); break;
			case 'f': hint->fail = sdb_atoi (r); break;
			case 'p': hint->ptr  = sdb_atoi (r); break;
			case 'b': hint->bits = sdb_atoi (r); break;
			case 's': hint->size = sdb_atoi (r); break;
			case 'S': hint->syntax = (char*)sdb_decode (r, 0); break;
			case 'o': hint->opcode = (char*)sdb_decode (r, 0); break;
			case 'e': hint->esil = (char*)sdb_decode (r, 0); break;
			case 'a': hint->arch = (char*)sdb_decode (r, 0); break;
			}
			token = 0;
		} else token = *r;
		if (!nxt)
			break;
	}
	free (s);
	return hint;
}
Example #8
0
static int cmd_seek(void *data, const char *input) {
	RCore *core = (RCore *) data;
	char *cmd, *p;
	ut64 off;

	if (!*input) {
		r_cons_printf ("0x%"PFMT64x "\n", core->offset);
		return 0;
	}
	char *ptr;
	if ((ptr = strstr (input, "+.")) != NULL) {
		char *dup = strdup (input);
		dup[ptr - input] = '\x00';
		off = r_num_math (core->num, dup + 1);
		core->offset = off;
		free (dup);
	}
	const char *inputnum = strchr (input, ' ');
	{
		const char *u_num = inputnum? inputnum + 1: input + 1;
		off = r_num_math (core->num, u_num);
		if (*u_num == '-') {
			off = -off;
		}
	}
	int sign = 1;
	if (input[0] == ' ') {
		switch (input[1]) {
		case '-':
			sign = -1;
			/* pass thru */
		case '+':
			input++;
			break;
		}
	}
	bool silent = false;
	if (*input == 's') {
		silent = true;
		input++;
		if (*input == '?') {
			const char *help_message[] = {
				"Usage: ss", "", " # Seek silently (not recorded in the seek history)",
				"s?", "", "Works with all s subcommands",
				NULL
			};
			r_core_cmd_help (core, help_message);
			return 0;
		}
	}

	switch (*input) {
	case 'r':
		if (input[1] && input[2]) {
			seek_to_register (core, input + 2, silent);
		} else {
			eprintf ("|Usage| 'sr PC' seek to program counter register\n");
		}
		break;
	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;
				if (!silent) {
					r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				}
				r_core_seek (core, off, 1);
				r_core_block_read (core);
				break;
			default:
				eprintf ("Too many results\n");
				break;
			}
			free (cb.str);
		} else {
			const char *help_msg[] = {
				"Usage:", "sC", "Comment grep",
				"sC", "*", "List all comments",
				"sC", " str", "Seek to the first comment matching 'str'",
				NULL
			};
			r_core_cmd_help (core, help_msg);
		}
		break;
	case ' ':
		if (!silent) {
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
		}
		r_core_seek (core, off * sign, 1);
		r_core_block_read (core);
		break;
	case '/':
	{
		const char *pfx = r_config_get (core->config, "search.prefix");
		ut64 from = r_config_get_i (core->config, "search.from");
// 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 'v':
		case 'V':
		case 'w':
		case 'W':
		case 'z':
		case 'm':
		case 'c':
		case 'A':
		case 'e':
		case 'E':
		case 'i':
		case 'R':
		case 'r':
		case '/':
		case 'x':
			r_config_set_i (core->config, "search.from", core->offset + 1);
			r_config_set_i (core->config, "search.count", 1);
			r_core_cmdf (core, "s+1; %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.from", from);
			r_config_set_i (core->config, "search.count", 0);
			break;
		case '?':
			eprintf ("Usage: s/.. arg.\n");
			r_cons_printf ("/?\n");
			break;
		default:
			eprintf ("unknown search method\n");
			break;
		}
	}
	break;
	case '.':
		for (input++; *input == '.'; input++) {
			;
		}
		r_core_seek_base (core, input);
		break;
	case 'j':  // sj
		{
			RList /*<ut64 *>*/ *addrs = r_list_newf (free);
			RList /*<char *>*/ *names = r_list_newf (free);
			RList *list = r_io_sundo_list (core->io, '!');
			ut64 lsz = 0;
			ut64 i;
			RListIter *iter;
			RIOUndos *undo;
			if (list) {
				r_list_foreach (list, iter, undo) {
					char *name = NULL;

					core->flags->space_strict = true;
					RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
					core->flags->space_strict = false;
					if (f) {
						if (f->offset != undo->off) {
							name = r_str_newf ("%s + %d\n", f->name,
									(int)(undo->off- f->offset));
						} else {
							name = strdup (f->name);
						}
					}
					if (!name) {
						name = strdup ("");
					}
					ut64 *val = malloc (sizeof (ut64));
					if (!val) {
						free (name);
						break;
					}
					*val = undo->off;
					r_list_append (addrs, val);
					r_list_append (names, strdup (name));
					lsz++;
					free (name);
				}
				r_list_free (list);
			}
			r_cons_printf ("[");
			for (i = 0; i < lsz; ++i) {
				ut64 *addr = r_list_get_n (addrs, i);
				const char *name = r_list_get_n (names, i);
				// XXX(should the "name" field be optional? That might make
				// a bit more sense.
				r_cons_printf ("{\"offset\":%"PFMT64d",\"symbol\":\"%s\"}", *addr, name);
				if (i != lsz - 1) {
					r_cons_printf (",");
				}
			}
			r_cons_printf ("]\n");
			r_list_free (addrs);
			r_list_free (names);
		}
		break;
	case '*':
	case '=':
	case '!':
		{
			RList *list = r_io_sundo_list (core->io, input[0]);
			RListIter *iter;
			RIOUndos *undo;
			if (list) {
				r_list_foreach (list, iter, undo) {
					char *name = NULL;

					core->flags->space_strict = true;
					RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
					core->flags->space_strict = false;
					if (f) {
						if (f->offset != undo->off) {
							name = r_str_newf ("%s + %d\n", f->name,
									(int)(undo->off- f->offset));
						} else {
							name = strdup (f->name);
						}
					}
					if (!name) {
						name = strdup ("");
					}
					r_cons_printf ("0x%"PFMT64x" %s\n", undo->off, name);
					free (name);
				}
				r_list_free (list);
			}
		}
Example #9
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 {
				RReg *orig = core->dbg->reg;
				core->dbg->reg = core->anal->reg;
				off = r_debug_reg_get (core->dbg, input+2);
				core->dbg->reg = orig;
				r_core_seek (core, off, 1);
			}
		} 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':
			if (strlen(input) > 2 && input[1]==' ') {
				RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input+2);
				if (fcn) {
					r_core_seek (core, fcn->addr, 1);
				}
				break;
			}
			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_vget (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_vget (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 '?': {
			const char * help_message[] = {
			"Usage: s", "", " # Seek commands",
			"s", "", "Print current address",
			"s", " addr", "Seek to address",
			"s-", "", "Undo seek",
			"s-", " n", "Seek n bytes backward",
			"s--", "", "Seek blocksize bytes backward",
			"s+", "", "Redo seek",
			"s+", " n", "Seek n bytes forward",
			"s++", "", "Seek blocksize bytes forward",
			"s*", "", "List undo seek history",
			"s/", " DATA", "Search for next occurrence of 'DATA'",
			"s/x", " 9091", "Search for next occurrence of \\x90\\x91",
			"s.", "hexoff", "Seek honoring a base from core->offset",
			"sa", " [[+-]a] [asz]", "Seek asz (or bsize) aligned to addr",
			"sb", "", "Seek aligned to bb start",
			"sC", " string", "Seek to comment matching given string",
			"sf", "", "Seek to next function (f->addr+f->size)",
			"sf", " function", "Seek to address of specified function",
			"sg/sG", "", "Seek begin (sg) or end (sG) of section or file",
			"sn/sp", "", "Seek next/prev scr.nkey",
			"so", " [N]", "Seek to N next opcode(s)",
			"sr", " pc", "Seek to register",
			//"sp [page]  seek page N (page = block)",
			NULL
			};
			r_core_cmd_help(core, help_message);
		}
			break;
		}
	} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
	return 0;
}
Example #10
0
R_API int r_type_get_bitsize(Sdb *TDB, const char *type) {
	char *query;
	/* Filter out the structure keyword if type looks like "struct mystruc" */
	const char *tmptype;
	if (!strncmp (type, "struct ", 7)) {
		tmptype = type + 7;
	} else {
		tmptype = type;
	}
	if ((strstr (type, "*(") || strstr (type, " *")) &&
			strncmp (type, "char *", 7)) {
		return 32;
	}
	const char *t = sdb_const_get (TDB, tmptype, 0);
	if (!t) {
		if (!strncmp (tmptype, "enum ", 5)) {
			//XXX: Need a proper way to determine size of enum
			return 32;
		}
		return 0;
	}
	if (!strcmp (t, "type")){
		query = sdb_fmt ("type.%s.size", tmptype);
		return sdb_num_get (TDB, query, 0); // returns size in bits
	}
	if (!strcmp (t, "struct")) {
		query = sdb_fmt ("struct.%s", tmptype);
		char *members = sdb_get (TDB, query, 0);
		char *next, *ptr = members;
		int ret = 0;
		if (members) {
			do {
				char *name = sdb_anext (ptr, &next);
				if (!name) {
					break;
				}
				query = sdb_fmt ("struct.%s.%s", tmptype, name);
				char *subtype = sdb_get (TDB, query, 0);
				if (!subtype) {
					break;
				}
				char *tmp = strchr (subtype, ',');
				if (tmp) {
					*tmp++ = 0;
					tmp = strchr (tmp, ',');
					if (tmp) {
						*tmp++ = 0;
					}
					int elements = r_num_math (NULL, tmp);
					if (elements == 0) {
						elements = 1;
					}
					ret += r_type_get_bitsize (TDB, subtype) * elements;
				}
				free (subtype);
				ptr = next;
			} while (next);
			free (members);
		}
		return ret;
	}
	return 0;
}
Example #11
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_print_get_cursor (core->print));
				r_core_seek (core, off, 1);
			} else {
				RReg *orig = core->dbg->reg;
				core->dbg->reg = core->anal->reg;
				off = r_debug_reg_get (core->dbg, input + 2);
				core->dbg->reg = orig;
				r_core_seek (core, off, 1);
			}
		} else eprintf ("|Usage| 'sr PC' seek to program counter register\n");
	}
	if (*input) {
		char* ptr;
		if ((ptr = strstr(input, "+.")) != NULL) {
			char* dup = strdup(input);
			dup[ptr - input] = '\x00';
			off = r_num_math (core->num, dup + 1);
			core->offset = off;
			free (dup);
		}
		const char *inputnum = strchr (input, ' ');
		int sign = 1;
		{
			const char *u_num = inputnum? inputnum + 1: input + 1;
			off = r_num_math (core->num, u_num);
			if (*u_num == '-') 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 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_print_get_cursor (core->print));
					r_core_seek (core, off, 1);
					r_core_block_read (core);
					break;
				default:
					eprintf ("Too many results\n");
					break;
				}
				free (cb.str);
			} else {
				const char *help_msg[] = {
					"Usage:", "sC", "Comment grep",
					"sC", "*", "List all comments",
					"sC", " str", "Seek to the first comment matching 'str'",
					NULL };
				r_core_cmd_help (core, help_msg);
			}
			break;
		case ' ':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek (core, off * sign, 1);
			r_core_block_read (core);
			break;
		case '/':
			{
			const char *pfx = r_config_get (core->config, "search.prefix");
			ut64 from = r_config_get_i (core->config, "search.from");
//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 'v':
			case 'V':
			case 'w':
			case 'W':
			case 'z':
			case 'm':
			case 'c':
			case 'A':
			case 'e':
			case 'E':
			case 'i':
			case 'R':
			case 'r':
			case '/':
			case 'x':
				r_config_set_i (core->config, "search.from", core->offset+1);
				r_config_set_i (core->config, "search.count", 1);
				r_core_cmdf (core, "s+1; %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.from", from);
				r_config_set_i (core->config, "search.count", 0);
				break;
			case '?':
				eprintf ("Usage: s/.. arg.\n");
				r_cons_printf ("/?\n");
				break;
			default:
				eprintf ("unknown search method\n");
				break;
			}
			}
			break;
		case '.':
			for (input++;*input=='.';input++);
			r_core_seek_base (core, input);
			break;
		case '*':
		case '=':
		case 'j':
			r_io_sundo_list (core->io, input[0]);
			break;
		case '+':
			if (input[1]!='\0') {
				int delta = (input[1]=='+')? core->blocksize: off;
				r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				r_core_seek_delta (core, delta);
			} else {
				RIOUndos *undo = r_io_sundo_redo (core->io);
				if (undo != NULL)
					r_core_seek (core, undo->off, 0);
			}
			break;
		case '-':
			if (input[1]!='\0') {
				int delta = (input[1]=='-') ? -core->blocksize: -off;
				r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				r_core_seek_delta (core, delta);
			} else {
				RIOUndos *undo = r_io_sundo (core->io, core->offset);
				if (undo) {
					r_core_seek (core, undo->off, 0);
					r_core_block_read (core);
				}
			}
			break;
		case 'n':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
			break;
		case 'p':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			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_print_get_cursor (core->print));
			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_print_get_cursor (core->print));
			r_core_anal_bb_seek (core, off);
			break;
		case 'f': // "sf"
			if (strlen(input) > 2 && input[1]==' ') {
				RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input+2);
				if (fcn) {
					r_core_seek (core, fcn->addr, 1);
				}
				break;
			}
			RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			if (fcn) {
				r_core_seek (core, fcn->addr + r_anal_fcn_size (fcn), 1);
			}
			break;
		case 'o': // "so"
			{
			RAnalOp op;
			int val=0, ret, i, n = r_num_math (core->num, input+1);
			if (n==0) n = 1;
			if (n<0) {
				int instr_len;
				ut64 addr = core->offset;
				int numinstr = n * -1;
				if (r_core_prevop_addr (core, core->offset, numinstr, &addr)) {
					ret = core->offset - addr;
				} else {
					ret = r_core_asm_bwdis_len (core, &instr_len, &addr, numinstr);
				}
				r_core_seek (core, addr, true);
				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)
						ret = 1;
					r_core_seek_delta (core, ret);
					val += ret;
				}
			}
			core->num->value = val;
			}
			break;
		case 'g': // "sg"
			{
			RIOSection *s = r_io_section_vget (core->io, core->offset);
			if (s) r_core_seek (core, s->vaddr, 1);
			else r_core_seek (core, 0, 1);
			}
			break;
		case 'G': // "sG"
			{
			if (!core->file) break;
			RIOSection *s = r_io_section_vget (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, r_io_desc_size (core->io, core->file->desc), 1);
			}
			break;
		case 'l': // "sl"
			{
			int sl_arg = r_num_math (core->num, input+1);
			const char *help_msg[] = {
				"Usage:", "sl+ or sl- or slc", "",
				"sl", " [line]", "Seek to absolute line",
				"sl", "[+-][line]", "Seek to relative line",
				"slc", "", "Clear line cache",
				"sll", "", "Show total number of lines",
				NULL };
			switch (input[1]) {
			case 0:
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__get_current_line (core);
				break;
			case ' ':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__seek_line_absolute (core, sl_arg);
				break;
			case '+':
			case '-':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__seek_line_relative (core, sl_arg);
				break;
			case 'c':
				__clean_lines_cache (core);
				break;
			case 'l':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				eprintf ("%d lines\n", core->print->lines_cache_sz-1);
				break;
			case '?':
				r_core_cmd_help (core, help_msg);
				break;
			}
			}
			break;
		case ':':
			printPadded (core, atoi (input + 1));
			break;
		case '?': {
			const char * help_message[] = {
			"Usage: s", "", " # Seek commands",
			"s", "", "Print current address",
			"s:", "pad", "Print current address with N padded zeros (defaults to 8)",
			"s", " addr", "Seek to address",
			"s-", "", "Undo seek",
			"s-", " n", "Seek n bytes backward",
			"s--", "", "Seek blocksize bytes backward",
			"s+", "", "Redo seek",
			"s+", " n", "Seek n bytes forward",
			"s++", "", "Seek blocksize bytes forward",
			"s[j*=]", "", "List undo seek history (JSON, =list, *r2)",
			"s/", " DATA", "Search for next occurrence of 'DATA'",
			"s/x", " 9091", "Search for next occurrence of \\x90\\x91",
			"s.", "hexoff", "Seek honoring a base from core->offset",
			"sa", " [[+-]a] [asz]", "Seek asz (or bsize) aligned to addr",
			"sb", "", "Seek aligned to bb start",
			"sC", "[?] string", "Seek to comment matching given string",
			"sf", "", "Seek to next function (f->addr+f->size)",
			"sf", " function", "Seek to address of specified function",
			"sg/sG", "", "Seek begin (sg) or end (sG) of section or file",
			"sl", "[?] [+-]line", "Seek to line",
			"sn/sp", "", "Seek next/prev scr.nkey",
			"so", " [N]", "Seek to N next opcode(s)",
			"sr", " pc", "Seek to register",
			//"sp [page]  seek page N (page = block)",
			NULL
			};
			r_core_cmd_help(core, help_message);
		}
			break;
		}
	} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
	return 0;
}
Example #12
0
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size) {
	char key[100], *dtr, *s, *p, *next;
	const char *val;
	int i;
	if (size == UT64_MAX) {
		// FULL CLEANUP
		// XXX: this thing ignores the type
		if (type == R_META_TYPE_ANY) {
			sdb_reset (DB);
		} else {
			snprintf (key, sizeof (key)-1, "meta.%c.count", type);
			int last = (ut64)sdb_num_get (DB, key, NULL)/K;
			for (i=0; i<last; i++) {
				snprintf (key, sizeof (key)-1, "meta.%c.%d", type, i);
				dtr = sdb_get (DB, key, 0);
				for (p = dtr; p; p = next) {
					s = sdb_anext (p, &next);
					snprintf (key, sizeof (key)-1,
						"meta.%c.0x%"PFMT64x,
						type, sdb_atoi (s));
					sdb_unset (DB, key, 0);
					if (!next) break;
				}
				free (dtr);
			}
		}
		return false;
	}
	if (type == R_META_TYPE_ANY) {
		/* special case */
		r_meta_del (a, R_META_TYPE_COMMENT, addr, size);
		r_meta_del (a, R_META_TYPE_VARTYPE, addr, size);
	}
	if (type == R_META_TYPE_COMMENT || type == R_META_TYPE_VARTYPE) {
		snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr);
	} else {
		snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, addr);
	}
	meta_inrange_del (a, addr, size);
	val = sdb_const_get (DB, key, 0);
	if (val) {
		if (type == R_META_TYPE_ANY) {
			char item_key[100];
			const char *ptr = val;
			while (*ptr) {
				snprintf (item_key, sizeof (item_key), "meta.%c.0x%" PFMT64x, *ptr, addr);
				sdb_unset (DB, item_key, 0);
				ptr++;
				if (*ptr) {
					ptr++;
				}
			}
			sdb_unset (DB, key, 0);
			return false;
		}
		if (strchr (val, ',')) {
			char type_fld[] = "##";
			if (val[0] == type) {
				type_fld[0] = type;
				type_fld[1] = ',';
			} else {
				type_fld[0] = ',';
				type_fld[1] = type;
			}
			sdb_uncat (DB, key, type_fld, 0);
		} else {
			sdb_unset (DB, key, 0);
		}
		snprintf (key, sizeof (key), "meta.%c.0x%" PFMT64x, type, addr);
		sdb_unset (DB, key, 0);
	}
	sdb_unset (DB, key, 0);
	return false;
}