Esempio n. 1
0
static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len,
		char *name, int slide, int mode, const char *setval, char *field) {
	const char *fmt;
	char namefmt[8];
	if ((slide % STRUCTPTR) > NESTDEPTH || (slide%STRUCTFLAG)/STRUCTPTR > NESTDEPTH) {
		eprintf ("Too much nested struct, recursion too deep...\n");
		return 0;
	}
	fmt = r_strht_get (p->formats, name);
	if (!fmt || !*fmt) {
		eprintf ("Undefined struct '%s'.\n", name);
		return 0;
	}
	if (MUSTSEE && !SEEVALUE) {
		snprintf (namefmt, sizeof (namefmt), "%%%ds", 10+6*slide%STRUCTPTR);
		if (fmt[0] == '0')
			p->cb_printf (namefmt, "union");
		else p->cb_printf (namefmt, "struct");
		p->cb_printf ("<%s>\n", name);
	}
	r_print_format (p, seek, b, len, fmt, mode, setval, field);
	return r_print_format_struct_size(fmt, p, mode);
}
Esempio n. 2
0
// XXX: this is very incomplete. must be updated to handle all format chars
int r_print_format_struct_size(const char *f, RPrint *p, int mode) {
	char *o = strdup(f);
	char *end = strchr (o, ' '), *args, *fmt = o;
	int size = 0, tabsize=0, i, idx=0, biggest = 0;
	if (!end && !(end = strchr (o, '\0')))
		return -1;
	if (*end) {
		*end = 0;
		args = strdup (end+1);
	} else {
		args = strdup ("");
	}
	if (fmt[0] == '0') {
		mode |= R_PRINT_UNIONMODE;
		fmt++;
	} else {
		mode &= ~R_PRINT_UNIONMODE;
	}

	r_str_word_set0 (args);
	for (i=0; i<strlen (fmt); i++) {
		if (fmt[i] == '[') {
			char *end = strchr (fmt+i,']');
			if (end == NULL) {
				eprintf ("No end bracket.\n");
				continue;
			}
			*end = '\0';
			tabsize = r_num_math (NULL, fmt+i+1);
			*end = ']';
			while (fmt[i++]!=']');
		} else {
			tabsize = 1;
		}

		switch (fmt[i]) {
			case 'c':
			case 'b':
			case '.':
				size+=tabsize*1;
				break;
			case 'w':
				size += tabsize*2;
				break;
			case 'd':
			case 'o':
			case 'i':
			case 'x':
			case 'f':
			case 's':
			case 't':
			case ':':
				size += tabsize*4;
				break;
			case 'S':
			case 'q':
				size += tabsize*8;
				break;
			case 'z':
			case 'Z':
				size += tabsize;
				break;
			case '*':
				size += tabsize*4;
				i++;
				break;
			case 'B':
			case 'E':
				switch (tabsize) {
				case 1: size+=1; break;
				case 2: size+=2; break;
				case 4: size+=4; break;
				default: break;
				}
				break;
			case '?':
				{
				const char *format = NULL;
				char *endname = NULL, *structname = NULL;
				structname = strdup(r_str_word_get0 (args, idx));
				if (*structname == '(') {
					endname = strchr (structname, ')');
				} else {
					eprintf ("Struct name missing (%s)\n", structname);
					free(structname);
					break;
				}
				if (endname) *endname = '\0';
				format = r_strht_get (p->formats, structname+1);
				free (structname);
				size += tabsize * r_print_format_struct_size (format, p, mode);
				}
				break;
				// TODO continue list
			default:
				break;
		}
		idx++;
		if (mode & R_PRINT_UNIONMODE) {
			if (size > biggest) biggest = size;
			size = 0;
		}
	}
	free (o);
	free (args);
	if (mode & R_PRINT_UNIONMODE)
		return biggest;
	else
		return size;
}
Esempio n. 3
0
static int cmd_meta_hsdmf(RCore *core, const char *input) {
	int n, type = input[0];
	char *t = 0, *p, name[256];
	int repeat = 1;
	ut64 addr_end = 0LL, addr = core->offset;

	switch (input[1]) {
	case '?':
		eprintf ("See C?\n");
		break;
	case '-':
		switch (input[2]) {
		case '*':
			core->num->value = r_meta_del (core->anal,
					input[0], 0, UT64_MAX, NULL);
			break;
		case ' ':
			addr = r_num_math (core->num, input+3);
			/* fallthrough */
		default:
			core->num->value = r_meta_del (core->anal,
					input[0], addr, 1, NULL);
			break;
		}
		break;
	case '*':
		r_meta_list (core->anal, input[0], 1);
		break;
	case '!':
		{
			char *out, *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			out = r_core_editor (core, NULL, comment);
			if (out) {
				//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
				r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
				//r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out);
				free (out);
			}
			free (comment);
		}
		break;
	case ' ':
	case '\0':
		if (type != 'z' && input[1] == '*') {
			r_meta_list (core->anal, type, 0);
			break;
		}
		if (type == 'z') {
			type = 's';
		}
		if (strlen (input) > 2) {
			char *rep = strchr (input + 2, '[');
			if (!rep) rep = strchr (input + 2, ' ');
			if (rep) {
				repeat = r_num_get (core->num, rep + 1);
			}
		}
		int repcnt = 0;
		if (repeat < 1) {
			repeat = 1;
		}
		while (repcnt < repeat) {
			t = strdup (r_str_chop_ro (input + 1));
			p = NULL;
			n = 0;
			strncpy (name, t, sizeof (name) - 1);
			if (type != 'C') {
				n = r_num_math (core->num, t);
				if (type == 'f') { // "Cf"
					p = strchr (t, ' ');
					if (p) {
						if (n < 1) {
							n = r_print_format_struct_size (p + 1, core->print, 0);
							if (n < 1) {
								eprintf ("Cannot resolve struct size\n");
								n = 32; //
							}
						}
						int r = r_print_format (core->print, addr, core->block,
							n, p + 1, 0, NULL, NULL);
						if (r < 0) {
							n  = -1;
						}
					} else {
						eprintf ("Usage: Cf [size] [pf-format-string]\n");
						break;
					}
				} else if (type == 's') { //Cs
					char tmp[256] = {0};
					int i, j, name_len = 0;
					(void)r_core_read_at (core, addr, (ut8*)tmp, sizeof (tmp) - 1);
					name_len = r_str_nlen_w (tmp, sizeof (tmp));
					//handle wide strings
					for (i = 0, j = 0; i < sizeof (name); i++, j++) {
						name[i] = tmp[j];
						if (!tmp[j]) {
							break;
						}
						if (!tmp[j + 1]) {
							if (j + 3 < sizeof (tmp)) {
								if (tmp[j + 3]) {
									break;	
								}
							}
							j++;
						}
					}
					name[sizeof (name) - 1] = '\0';
					if (n == 0) {
						n = name_len + 1;
					} else {
						if (n > 0 && n < name_len) {
							name[n] = 0;
						}
					}
				}
				if (n < 1) {
					/* invalid length, do not insert into db */
					return false;
				}
				if (!*t || n > 0) {
					RFlagItem *fi;
					p = strchr (t, ' ');
					if (p) {
						*p = '\0';
						strncpy (name, p + 1, sizeof (name)-1);
					} else {
						if (type != 's') {
							fi = r_flag_get_i (core->flags, addr);
							if (fi) strncpy (name, fi->name, sizeof (name)-1);
						}
					}
				}
			}
			if (!n) {
				n++;
			}
			addr_end = addr + n;
			r_meta_add (core->anal, type, addr, addr_end, name);
			free (t);
			repcnt ++;
			addr = addr_end;
		}
		//r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX);
		break;
	default:
		eprintf ("Missing space after CC\n");
		break;
	}

	return true;
}