Пример #1
0
R_API char *r_type_link_at (Sdb *TDB, ut64 addr) {
	char* res = NULL;

	if (addr == UT64_MAX) {
		return NULL;
	}
	char* query = sdb_fmt ("link.%08"PFMT64x, addr);
	res = sdb_get (TDB, query, 0);
	if (!res) { // resolve struct memb if possible for given addr
		SdbKv *kv;
		SdbListIter *sdb_iter;
		SdbList *sdb_list = sdb_foreach_list (TDB, true);
		ls_foreach (sdb_list, sdb_iter, kv) {
			if (strncmp (kv->key, "link.", strlen ("link."))) {
				continue;
			}
			const char *linkptr = sdb_fmt ("0x%s", kv->key + strlen ("link."));
			ut64 baseaddr = r_num_math (NULL, linkptr);
			int delta = (addr > baseaddr)? addr - baseaddr: -1;
			res = r_type_get_struct_memb (TDB, kv->value, delta);
			if (res) {
				break;
			}
		}
		ls_free (sdb_list);
	}
Пример #2
0
R_API RList* r_type_get_by_offset(Sdb *TDB, ut64 offset) {
	RList *offtypes = r_list_new ();
	SdbList *ls = sdb_foreach_list (TDB, true);
	SdbListIter *lsi;
	SdbKv *kv;
	ls_foreach (ls, lsi, kv) {
		// TODO: Add unions support
		if (!strncmp (kv->value, "struct", 6) && strncmp (kv->key, "struct.", 7)) {
			char *res = r_type_get_struct_memb (TDB, kv->key, offset);
			if (res) {
				r_list_append (offtypes, res);
			}
		}
	}
	ls_free (ls);
	return offtypes;
}
Пример #3
0
R_API char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset) {
	int i, prev_typesize, typesize = 0;
	char *res = NULL;

	if (offset < 0) {
		return NULL;
	}
	char* query = sdb_fmt ("struct.%s", type);
	char *members = sdb_get (TDB, query, 0);
	if (!members) {
		//eprintf ("%s is not a struct\n", type);
		return NULL;
	}
	int nargs = r_str_split (members, ',');
	for (i = 0; i < nargs ; i++) {
		const char *name = r_str_word_get0 (members, i);
		if (!name) {
			break;
		}
		query = sdb_fmt ("struct.%s.%s", type, name);
		char *subtype = sdb_get (TDB, query, 0);
		if (!subtype) {
			break;
		}
		int len = r_str_split (subtype, ',');
		if (len < 3) {
			free (subtype);
			break;
		}
		int val = r_num_math (NULL, r_str_word_get0 (subtype, len - 1));
		int arrsz = val ? val : 1;
		if ((typesize / 8) == offset) {
			res = r_str_newf ("%s.%s", type, name);
			free (subtype);
			break;
		}
		prev_typesize = typesize;
		typesize += r_type_get_bitsize (TDB, subtype) * arrsz;
		// Handle nested structs
		if (offset < (typesize / 8)) {
			char *nested_type = (char *)r_str_word_get0 (subtype, 0);
			if (r_str_startswith (nested_type, "struct ") && !r_str_endswith (nested_type, " *")) {
				len = r_str_split (nested_type, ' ');
				if (len < 2) {
					free (subtype);
					break;
				}
				nested_type = (char *)r_str_word_get0 (nested_type, 1);
				char *nested_res = r_type_get_struct_memb (TDB, nested_type, offset - (prev_typesize / 8));
				if (nested_res) {
					len = r_str_split(nested_res, '.');
					res = r_str_newf ("%s.%s.%s", type, name, r_str_word_get0 (nested_res, len - 1));
					free (nested_res);
					free (subtype);
					break;
				}
			}
		}
		free (subtype);
	}
	free (members);
	return res;
}