Example #1
0
static int meta_enumerate_cb(void *user, const char *k, const char *v) {
	const char *v2;
	RAnalMetaUserItem *ui = user;
	RList *list = ui->user;
	//RAnal *a = ui->anal;
	RAnalMetaItem *it;
	if (strlen (k)<8)
		return 1;
	if (memcmp (k+6, ".0x", 3))
		return 1;
	it = R_NEW0 (RAnalMetaItem);
	if (!it) return 0;
	it->type = k[5];
	it->size = sdb_atoi (v);
	it->from = sdb_atoi (k+7);
	it->to = it->from + it->size;
	v2 = strchr (v, ',');
	if (!v2) {
		free (it); 
		goto beach;
	}
	it->space = atoi (v2+1);
	it->str = strchr (v2+1, ',');

	if (it->str)
		it->str = (char *)sdb_decode ((const char*)it->str+1, 0);
	//printmetaitem (ui->anal, &it, ui->rad);
	r_list_append (list, it);
beach:
	return 1;
}
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
static int meta_print_item(void *user, const char *k, const char *v) {
	// const char *v; // size
	const char *v2; // space_idx
	RAnalMetaUserItem *ui = user;
	RAnalMetaItem it;
	if (strlen (k)<8)
		return 1;
	if (memcmp (k+6, ".0x", 3))
		return 1;
	it.type = k[5];
	it.size = sdb_atoi (v);
	it.from = sdb_atoi (k+7);

	v2 = strchr (v, ',');
	if (!v2) goto beach;
	it.space = atoi (v2+1);
	it.to = it.from + it.size;
	it.str = strchr (v2+1, ',');
	if (it.str)
		it.str = (char *)sdb_decode ((const char*)it.str+1, 0);
	else it.str = strdup (it.str); // don't break in free
	printmetaitem (ui->anal, &it, ui->rad);
	free (it.str);
beach:
	return 1;
}
Example #4
0
SDB_API ut64 sdb_array_get_num(Sdb *s, const char *key, int idx, ut32 *cas) {
	const char *str, *n, *p;
	int i;
	p = str = sdb_const_get (s, key, cas);
	if (!str || !*str)
		return 0LL;
	if (idx==0)
		return sdb_atoi (str);
	for (i=0; i<idx; i++) {
		n = strchr (p, SDB_RS);
		if (!n) return 0LL;
		p = n+1;
	}
	return sdb_atoi (p);
}
Example #5
0
R_API bool r_meta_deserialize_val(RAnalMetaItem *it, int type, ut64 from, const char *v) {
	const char *v2;
	char *v3;
	it->type = type;
	it->subtype = 0;
	it->size = sdb_atoi (v);
	it->from = from;
	it->to = from + it->size;
	v2 = strchr (v, ',');
	if (!v2) {
		return false;
	}
	it->space = atoi (v2 + 1);
	it->str = strchr (v2 + 1, ',');
	if (it->str) {
		if (it->type == R_META_TYPE_STRING) {
			v3 = strchr (it->str + 1, ',');
			if (v3) {
				it->subtype = *(it->str + 1);
				it->str = v3;
			}
		}
		it->str = (char *)sdb_decode ((const char*)it->str + 1, 0);
	}
	return true;
}
Example #6
0
static int meta_print_item(void *user, const char *k, const char *v) {
	RAnalMetaUserItem *ui = user;
	RAnalMetaItem it;
	if (strlen (k)<8)
		return 1;
	if (k[6]!='.')
		return 1;
	it.type = k[5];
	it.size = sdb_atoi (v);
	it.from = sdb_atoi (k+7);
	it.to = it.from + it.size;
	it.str = strchr (v, ',');
	if (it.str)
		it.str = (char *)sdb_decode ((const char*)it.str+1, 0);
	printmetaitem (ui->anal, &it, ui->rad);
	free (it.str);
	return 1;
}
Example #7
0
static bool meta_deserialize(RAnalMetaItem *it, const char *k, const char *v) {
	if (strlen (k) < 8) {
		return false;
	}
	if (memcmp (k + 6, ".0x", 3)) {
		return false;
	}
	return r_meta_deserialize_val (it, k[5], sdb_atoi (k + 7), v);
}
Example #8
0
static int deserialize(RAnalMetaItem *it, const char *k, const char *v) {
	const char *v2;
	if (strlen (k)<8)
		return 1;
	if (memcmp (k+6, ".0x", 3))
		return 1;
	it->type = k[5];
	it->size = sdb_atoi (v);
	it->from = sdb_atoi (k+7);
	it->to = it->from + it->size;
	v2 = strchr (v, ',');
	if (!v2) goto beach;
	it->space = atoi (v2+1);
	it->str = strchr (v2+1, ',');
	//printmetaitem (ui->anal, &it, ui->rad);
beach:
	return 1;
}
Example #9
0
static int sdb_grep_dump(const char *db, int fmt, bool grep,
                         const char *expgrep) {
	char *v;
	char k[SDB_MAX_KEY] = {
		0
	};
	const char *comma = "";
	Sdb *s = sdb_new (NULL, db, 0);
	if (!s) {
		return 1;
	}
	sdb_config (s, options);
	sdb_dump_begin (s);
	if (fmt == MODE_JSON) {
		printf ("{");
	}
	while (sdb_dump_dupnext (s, k, &v, NULL)) {
		if (grep && !strstr (k, expgrep) && !strstr (v, expgrep)) {
			continue;
		}
		switch (fmt) {
		case MODE_JSON:
			if (!strcmp (v, "true") || !strcmp (v, "false")) {
				printf ("%s\"%s\":%s", comma, k, v);
			} else if (sdb_isnum (v)) {
				printf ("%s\"%s\":%llu", comma, k, sdb_atoi (v));
			} else if (*v == '{' || *v == '[') {
				printf ("%s\"%s\":%s", comma, k, v);
			} else {
				printf ("%s\"%s\":\"%s\"", comma, k, v);
			}
			comma = ",";
			break;
		case MODE_ZERO:
			printf ("%s=%s", k, v);
			fwrite ("", 1, 1, stdout);
			break;
		default:
			printf ("%s=%s\n", k, v);
			break;
		}
		free (v);
	}
	switch (fmt) {
	case MODE_ZERO:
		fflush (stdout);
		write (1, "", 1);
		break;
	case MODE_JSON:
		printf ("}\n");
		break;
	}
	sdb_free (s);
	return 0;
}
Example #10
0
static int meta_print_item(void *user, const char *k, const char *v) {
	// const char *v; // size
	const char *v2; // space_idx
	RAnalMetaUserItem *ui = user;
	RAnalMetaItem it;
	if (strlen (k) < 8) {
		return 1;
	}
	if (memcmp (k + 6, ".0x", 3)) {
		return 1;
	}
	it.type = k[5];
	it.size = sdb_atoi (v);
	it.from = sdb_atoi (k + 7);
	int uirad = ui->rad;
	if (ui->rad == 'f') {
		if (!r_anal_fcn_in (ui->fcn, it.from)) {
			goto beach;
		}
		ui->rad = 0;
	}
	v2 = strchr (v, ',');
	if (!v2) {
		goto beach;
	}
	it.space = atoi (v2 + 1);
	it.to = it.from + it.size;
	it.str = strchr (v2 + 1, ',');
	if (it.str) {
		it.str = (char *)sdb_decode ((const char*)it.str + 1, 0);
	} else {
		it.str = strdup (it.str? it.str: ""); // don't break in free
		if (!it.str) {
			goto beach;
		}
	}
	printmetaitem (ui->anal, &it, ui->rad);
	free (it.str);
beach:
	ui->rad = uirad;
	return 1;
}
Example #11
0
static int sdb_dump (const char *db, int fmt) {
	char *k, *v;
	const char *comma = "";
	Sdb *s = sdb_new (NULL, db, 0);
	if (!s) return 1;
	sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
	sdb_dump_begin (s);
	if (fmt==MODE_JSON)
		printf ("{");
	while (sdb_dump_dupnext (s, &k, &v, NULL)) {
		switch (fmt) {
		case MODE_JSON:
			if (!strcmp (v, "true") || !strcmp (v, "false")) {
				printf ("%s\"%s\":%s", comma, k, v);
			} else if (sdb_isnum (v)) {
				printf ("%s\"%s\":%llu", comma, k, sdb_atoi (v));
			} else if (*v=='{' || *v=='[') {
				printf ("%s\"%s\":%s", comma, k, v);
			} else printf ("%s\"%s\":\"%s\"", comma, k, v);
			comma = ",";
			break;
		case MODE_ZERO:
			printf ("%s=%s", k, v);
			break;
		default:
			printf ("%s=%s\n", k, v);
			break;
		}
#if 0
		if (qf && strchr (v, SDB_RS)) {
			for (p=v; *p; p++)
				if (*p==SDB_RS)
					*p = ',';
			printf ("[]%s=%s\n", k, v);
		} else {
			printf ("%s=%s\n", k, v);
		}
#endif
		free (k);
		free (v);
	}
	switch (fmt) {
	case MODE_ZERO:
		fflush (stdout);
		write (1, "", 1);
		break;
	case MODE_JSON:
		printf ("}\n");
		break;
	}
	sdb_free (s);
	return 0;
}
Example #12
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 #13
0
SDB_API ut64 sdb_array_pop_num(Sdb *s, const char *key, ut32 *cas) {
	ut64 ret;
	char *a = sdb_array_pop (s, key, cas);
	if (!a) {
		if (cas) *cas = UT32_MAX; // invalid
		return UT64_MAX;
	}
	if (cas)
		*cas = 0;
	ret = sdb_atoi (a);
	free (a);
	return ret;
}
Example #14
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 #15
0
SDB_API ut64 sdb_array_get_num(Sdb *s, const char *key, int idx, ut32 *cas) {
	int i;
	const char *n, *str = sdb_const_get (s, key, cas);
	if (!str || !*str) {
		return 0LL;
	}
	if (idx) {
		for (i = 0; i < idx; i++) {
			n = strchr (str, SDB_RS);
			if (!n) return 0LL;
			str = n + 1;
		}
	}
	return sdb_atoi (str);
}
Example #16
0
SDB_API int sdb_array_remove_num(Sdb *s, const char *key, ut64 val, ut32 cas) {
	const char *n, *p, *str = sdb_const_get (s, key, 0);
	int idx = 0;
	ut64 num;
	if (!str) return 0;
	for (p=str; ; idx++) {
		num = sdb_atoi (p);
		if (num == val)
			return sdb_array_delete (s, key, idx, cas);
		n = strchr (p, SDB_RS);
		if (!n) break;
		p = n+1;
	}
	return 0;
}
Example #17
0
SDB_API int sdb_array_add_sorted_num(Sdb *s, const char *key, ut64 val, ut32 cas) {
	int i;
	char valstr[SDB_NUM_BUFSZ];
	const char *str = sdb_const_get (s, key, 0);
	const char *n = str;
	if (!str || !*str) {
		return sdb_set (s, key, sdb_itoa (val, valstr, SDB_NUM_BASE), cas);
	}
	for (i = 0; n; i++) {
		if (val <= sdb_atoi (n)) {
			break;
		}
		sdb_const_anext (n, &n);
	}
	return sdb_array_insert_num (s, key, n? i: -1, val, cas);
}
Example #18
0
SDB_API int sdb_array_add_sorted_num(Sdb *s, const char *key, ut64 val, ut32 cas) {
	int i;
	char valstr[64];
	const char *str = sdb_const_get (s, key, 0);
	const char *n = str;
	if (!str || !*str)
		return sdb_set (s, key, sdb_itoa (val, valstr, SDB_NUM_BASE), cas);
	for (i=0; n != NULL; i++) {
		if (val <= sdb_atoi(n))
			break;
		sdb_const_anext(n, &n);
	}
	if (n == NULL)
		i = -1;
	sdb_array_insert_num (s, key, i, val, cas);
	return 0;
}
Example #19
0
// TODO: move this into fmt?
SDB_API ut64* sdb_fmt_array_num(const char *list) {
	ut64 *retp, *ret = NULL;
	const char *next, *ptr = list;
	if (list && *list) {
		int len = sdb_alen (list);
		retp = ret = (ut64*) malloc (sizeof(ut64)*(len+1));
		if (!ret)
			return NULL;
		*retp++ = len;
		do {
			const char *str = sdb_anext2 (ptr, &next);
			ut64 n = sdb_atoi (str);
			*retp++ = n;
			ptr = next;
		} while (next);
	}
	return ret;
}
Example #20
0
static int print_addrinfo (void *user, const char *k, const char *v) {
	char *colonpos, *subst;

	ut64 offset = sdb_atoi (k);
	if (!offset) {
		return true;
	}
	subst = strdup (v);
	colonpos = strchr (subst, '|');

	if (colonpos) {
		*colonpos = ':';
	}
	r_cons_printf ("CL %s %s\n", subst, k);
	free (subst);

	return true;
}
Example #21
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 #22
0
static int sdb_dump (const char *db, int json) {
	char *k, *v;
	const char *comma = "";
	Sdb *s = sdb_new (NULL, db, 0);
	if (!s) return 1;
	sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
	sdb_dump_begin (s);
	if (json)
		printf ("{");
	while (sdb_dump_dupnext (s, &k, &v)) {
		if (json) {
			if (!strcmp (v, "true") || !strcmp (v, "false")) {
				printf ("%s\"%s\":%s", comma, k, v);
			} else
			if (sdb_isnum (v)) {
				printf ("%s\"%s\":%llu", comma, k, sdb_atoi (v));
			} else
			if (*v=='{' || *v=='[') {
				printf ("%s\"%s\":%s", comma, k, v);
			} else
				printf ("%s\"%s\":\"%s\"", comma, k, v);
			comma = ",";
		} else {
			printf ("%s=%s\n", k, v);
		}
#if 0
		if (qf && strchr (v, SDB_RS)) {
			for (p=v; *p; p++)
				if (*p==SDB_RS)
					*p = ',';
			printf ("[]%s=%s\n", k, v);
		} else {
			printf ("%s=%s\n", k, v);
		}
#endif
		free (k);
		free (v);
	}
	if (json)
		printf ("}\n");
	sdb_free (s);
	return 0;
}
Example #23
0
static int print_addrinfo (void *user, const char *k, const char *v) {
	ut64 offset;
	char *colonpos, *subst;

	offset = sdb_atoi (v);
	if (!offset)
		return R_TRUE;

	subst = strdup (k);
	colonpos = strchr (subst, '|');

	if (colonpos)
		*colonpos = ':';

	r_cons_printf ("CL %s %s\n", subst, v);

	free (subst);

	return R_TRUE;
}
Example #24
0
static ut64 sdb_array_get_closer_num (Sdb *db, const char *key, ut64 addr) {
	const char *s = sdb_const_get (db, key, NULL);
	const char *next = NULL;
	const char *ptr = NULL;
	ut64 num, closer = UT64_MAX;
	if (!s) return UT64_MAX;
	ptr = s;
	do {
		const char *str = sdb_const_anext (ptr, &next);
		num = sdb_atoi (str);
		if (addr == num)
			return closer;
		if (addr>=num) {
			if (closer > (addr - num))
				closer = num;
		}
		ptr = next;
	} while (next);
	return closer;
}
Example #25
0
static ut64 getFunctionSize(Sdb *db) {
	ut64 min = UT64_MAX, max = 0;
	char *c, *bbs = sdb_get (db, "bbs", NULL);
	bool first = true;
	sdb_aforeach (c, bbs) {
		ut64 addr = sdb_atoi (c);
		ut64 addr_end = sdb_num_get (db, Fbb (addr), NULL);
		if (first) {
			min = addr;
			max = addr_end;
			first = false;
		} else {
			if (addr < min) {
				min = addr;
			}
			if (addr_end > max) {
				max = addr_end;
			}
		}
		sdb_aforeach_next (c);
	}
Example #26
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 #27
0
static ut64 getFunctionSize(Sdb *db) {
#if 1
	ut64 min = sdb_num_get (db, Fmin (addr), NULL);
	ut64 max = sdb_num_get (db, Fmax (addr), NULL);
#else
	ut64 min, max;
	char *c, *bbs = sdb_get (db, "bbs", NULL);
	int first = 1;
	sdb_aforeach (c, bbs) {
		ut64 addr = sdb_atoi (c);
		ut64 addr_end = sdb_num_get (db, Fbb(addr), NULL);
		if (first) {
			min = addr;
			max = addr_end;
			first = 0;
		} else {
			if (addr<min)
				min = addr;
			if (addr_end>max)
				max = addr_end;
		}
		sdb_aforeach_next (c);
	}
Example #28
0
static ut64 getCrossingBlock(Sdb *db, const char *key, ut64 start, ut64 end) {
	ut64 block_start, block_end;
	ut64 nearest_start = UT64_MAX;
	const char *s = sdb_const_get (db, key, NULL);
	const char *next = NULL;
	const char *ptr = NULL;
	if (!s) {
		return UT64_MAX;
	}
	ptr = s;
	do {
		const char *str = sdb_const_anext (ptr, &next);
		block_start = sdb_atoi (str);

		if (start == block_start) { // case 5
			return start;
		}

		block_end = sdb_num_get (db, Fbb(block_start), NULL);
		if (block_end) {
			if (start > block_start && start < block_end) { // case 2
				// start is inside the block
				return block_start;
			}
			if (start < block_start && end >= block_end) {
				// crossing the start of the block
				if (nearest_start > block_start) {
					nearest_start = block_start;
				}
			}
		}
		ptr = next;
	} while (next);

	return nearest_start;
}
Example #29
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 #30
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;
}