コード例 #1
0
ファイル: grep.c プロジェクト: tutamuniz/radare2
static int cmp(const void *a, const void *b) {
	char *da = NULL;
	char *db = NULL;
	const char *ca = r_str_trim_ro (a);
	const char *cb = r_str_trim_ro (b);
	if (!a || !b) {
		return (int) (size_t) ((char*) a - (char*) b);
	}
	if (sorted_column > 0) {
		da = strdup (ca);
		db = strdup (cb);
		int colsa = r_str_word_set0 (da);
		int colsb = r_str_word_set0 (db);
		ca = (colsa > sorted_column)? r_str_word_get0 (da, sorted_column): "";
		cb = (colsb > sorted_column)? r_str_word_get0 (db, sorted_column): "";
	}
	if (IS_DIGIT (*ca) && IS_DIGIT (*cb)) {
		ut64 na = r_num_get (NULL, ca);
		ut64 nb = r_num_get (NULL, cb);
		int ret = na > nb;
		free (da);
		free (db);
		return ret;
	}
	if (da && db) {
		int ret = strcmp (ca, cb);
		free (da);
		free (db);
		return ret;
	}
	free (da);
	free (db);
	return strcmp (a, b);
}
コード例 #2
0
ファイル: syscall.c プロジェクト: PankajKataria/radare2
R_API RSyscallItem *r_syscall_item_new_from_string(const char *name, const char *s) {
	RSyscallItem *si;
	char *o;
	if (!name || !s) {
		return NULL;
	}
	si = R_NEW0 (RSyscallItem);
	if (!si) {
		return NULL;
	}
	o = strdup (s);
	r_str_split (o, ',');
	si->name = strdup (name);
	si->swi = r_num_get (NULL, r_str_word_get0 (o, 0));
	si->num = r_num_get (NULL, r_str_word_get0 (o, 1));
	si->args = r_num_get (NULL, r_str_word_get0 (o, 2));
	//in a definition such as syscall=0x80,0,4,
	//the string at index 3 is 0 causing oob read afterwards
	si->sargs = calloc (si->args + 1, sizeof (char));
	if (!si->sargs) {
		free (si);
		free (o);
		return NULL;
	}
	strncpy (si->sargs, r_str_word_get0 (o, 3), si->args);
	free (o);
	return si;
}
コード例 #3
0
ファイル: syscall.c プロジェクト: 0xroot/radare2
R_API RSyscallItem *r_syscall_item_new_from_string(const char *name, const char *s) {
	RSyscallItem *si;
	char *o;

	if (!s) return NULL;
	si = R_NEW0 (RSyscallItem);
	o = strdup (s);

	r_str_split (o, ',');

/*
	return r_syscall_item_new (name, 
			r_num_get (NULL, r_str_word_get0 (o, 0)),
			r_num_get (NULL, r_str_word_get0 (o, 1)),
			r_num_get (NULL, r_str_word_get0 (o, 2)),
			r_str_word_get0 (o, 3));
*/

	si->name = strdup (name);
	si->swi = r_num_get (NULL, r_str_word_get0 (o, 0));
	si->num = r_num_get (NULL, r_str_word_get0 (o, 1));
	si->args = r_num_get (NULL, r_str_word_get0 (o, 2));
	si->sargs = strdup (r_str_word_get0 (o, 3));
	free (o);
	return si;
}
コード例 #4
0
bool test_r_str_tokenize(void) {
	//XXX r_str_word0 doesn't work on "hello      world" to
	// tokenize into ["hello", "world"]
	char* hi = strdup ("hello world");
	mu_assert_eq (r_str_word_set0 (hi), 1, "tokenize hello world");
	const char* hello = r_str_word_get0 (hi, 0);
	const char* world = r_str_word_get0 (hi, 1);
	mu_assert_streq (hello, "hello", "first string in split");
	mu_assert_streq (world, "world", "second string in split");
	free (hi);
	mu_end;
}
コード例 #5
0
ファイル: str.c プロジェクト: bigendiansmalls/radare2
R_API char *r_str_word_get0set(char *stra, int stralen, int idx, const char *newstr, int *newlen) {
	char *p = NULL;
	char *out;
	int alen, blen, nlen;
	if (!stra && !newstr) return NULL;
	if (stra)
		p = (char *)r_str_word_get0 (stra, idx);
	if (!p) {
		int nslen = strlen (newstr);
		out = malloc (nslen+1);
		if (!out) return NULL;
		strcpy (out, newstr);
		out[nslen] = 0;
		if (newlen)
			*newlen = nslen;
		return out;
	}
	alen = (size_t)(p-stra);
	blen = stralen - ((alen + strlen (p))+1);
	if (blen<0) blen = 0;
	nlen = alen+blen+strlen (newstr);
	out = malloc (nlen + 2);
	if (!out) return NULL;
	if (alen>0)
		memcpy (out, stra, alen);
	memcpy (out+alen, newstr, strlen (newstr)+1);
	if (blen>0)
		memcpy (out+alen+strlen (newstr)+1, p+strlen (p)+1, blen+1);
	out[nlen+1] = 0;
	if (newlen)
		*newlen = nlen + ((blen==0)?1:0);
	return out;
}
コード例 #6
0
ファイル: editor.c プロジェクト: silky/radare2
static void setnewline(int old) {
	snprintf (prompt, sizeof (prompt), "%d: ", _n);
	r_line_set_prompt (prompt);
	strcpy (I->line->buffer.data, r_str_word_get0 (lines, _n));
	I->line->buffer.index = 
	I->line->buffer.length = strlen (I->line->buffer.data);
		I->line->contents = I->line->buffer.data;
}
コード例 #7
0
ファイル: table.c プロジェクト: begoon/radare2
/* Get offset of given named field inside the table */
int r_db_table_key(struct r_db_table_t *table, const char *name) {
	const char *word;
	int i;
	for(i=0;i<table->nelems;i++) {
		word = r_str_word_get0(table->args, i);
		if (!strcmp(name, word))
			break;
	}
	return table->offset[i];
}
コード例 #8
0
ファイル: ctype.c プロジェクト: skuater/radare2
R_API char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset) {
	int i, 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;
		}
		typesize += r_type_get_bitsize (TDB, subtype) * arrsz;
		free (subtype);
	}
	free (members);
	return res;
}
コード例 #9
0
ファイル: syscall.c プロジェクト: 0xroot/radare2
R_API int r_syscall_get_num(RSyscall *ctx, const char *str) {
	char *o;
	int i = 0;
	if (!ctx->syspair)
		return 0;
	o = r_pair_get (ctx->syspair, str);
	if (o && *o) {
		r_str_split (o, ',');
		i = r_num_get (NULL, r_str_word_get0 (o, 1));
	}
	free (o);
	return i;
}
コード例 #10
0
ファイル: syscall.c プロジェクト: CodingFree/radare2
R_API int r_syscall_get_num(RSyscall *s, const char *str) {
	char *o;
	int i = -1;
	// TODO: use sdb array api here
	if (!s || !s->db)
		return -1;
	o = sdb_get (s->db, str, 0);
	if (o && *o) {
		r_str_split (o, ',');
		i = r_num_get (NULL, r_str_word_get0 (o, 1));
	}
	free (o);
	return i;
}
コード例 #11
0
ファイル: table.c プロジェクト: begoon/radare2
/* Get name of the N field in the table */
const char *r_db_table_field_i(struct r_db_table_t *table, int elem) {
	const char *name = NULL;
	if (elem>=0 && table->nelems<elem)
		name = r_str_word_get0 (table->args, elem);
	return name;
}
コード例 #12
0
ファイル: p_format.c プロジェクト: mjdunn/radare2
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
		const char *formatname, int mode, const char *setval, char *ofield) {
	int nargs, i, j, invalid, nexti, idx, times, otimes, endian, isptr = 0;
	const int old_bits = p->bits;
	char *args = NULL, *bracket, tmp, last = 0;
	ut64 addr = 0, addr64 = 0, seeki = 0;
	static int slide = 0, oldslide = 0;
	char namefmt[8], *field = NULL;
	const char *arg = NULL;
	const char *fmt = NULL;
	const char *argend;
	int viewflags = 0;
	char *oarg = NULL;
	ut8 *buf;

	/* Load format from name into fmt */
	if (!formatname) return 0;
	fmt = r_strht_get (p->formats, formatname);
	if (!fmt) fmt = formatname;
	while (*fmt && iswhitechar (*fmt)) fmt++;
	argend = fmt+strlen (fmt);
	arg = fmt;

	nexti = nargs = i = j = 0;

	if (len < 1) return 0;
	// len+2 to save space for the null termination in wide strings
	buf = calloc (1,len + 2);
	if (!buf) return 0;
	memcpy (buf, b, len);
	endian = p->big_endian;

	if (ofield && ofield != MINUSONE) field = strdup (ofield);

	/* get times */
	otimes = times = atoi (arg);
	if (times > 0) {
		while (*arg >= '0' && *arg <= '9') arg++;
	}

	bracket = strchr (arg,'{');
	if (bracket) {
		char *end = strchr (arg, '}');
		if (end == NULL) {
			eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
			goto beach;
		}
		*end = '\0';
		times = r_num_math (NULL, bracket+1);
		arg = end + 1;
	}

	if (*arg=='\0') {
		goto beach;
	}

	/* get args */
	args = get_args_offset (arg);
	if (args) {
		int l=0, maxl = 0;
		argend = args;
		args = strdup (args+1);
		nargs = r_str_word_set0 (args);
		if (nargs == 0)
			R_FREE (args);
		for (i=0; i<nargs; i++) {
			const int len = strlen (r_str_word_get0 (args, i));
			if (len > maxl)
				maxl = len;
		}
		l++;
		snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl+6*slide%STRUCTPTR);
	}
#define ISPOINTED ((slide%STRUCTFLAG)/STRUCTPTR<=(oldslide%STRUCTFLAG)/STRUCTPTR)
#define ISNESTED ((slide%STRUCTPTR)<=(oldslide%STRUCTPTR))
	if (mode == R_PRINT_JSON && slide==0) p->cb_printf("[");
	if (arg[0] == '0') {
		mode |= R_PRINT_UNIONMODE;
		arg++;
	} else {
		mode &= ~R_PRINT_UNIONMODE;
	}
	if (mode & R_PRINT_DOT) {
		char *fmtname;
		if (formatname && *formatname) {
			if (strchr (formatname, ' ')) {
				fmtname = r_str_newf ("0x%"PFMT64x, seek);
			} else {
				fmtname = strdup (formatname);
			}
		} else {
			fmtname = r_str_newf ("0x%"PFMT64x, seek);
		}
		p->cb_printf ("digraph g { graph [ rank=same; rankdir=LR; ];\n");
		p->cb_printf ("root [ rank=1; shape=record\nlabel=\"%s", fmtname);
	}

	/* go format */
	i = 0;
	if (!times)
		otimes = times = 1;
	for (; times; times--) { // repeat N times
		const char * orig = arg;
		int first = 1;
		if (otimes>1) {
			if (mode & R_PRINT_JSON) {
				if (otimes > times) p->cb_printf (",");
				p->cb_printf ("[{\"index\":%d,\"offset\":%d},", otimes-times, seek+i);
			} else {
				p->cb_printf ("0x%08"PFMT64x" [%d] {\n", seek+i, otimes-times);
			}
		}
		arg = orig;
		for (idx=0; i<len && arg<argend && *arg; arg++) {
			int size = 0, elem = 0; /* size of the array, element of the array */
			char *fieldname = NULL, *fmtname = NULL;
			if (mode & R_PRINT_UNIONMODE) {
				i = 0;
			}
			seeki = seek+i;
			addr = 0LL;
			invalid = 0;
			p->bits = old_bits;
			if (arg[0] == '[') {
				char *end = strchr (arg,']');
				if (end == NULL) {
					eprintf ("No end bracket.\n");
					goto beach;
				}
				*end = '\0';
				size = r_get_size (p->num, buf, endian, arg+1);
				arg = end + 1;
				*end = ']';
			} else {
				size = -1;
			}
			if (i+7<len) { // Max byte number where updateAddr will look into
				updateAddr (buf, i, endian, &addr, &addr64);
			} else {
				eprintf ("Likely a heap buffer overflow in %s at %d\n", __FILE__, __LINE__);
				goto beach;
			}

			tmp = *arg;

			if (args == NULL)
				mode |= R_PRINT_ISFIELD;
			if (mode & R_PRINT_MUSTSEE && otimes>1)
				p->cb_printf ("   ");
			if (idx<nargs && tmp != 'e' && isptr == 0) {
				char *dot = NULL, *bracket = NULL;
				if (field)
					dot = strchr (field, '.');
				if (dot)
					*dot = '\0';
				if (oarg != NULL)
					free (oarg);
				oarg = fieldname = strdup(r_str_word_get0 (args, idx));
				if (ISSTRUCT || tmp=='E' || tmp=='B' || tmp=='r') {
					if (*fieldname == '(') {
						fmtname = fieldname+1;
						fieldname = strchr (fieldname, ')');
						if (fieldname) *fieldname++ = '\0';
						else {
							eprintf ("Missing closing parenthesis in format ')'\n");
							goto beach;
						}
					} else {
						eprintf ("Missing name (%s)\n", fieldname);
						goto beach;
					}
				}
				if (args == NULL || (field==NULL && ofield != MINUSONE)
						|| (field && !strncmp(field, fieldname,
								strchr(field, '[')!=NULL?strchr(field, '[')-field:strlen(field)+1))) {
					mode |= R_PRINT_ISFIELD;
				} else {
					mode &= ~R_PRINT_ISFIELD;
				}

				/* There we handle specific element in array */
				if (field != NULL && (bracket = strchr (field, '[')) != NULL && mode & R_PRINT_ISFIELD) {
					char *end = strchr (field, ']');
					if (end == NULL) {
						eprintf ("Missing closing bracket\n");
						goto beach;
					}
					*end = '\0';
					elem = r_num_math (NULL, bracket+1)+1; // +1 to handle 0 index easily
					for ( ; bracket < end; bracket++)
						*bracket = '\0';
					size += elem*ARRAYINDEX_COEF;
				} else {
					elem = -1;
				}
				idx++;
				if (MUSTSEE && !SEEVALUE) {
					p->cb_printf (namefmt, fieldname);
				}
			}

		feed_me_again:
			switch (isptr) {
			case PTRSEEK:
				{
				nexti = i + (p->bits/8);
				i = 0;
				if (tmp == '?' ) seeki = addr;
				memset (buf, '\0', len);
				if (MUSTSEE)
					p->cb_printf ("(*0x%"PFMT64x") ", addr);
				if (addr == 0) isptr = NULLPTR;
				else isptr = PTRBACK;
				if (/*addr<(b+len) && addr>=b && */p->iob.read_at) { /* The test was here to avoid segfault in the next line,
						but len make it doesnt work... */
					p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4);
					if (i+3<len || i+7<len)
						updateAddr (buf, i, endian, &addr, &addr64);
					else {
						eprintf ("Likely a heap buffer overflow at %s at %d\n", __FILE__, __LINE__);
						goto beach;
					}
				} else {
					eprintf ("(SEGFAULT: cannot read memory at 0x%08"PFMT64x", Block: %s, blocksize: 0x%x)\n",
							addr, b, len);
					p->cb_printf("\n");
					goto beach;
				}
				}
				break;
			case PTRBACK:
				// restore state after pointer seek
				i = nexti;
				memcpy (buf, b, len);
				isptr = NOPTR;
				arg--;
				continue;
			}
			if (tmp == 0 && last != '*')
				break;

			/* skip chars */
			switch (tmp) {
			case '*': // next char is a pointer
				isptr = PTRSEEK;
				arg++;
				tmp = *arg; //last;
				goto feed_me_again;
			case '+': // toggle view flags
				viewflags = !viewflags;
				continue;
			case 'e': // tmp swap endian
				endian ^= 1;
				continue;
			case ':': // skip 4 bytes
				if (size == -1) i+=4;
				else while (size--) i+=4;
				continue;
			case '.': // skip 1 byte
				if (size == -1) i++;
				else i+=size;
				continue;
			case 'p': // pointer reference
				if (*(arg+1) == '2') {
					p->bits = 16;
					arg++;
				} else if (*(arg+1) == '4') {
					p->bits = 32;
					arg++;
				} else if (*(arg+1) == '8') {
					p->bits = 64;
					arg++;
				}
				switch (p->bits) {
					case 16: tmp = 'w'; break;
					case 32: tmp = 'x'; break;
					default: tmp = 'q'; break;
				}
				break;
			}

			/* flags */
			if (mode & R_PRINT_SEEFLAGS && isptr != NULLPTR) {
				char *newname = NULL;
				if (!fieldname) {
					newname = fieldname = r_str_newf ("pf.%d", seeki);
				}
				if (mode & R_PRINT_UNIONMODE) {
					p->cb_printf ("f %s=0x%08"PFMT64x"\n", formatname, seeki);
					goto beach;
				} else if (tmp == '?') {
					p->cb_printf ("f %s.%s_", fmtname, fieldname);
				} else if (tmp == 'E') {
					p->cb_printf ("f %s=0x%08"PFMT64x"\n", fieldname, seeki);
				} else if (slide/STRUCTFLAG>0 && idx==1) {
					p->cb_printf ("%s=0x%08"PFMT64x"\n", fieldname, seeki);
				} else p->cb_printf ("f %s=0x%08"PFMT64x"\n", fieldname , seeki);
				if (newname) {
					free (newname);
					newname = fieldname = NULL;
				}
			}

			/* dot */
			if (mode & R_PRINT_DOT) {
				if (fieldname) {
					p->cb_printf ("|{0x%"PFMT64x"|%c|%s|<%s>",
						seeki, tmp, fieldname, fieldname);
				} else {
					p->cb_printf ("|{0x%"PFMT64x"|%c|",
						seeki, tmp);
				}
			}

			/* json */
			if (MUSTSEEJSON && mode & R_PRINT_JSON) {
				if (oldslide <= slide) {
					if (first) first = 0;
					else p->cb_printf (",");
				} else if (oldslide) {
					p->cb_printf ("]},");
				}
				p->cb_printf ("{\"name\":\"%s\",\"type\":\"", fieldname);
				if (ISSTRUCT) {
					p->cb_printf ("%s", fmtname);
				} else {
					p->cb_printf ("%c", tmp);
				}
				if (isptr) p->cb_printf ("*");
				p->cb_printf ("\",\"offset\":%d,\"value\":",(isptr)?(seek+nexti-(p->bits/8)):seek+i);
			}

			if (isptr == NULLPTR) {
				if (MUSTSEEJSON) p->cb_printf ("\"NULL\"}", tmp, seek+i);
				else if (MUSTSEE) p->cb_printf ("NULL\n");
				isptr = PTRBACK;
			} else
			/* format chars */
			// before to enter in the switch statement check buf boundaries due to  updateAddr
			// might go beyond its len and it's usually called in each of the following functions
			if (((i+3)<len) || (i+7)<len) {
				switch (tmp) {
				case 'u':
					i+= r_print_format_uleb (p, endian, mode, setval, seeki, buf, i, size);
					break;
				case 't':
					r_print_format_time (p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 4 : 4*size;
					break;
				case 'q':
					r_print_format_quadword (p, endian, mode, setval, seeki, buf, i, size);
					i += (size==-1) ? 8 : 8*size;
					break;
				case 'b':
					r_print_format_byte (p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 1 : size;
					break;
				case 'C':
					r_print_format_decchar (p, endian, mode,
						setval, seeki, buf, i, size);
					i+= (size==-1) ? 1 : size;
					break;
				case 'c':
					r_print_format_char (p, endian, mode,
						setval, seeki, buf, i, size);
					i+= (size==-1) ? 1 : size;
					break;
				case 'X':
					size = r_print_format_hexpairs (p, endian, mode,
						setval, seeki, buf, i, size);
					i += size;
					break;
				case 'T':
					if (r_print_format_10bytes (p, mode,
						setval, seeki, addr, buf) == 0)
						i += (size==-1) ? 4 : 4*size;
					break;
				case 'f':
					r_print_format_float (p, endian, mode, setval, seeki, buf, i, size);
					i += (size==-1) ? 4 : 4*size;
					break;
				case 'i':
				case 'd':
					r_print_format_hex (p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 4 : 4*size;
					break;
				case 'D':
					if (size>0) p->cb_printf ("Size not yet implemented\n");
					if (p->disasm && p->user)
						i += p->disasm (p->user, seeki);
					break;
				case 'o':
					r_print_format_octal (p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 4 : 4*size;
					break;
				case 'x':
					r_print_format_hexflag (p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 4 : 4*size;
					break;
				case 'w':
					r_print_format_word(p, endian, mode, setval, seeki, buf, i, size);
					i+= (size==-1) ? 2 : 2*size;
					break;
				case 'z': // zero terminated string
					r_print_format_nulltermstring (p, len, endian, mode, setval, seeki, buf, i, size);
					if (size == -1)
						i+=strlen((char*)buf+i)+1;
					else
						while (size--) i++;
					break;
				case 'Z': // zero terminated wide string
					r_print_format_nulltermwidestring (p, len, endian, mode, setval, seeki, buf, i, size);
					if (size == -1)
						i += r_wstr_clen((char*)(buf+i))*2+2;
					else
						while (size--) i+=2;
					break;
				case 's':
					if (r_print_format_string (p, seeki, addr64, addr, 0, mode) == 0)
						i += (size==-1) ? 4 : 4*size;
					break;
				case 'S':
					if (r_print_format_string (p, seeki, addr64, addr, 1, mode) == 0)
						i += (size==-1) ? 8 : 8*size;
					break;
				case 'B': // resolve bitfield
					if (size >= ARRAYINDEX_COEF) size %= ARRAYINDEX_COEF;
					r_print_format_bitfield (p, seeki, fmtname, fieldname, addr, mode, size);
					i+=(size==-1)?1:size;
					break;
				case 'E': // resolve enum
					if (size >= ARRAYINDEX_COEF) size %= ARRAYINDEX_COEF;
					r_print_format_enum (p, seeki, fmtname, fieldname, addr, mode, size);
					i+=(size==-1)?1:size;
					break;
				case 'r':
					r_print_format_register (p, mode, fmtname, setval);
					break;
				case '?':
					{
					int s = 0;
					char *nxtfield = NULL;
					if (size >= ARRAYINDEX_COEF) {
						elem = size/ARRAYINDEX_COEF-1;
						size %= ARRAYINDEX_COEF;
					}
					if (!(mode & R_PRINT_ISFIELD)) nxtfield = MINUSONE;
					else if (field) nxtfield = strchr (ofield, '.');
					if (nxtfield != MINUSONE && nxtfield != NULL) nxtfield++;

					if (MUSTSEE)
						if (!SEEVALUE) p->cb_printf ("\n");
					if (MUSTSEEJSON) {
						if (isptr)
							p->cb_printf ("%d},", seeki);
						else
							p->cb_printf ("[");
					}
					if (mode & R_PRINT_SEEFLAGS) slide+=STRUCTFLAG;
					oldslide = slide;
					slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT;
					if (size == -1) {
						s = r_print_format_struct (p, seeki,
							buf+i, len-i, fmtname, slide,
							mode, setval, nxtfield);
						i+= (isptr) ? 4 : s;
					} else {
						if (mode & R_PRINT_ISFIELD)
							if (!SEEVALUE) p->cb_printf ("[\n");
						while (size--) {
							if (elem == -1 || elem == 0) {
								mode |= R_PRINT_MUSTSEE;
								if (elem == 0) elem = -2;
							} else {
								mode &= ~R_PRINT_MUSTSEE;
							}
							s = r_print_format_struct (p, seek+i,
								buf+i, len-i, fmtname, slide, mode, setval, nxtfield);
							if ((MUSTSEE || MUSTSEEJSON) && size != 0 && elem == -1) {
								p->cb_printf (",");
								if (MUSTSEE) p->cb_printf ("\n");
							}
							if (elem > -1) elem--;
							i+= (isptr) ? 4 : s;
						}
						if (mode & R_PRINT_ISFIELD)
							if (!SEEVALUE) p->cb_printf ("]");
						if (MUSTSEEJSON) p->cb_printf ("]}]}");
					}
					oldslide = slide;
					slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT;
					if (mode & R_PRINT_SEEFLAGS) {
						oldslide = slide;
						slide-=STRUCTFLAG;
					}
					break;
					}
				default:
					/* ignore unknown chars */
					invalid = 1;
					break;
				} //switch
			} else {
				eprintf ("Likely a heap buffer overflow in %s at %d\n", __FILE__, __LINE__);
				goto beach;
			}
			if (mode & R_PRINT_DOT) {
				p->cb_printf ("}");
			}
			if (viewflags && p->offname) {
				const char *s = p->offname (p->user, seeki);
				if (s)
					p->cb_printf ("@(%s)", s);
				s = p->offname (p->user, addr);
				if (s)
					p->cb_printf ("*(%s)", s);
			}
			if (tmp != 'D' && !invalid && fmtname==NULL && MUSTSEE)
				p->cb_printf ("\n");
			last = tmp;
		}
		if (otimes>1) {
			if (MUSTSEEJSON) p->cb_printf ("]");
			else p->cb_printf ("}\n");
		}
		arg = orig;
		oldslide = 0;
	}
	if (mode & R_PRINT_JSON && slide==0) p->cb_printf("]\n");
	if (mode & R_PRINT_DOT) {
		p->cb_printf ("\"];\n}\n");
		// TODO: show nested structs and field reference lines
	}
beach:
	free (oarg);
	free (buf);
	free (field);
	free (args);
	return i;
}
コード例 #13
0
ファイル: p_format.c プロジェクト: jody-frankowski/radare2
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
		const char *fmt, int mode, const char *setval, char *ofield) {
	int nargs, i, j, invalid, nexti, idx, times, otimes, endian, isptr = 0;
	const char *argend;
	ut64 addr = 0, addr64 = 0, seeki = 0;;
	char *args = NULL, *bracket, tmp, last = 0;
	const char *arg = fmt;
	int viewflags = 0;
	char namefmt[8], *field = NULL;
	static int slide=0, oldslide=0;
	ut8 *buf;
	if (!fmt)
		return 0;
	argend = fmt+strlen (fmt);

	nexti = nargs = i = j = 0;

	if (len < 1)
		return 0;
	buf = malloc (len);
	if (!buf)
		return 0;
	memcpy (buf, b, len);
	endian = p->big_endian;

	if (ofield && ofield != MINUSONE) field = strdup (ofield);

	while (*arg && iswhitechar (*arg)) arg++;

	/* get times */
	otimes = times = atoi (arg);
	if (times > 0)
		while ((*arg>='0'&&*arg<='9')) arg++;

	bracket = strchr (arg,'{');
	if (bracket) {
		char *end = strchr (arg, '}');
		if (end == NULL) {
			eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
			goto beach;
		}
		*end='\0';
		times = r_num_math (NULL, bracket+1);
		arg = end + 1;
	}

	if (*arg=='\0') {
		goto beach;
	}

	/* get args */
	args = strchr (arg, ' ');
	if (args) {
		int l=0, maxl = 0;
		argend = args;
		args = strdup (args+1);
		nargs = r_str_word_set0 (args);
		if (nargs == 0)
			R_FREE (args);
		for (i=0; i<nargs; i++) {
			const int len = strlen (r_str_word_get0 (args, i));
			if (len > maxl)
				maxl = len;
		}
		l++;
		snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl+6*slide%STRUCTPTR);
	}
#define ISPOINTED ((slide%STRUCTFLAG)/STRUCTPTR<=(oldslide%STRUCTFLAG)/STRUCTPTR)
#define ISNESTED ((slide%STRUCTPTR)<=(oldslide%STRUCTPTR))
	if (mode == R_PRINT_JSON && slide==0) p->printf("[");
	if (arg[0] == '0') {
		mode |= R_PRINT_UNIONMODE;
		arg++;
	} else {
		mode &= ~R_PRINT_UNIONMODE;
	}

	/* go format */
	i = 0;
	if (!times)
		otimes = times = 1;
	for (; times; times--) { // repeat N times
		const char * orig = arg;
		int first = 1;
		if (otimes>1) {
			if (mode & R_PRINT_JSON) {
				if (otimes > times) p->printf (",");
				p->printf ("[{\"index\":%d,\"offset\":%d},", otimes-times, seek+i);
			} else
				p->printf ("0x%08"PFMT64x" [%d] {\n", seek+i, otimes-times);
		}
		arg = orig;
		for (idx=0; i<len && arg<argend && *arg; arg++) {
			int size, elem; /* size of the array, element of the array */
			char *fieldname = NULL, *fmtname = NULL, *oarg = NULL;
			if (mode & R_PRINT_UNIONMODE) {
				i = 0;
			}
			seeki = seek+i;
			addr = 0LL;
			invalid = 0;
			if (arg[0] == '[') {
				char *end = strchr (arg,']');
				if (end == NULL) {
					eprintf ("No end bracket.\n");
					goto beach;
				}
				*end = '\0';
				size = r_num_math (NULL, arg+1);
				arg = end + 1;
				*end = ']';
			} else {
				size = -1;
			}
			updateAddr (buf, i, endian, &addr, &addr64);

			tmp = *arg;

			if (args == NULL)
				mode |= R_PRINT_ISFIELD;
			if (mode & R_PRINT_MUSTSEE && otimes>1)
				p->printf ("   ");
			if (idx<nargs && tmp != 'e' && isptr == 0) {
				char *dot = NULL, *bracket = NULL;
				if (field)
					dot = strchr (field, '.');
				if (dot)
					*dot = '\0';
				oarg = fieldname = strdup(r_str_word_get0 (args, idx));
				if (ISSTRUCT || tmp=='E' || tmp=='B') {
					if (*fieldname == '(') {
						fmtname = fieldname+1;
						fieldname = strchr (fieldname, ')');
						if (fieldname) *fieldname++ = '\0';
						else {
							eprintf ("Missing closing parenthesis in format ')'\n");
							free (oarg);
							goto beach;
						}
					} else {
						eprintf ("Missing name (%s)\n", fieldname);
						free(oarg);
						goto beach;
					}
				}
				if (args == NULL || (field==NULL && ofield != MINUSONE)
						|| (field && !strncmp(field, fieldname, strlen(fieldname)))) {
					mode |= R_PRINT_ISFIELD;
				} else {
					mode &= ~R_PRINT_ISFIELD;
				}
				/* There we handle specific element in array */
				if (field != NULL && (bracket = strchr (field, '[')) != NULL && mode & R_PRINT_ISFIELD) {
					char *end = strchr (field, ']');
					if (end == NULL) {
						eprintf ("Missing closing bracket\n");
						goto beach;
					}
					*end = '\0';
					elem = r_num_math (NULL, bracket+1)+1; // +1 to handle 0 index easily
					for ( ; bracket < end; bracket++)
						*bracket = '\0';
					size += elem*ARRAYINDEX_COEF;
				} else {
					elem = -1;
				}
				idx++;
				if (MUSTSEE) {
					p->printf (namefmt, fieldname);
				}
			}

		feed_me_again:
			switch (isptr) {
			case 1:
				{
				nexti = i + (p->bits/8);
				i = 0;
				if(tmp == '?' )seeki = addr;
				memset (buf, '\0', len);
				if (MUSTSEE)
					p->printf ("(*0x%"PFMT64x") ", addr);
				if (addr == 0) isptr = NULLPTR;
				else isptr = PTRBACK;
				if (/*addr<(b+len) && addr>=b && */p->iob.read_at) { /* The test was here to avoid segfault in the next line,
						but len make it doesnt work... */
					p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4);
					updateAddr (buf, i, endian, &addr, &addr64);
				} else {
					eprintf ("(SEGFAULT: cannot read memory at 0x%08"PFMT64x", Block: %s, blocksize: 0x%x)\n",
							addr, b, len);
					p->printf("\n");
					free (oarg);
					goto beach;
				}
				}
				break;
			case 2:
				// restore state after pointer seek
				i = nexti;
				seeki = seek+i;
				memcpy (buf, b, len);
				isptr = NOPTR;
				arg--;
				continue;
			}
			if (tmp == 0 && last != '*')
				break;

			/* skip chars */
			switch (tmp) {
			case '*': // next char is a pointer
				isptr = PTRSEEK;
				arg++;
				tmp = *arg; //last;
				goto feed_me_again;
			case '+': // toggle view flags
				viewflags = !viewflags;
				continue;
			case 'e': // tmp swap endian
				endian ^= 1;
				continue;
			case ':': // skip 4 bytes
				if (size == -1) i+=4;
				else
					while (size--) i+=4;
				continue;
			case '.': // skip 1 byte
				if (size == -1) i++;
				else
					i+=size;
				continue;
			case 'p': // pointer reference
				tmp = (p->bits == 64)? 'q': 'x';
				break;
			}
			/* flags */
			if (mode & R_PRINT_SEEFLAGS && isptr != NULLPTR) {
				if (tmp == '?') {
					p->printf ("f %s.%s_", fmtname, fieldname);
				} else if (tmp == 'E') {
					p->printf ("f %s=0x%08"PFMT64x"\n", fieldname, seeki);
				} else if (slide/STRUCTFLAG>0 && idx==1) {
					p->printf ("%s=0x%08"PFMT64x"\n", fieldname, seeki);
				} else p->printf ("f %s=0x%08"PFMT64x"\n", fieldname , seeki);
			}
			/* json */
			if (mode & R_PRINT_JSON) {
				if (oldslide<=slide) {
					if (!first)
						p->printf (",");
					else
						first = 0;
				} else if(oldslide!=0) {
					p->printf ("]},");
				}
				p->printf ("{\"name\":\"%s\",\"type\":\"", fieldname);
				if (ISSTRUCT) {
					p->printf ("%s", fmtname);
				} else {
					p->printf ("%c", tmp);
				}
				if (isptr) p->printf ("*");
				p->printf ("\",\"offset\":%d,\"value\":",(isptr)?(seek+nexti-(p->bits/8)):seek+i);
			}

			if (isptr == NULLPTR) {
				if (MUSTSEEJSON)
					p->printf ("\"NULL\"}", tmp, seek+i);
				else if (MUSTSEE)
					p->printf ("NULL\n");
				isptr = PTRBACK;
			} else
			/* format chars */
			switch (tmp) {
			case 't':
				r_print_format_time(p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'q':
				r_print_format_quadword(p, endian, mode, setval, seeki, buf, i, size);
				i += (size==-1) ? 8 : 8*size;
				break;
			case 'b':
				r_print_format_byte(p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 1 : size;
				break;
			case 'c':
				r_print_format_char (p, endian, mode,
					setval, seeki, buf, i, size);
				i+= (size==-1) ? 1 : size;
				break;
			case 'X':
				size = r_print_format_hexpairs (p, endian, mode,
					setval, seeki, buf, size);
				i += size;
				break;
			case 'T':
				if(r_print_format_10bytes(p, mode,
					setval, seeki, addr, buf) == 0)
					i += (size==-1) ? 4 : 4*size;
				break;
			case 'f':
				r_print_format_float(p, endian, mode, setval, seeki, buf, i, size);
				i += (size==-1) ? 4 : 4*size;
				break;
			case 'i':
			case 'd':
				r_print_format_hex(p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'D':
				if (size>0) p->printf ("Size not yet implemented\n");
				if (p->disasm && p->user)
					i += p->disasm (p->user, seeki);
				break;
			case 'o':
				r_print_format_octal (p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'x':
				r_print_format_hexflag(p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'w':
				r_print_format_word(p, endian, mode, setval, seeki, buf, i, size);
				i+= (size==-1) ? 2 : 2*size;
				break;
			case 'z': // zero terminated string
				r_print_format_nulltermstring (p, len, endian, mode, setval, seeki, buf, i, size);
				if (size == -1)
					i+=strlen((char*)buf+i)+1;
				else
					while (size--) i++;
				break;
			case 'Z': // zero terminated wide string
				r_print_format_nulltermwidestring (p, len, endian, mode, setval, seeki, buf, i, size);
				if (size == -1)
					i+=r_wstr_clen((char*)(buf+seeki))*2+2;
				else
					while (size--) i+=2;
				break;
			case 's':
				if (r_print_format_string (p, seeki, addr64, addr, 0, mode) == 0)
					i += (size==-1) ? 4 : 4*size;
				break;
			case 'S':
				if (r_print_format_string (p, seeki, addr64, addr, 1, mode) == 0)
					i += (size==-1) ? 8 : 8*size;
				break;
			case 'B': // resolve bitfield
				if (size >= ARRAYINDEX_COEF) size %= ARRAYINDEX_COEF;
				r_print_format_bitfield (p, seeki, fmtname, fieldname, addr, mode, size);
				i+=(size==-1)?1:size;
				break;
			case 'E': // resolve enum
				if (size >= ARRAYINDEX_COEF) size %= ARRAYINDEX_COEF;
				r_print_format_enum (p, seeki, fmtname, fieldname, addr, mode, size);
				i+=(size==-1)?1:size;
				break;
			case '?':
				{
				int s = 0;
				char *nxtfield = NULL;
				if (size >= ARRAYINDEX_COEF) {
					elem = size/ARRAYINDEX_COEF-1;
					size %= ARRAYINDEX_COEF;
				}
				if (!(mode & R_PRINT_ISFIELD)) nxtfield = MINUSONE;
				else if (field) nxtfield = strchr (ofield, '.');
				if (nxtfield != MINUSONE && nxtfield != NULL) nxtfield++;

				if (MUSTSEE)
					p->printf ("\n");
				if (MUSTSEEJSON) {
					if (isptr)
						p->printf ("%d},", seeki);
					else
						p->printf ("[");
				}
				if (mode & R_PRINT_SEEFLAGS) slide+=STRUCTFLAG;
				oldslide = slide;
				slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT;
				if (size == -1) {
					s = r_print_format_struct (p, seeki,
						buf+i, len-i, fmtname, slide,
						mode, setval, nxtfield);
					i+= (isptr) ? 4 : s;
				} else {
					p->printf ("[\n");
					while (size--) {
						if (elem == -1 || elem == 0) {
							mode |= R_PRINT_MUSTSEE;
							if (elem == 0) elem = -2;
						} else {
							mode &= ~R_PRINT_MUSTSEE;
						}
						s = r_print_format_struct (p, seek+i,
							buf+i, len-i, fmtname, slide, mode, setval, nxtfield);
						if (size != 0 && elem == -1)
							p->printf (",\n");
						if (elem > -1) elem--;
						i+= (isptr) ? 4 : s;
					}
					if (MUSTSEEJSON) p->printf ("]]}");
					else p->printf ("]");
				}
				oldslide = slide;
				slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT;
				if (mode & R_PRINT_SEEFLAGS) {
					oldslide = slide;
					slide-=STRUCTFLAG;
				}
				break;
				}
			default:
				/* ignore unknown chars */
				invalid = 1;
				break;
			}
			if (viewflags && p->offname) {
				const char *s = p->offname (p->user, seeki);
				if (s)
					p->printf ("@(%s)", s);
				s = p->offname (p->user, addr);
				if (s)
					p->printf ("*(%s)", s);
			}
			if (tmp != 'D' && !invalid && fmtname==NULL && MUSTSEE)
				p->printf ("\n");
			last = tmp;
			if (oarg)
				free (oarg);
		}
		if (otimes>1) {
			if (MUSTSEEJSON) p->printf ("]");
			else p->printf ("}\n");
		}
		arg = orig;
		oldslide = 0;
	}
	if (mode & R_PRINT_JSON && slide==0) p->printf("]");
beach:
	free (buf);
	free (field);
	if (args)
		free (args);
	return i;
}
コード例 #14
0
ファイル: p_format.c プロジェクト: svensvin/radare2
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
		const char *fmt, int elem, const char *setval) {
	int nargs, i, j, invalid, nexti, idx, times, otimes, endian, isptr = 0;
	int (*oldprintf)(const char *str, ...);
	const char *argend = fmt+strlen (fmt);
	ut64 addr = 0, addr64 = 0, seeki = 0;;
	char *args = NULL, *bracket, tmp, last = 0;
	const char *arg = fmt;
	int viewflags = 0, flag = (elem==SEEFLAG)?1:0;
	char namefmt[8];
	static int slide=0;
	ut8 *buf;

	nexti = nargs = i = j = 0;

	if (len < 1)
		return 0;
	buf = malloc (len);
	if (!buf)
		return 0;
	memcpy (buf, b, len);
	endian = p->big_endian;

	oldprintf = NULL;
	realprintf = p->printf;

	while (*arg && iswhitechar (*arg)) arg++;

	/* get times */
	otimes = times = atoi (arg);
	if (times > 0)
		while ((*arg>='0'&&*arg<='9')) arg++;

	bracket = strchr (arg,'{');
	if (bracket) {
		char *end = strchr (arg, '}');
		if (end == NULL) {
			eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
			goto beach;
		}
		*end='\0';
		times = r_num_math (NULL, bracket+1);
		arg = end + 1;
	}

	if (*arg=='\0' || *arg=='?') {
		print_format_help (p);
		goto beach;
	}

	/* get args */
	args = strchr (arg, ' ');
	if (args) {
		int l=0, maxl = 0;
		argend = args;
		args = strdup (args+1);
		nargs = r_str_word_set0 (args);
		if (nargs == 0)
			R_FREE (args);
		for (i=0; i<nargs; i++) {
			const int len = strlen (r_str_word_get0 (args, i));
			if (len > maxl)
				maxl = len;
		}
		l++;
		snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl+6*slide%STRUCTPTR);
	}

	/* go format */
	i = 0;
	if (!times)
		otimes = times = 1;
	for (; times; times--) { // repeat N times
		const char * orig = arg;
		if (otimes>1)
			p->printf ("0x%08"PFMT64x" [%d] {\n", seek+i, otimes-times);
		arg = orig;
		for (idx=0; i<len && arg<argend && *arg; arg++) {
			int size;
			char *name = NULL;
			seeki = seek+i;
			addr = 0LL;
			invalid = 0;
			if (arg[0] == '[') {
				char *end = strchr (arg,']');
				if (end == NULL) {
					eprintf ("No end bracket.\n");
					goto beach;
				}
				*end = '\0';
				size = r_num_math (NULL, arg+1);
				arg = end + 1;
				*end = ']';
			} else {
				size = -1;
			}
			updateAddr (buf, i, endian, &addr, &addr64);

			tmp = *arg;

			if (otimes>1)
				p->printf ("   ");
#define MUSTSET (setval && elem == idx)
#define MUSTSEE (elem == -1 || elem == idx)
			if (MUSTSEE && !flag) {
				if (!(MUSTSET)) {
					if (oldprintf)
						p->printf = oldprintf;
					if (idx<nargs && tmp != 'e' && isptr == 0) {
						p->printf (namefmt, r_str_word_get0 (args, idx));
						idx++;
					}
				}
			} else {
				if (!oldprintf)
					oldprintf = p->printf;
				p->printf = nullprintf;
			}

		feed_me_again:
			switch (isptr) {
			case 1:
				{
				nexti = i + (p->bits/8);
				i = 0;
				if(tmp == '?' )seeki = addr;
				memset (buf, '\0', len);
				p->printf ("(*0x%"PFMT64x") ", addr);
				if (addr == 0) isptr = NULLPTR;
				else isptr = PTRBACK;
				if (/*addr<(b+len) && addr>=b && */p->iob.read_at) { /* The test was here to avoid segfault in the next line, 
						but len make it doesnt work... */
					p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4);
					updateAddr (buf, i, endian, &addr, &addr64);
				} else {
					eprintf ("(SEGFAULT: cannot read memory at 0x%08"PFMT64x", Block: %s, blocksize: 0x%x)\n",
							addr, b, len);
					p->printf("\n");
					goto beach;
				}
				}
				break;
			case 2:
				// restore state after pointer seek
				i = nexti;
				seeki = seek+i;
				memcpy (buf, b, len);
				isptr = NOPTR;
				arg--;
				continue;
			}
			if (tmp == 0 && last != '*')
				break;

			/* skip chars */
			switch (tmp) {
			case '*': // next char is a pointer
				isptr = PTRSEEK;
				arg++;
				tmp = *arg; //last;
				goto feed_me_again;
			case '+': // toggle view flags
				viewflags = !viewflags;
				continue;
			case 'e': // tmp swap endian
				endian ^= 1;
				continue;
			case ':': // skip 4 bytes
				if (size == -1) i+=4;
				else
					while (size--) i+=4;
				continue;
			case '.': // skip 1 byte
				if (size == -1) i++;
				else
					while (size--) i++;
				continue;
			case 'p': // pointer reference
				tmp = (p->bits == 64)? 'q': 'x';
				//tmp = (sizeof (void*)==8)? 'q': 'x';
				break;
			}
			if (flag && isptr != NULLPTR) {
				if (tmp == '?') {
					char *n = strdup (r_str_word_get0 (args, idx)+1);
					char *par = strchr (n, ')');
					if (par == NULL) {
						eprintf ("No end parenthesis for struct name");
						free (n);
						goto beach;
					} else {
						*par = '.';
					}
					realprintf ("f %s_", n);
					free(n);
				} else if (slide>0 && idx==0) {
					realprintf ("%s=0x%08"PFMT64x"\n",
						r_str_word_get0 (args, idx), seeki);
				} else realprintf ("f %s=0x%08"PFMT64x"\n",
					r_str_word_get0 (args, idx) , seeki);
				idx++;
			}

			if (isptr == NULLPTR) {
				p->printf ("NULL");
				isptr = PTRBACK;
			} else
			/* cmt chars */
			switch (tmp) {
#if 0
			case 't':
				/* unix timestamp */
				D cons_printf("0x%08x = ", config.seek+i);
				{
				/* dirty hack */
				int oldfmt = last_print_format;
				ut64 old = config.seek;
				radare_seek(config.seek+i, SEEK_SET);
				radare_read(0);
				print_data(config.seek+i, "8", buf+i, 4, FMT_TIME_UNIX);
				last_print_format=oldfmt;
				radare_seek(old, SEEK_SET);
				}
				break;
#endif
			case 'e': //WTF is this? 'e' is supposed to swap endians?!
				if (size > 0)
					p->printf ("Size not yet implemented\n");
				if (MUSTSET) {
					realprintf ("?e pf e not yet supported\n");
				} else {
					double doub;
					memcpy (&doub, buf+i, sizeof (double));
					p->printf ("0x%08"PFMT64x" = (double) ", seeki);
					p->printf ("%e", doub);
					i += 8;
				}
				break;
			case 'q':
				r_print_format_quadword(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i += (size==-1) ? 8 : 8*size;
				break;
			case 'b':
				r_print_format_byte(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i+= (size==-1) ? 1 : size;
				break;
			case 'c':
				r_print_format_char (p, endian, MUSTSET,
					setval, seeki, buf, i, size);
				i+= (size==-1) ? 1 : size;
				break;
			case 'X':
				size = r_print_format_hexpairs (p, endian, MUSTSET,
					setval, seeki, buf, size);
				i += size;
				break;
			case 'T':
				if(r_print_format_10bytes(p, MUSTSET,
					setval, seeki, addr, buf) == 0)
					i += (size==-1) ? 4 : 4*size;
				break;
			case 'f':
				r_print_format_float(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i += (size==-1) ? 4 : 4*size;
				break;
			case 'i':
			case 'd':
				r_print_format_hex(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'D':
				if (size>0) p->printf ("Size not yet implemented\n");
				if (p->disasm && p->user)
					i += p->disasm (p->user, seeki);
				break;
			case 'o':
				r_print_format_octal (p, endian, MUSTSET, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'x':
				r_print_format_hexflag(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i+= (size==-1) ? 4 : 4*size;
				break;
			case 'w':
			case '1': // word (16 bits)
				r_print_format_word(p, endian, MUSTSET, setval, seeki, buf, i, size);
				i+= (size==-1) ? 2 : 2*size;
				break;
			case 'z': // zero terminated string
				if (MUSTSET) {
					int buflen = strlen ((const char *)buf);
					if (buflen>seeki) {
						buflen = strlen ((const char *)buf+seeki);
					}
					if (strlen (setval) > buflen) {
						eprintf ("Warning: new string is longer than previous one \n");
					}
					realprintf ("w %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					for (; ((size || size==-1) && buf[i]) && i<len; i++) {
						if (IS_PRINTABLE (buf[i]))
							p->printf ("%c", buf[i]);
						else p->printf (".");
						size -= (size==-1) ? 0 : 1;
					}
				}
				if (size == -1)
					i++;
				else
					while (size--) i++;
				break;
			case 'Z': // zero terminated wide string
				if (MUSTSET) {
					if ((size = strlen(setval)) > r_wstr_clen((char*)(buf+seeki)))
						eprintf ("Warning: new string is longer than previous one\n");
					realprintf ("ww %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					for (; ((size || size==-1) && buf[i]) && i<len; i+=2) {
						if (IS_PRINTABLE (buf[i]))
							p->printf ("%c", buf[i]);
						else p->printf (".");
						size -= (size==-1) ? 0 : 1;
					}
				}
				if (size == -1)
					i+=2;
				else
					while (size--) i+=2;
				break;
			case 's':
				if (r_print_format_ptrstring (p, seeki, addr64, addr, 0) == 0)
					i += (size==-1) ? 4 : 4*size;
				break;
			case 'S':
				if (r_print_format_ptrstring (p, seeki, addr64, addr, 1) == 0)
					i += (size==-1) ? 8 : 8*size;
				break;
			case 'B': // resolve bitfield
				{
				char *structname, *osn;
				char *bitfield = NULL;
				structname = osn = strdup (r_str_word_get0 (args, idx-1));
				switch (size) {
				case 1: addr &= UT8_MAX; break;
				case 2: addr &= UT16_MAX; break;
				case 4: addr &= UT32_MAX; break;
				}
				if (*structname == '(') {
					name = strchr (structname, ')');
				} else {
					eprintf ("Bitfield name missing (%s)\n", structname);
					free (structname);
					goto beach;
				}
				structname++;
				if (name) *(name++) = '\0';
				else eprintf ("No ')'\n");

				if (p->get_bitfield) 
					bitfield = p->get_bitfield (p->user, structname, addr);
				if (bitfield && *bitfield) {
					p->printf (" %s (bitfield) = %s\n", name, bitfield);
				} else {
					p->printf (" %s (bitfield) = `tb %s 0x%x`\n",
						name, structname, addr);
				}
				i+= 4; //(isptr) ? 4 : s;
				free (osn);
				free (bitfield);
				}
				break;
			case 'E': // resolve enum
				{
				char *enumname, *osn;
				char *enumvalue = NULL;
				enumname = osn = strdup (r_str_word_get0 (args, idx-1));
				switch (size) {
				case 1: addr &= UT8_MAX; break;
				case 2: addr &= UT16_MAX; break;
				case 4: addr &= UT32_MAX; break;
				}
				if (*enumname == '(') {
					name = strchr (enumname, ')');
				} else {
					eprintf ("Enum name missing (%s)\n", enumname);
					free (enumname);
					goto beach;
				}
				enumname++;
				if (name) *(name++) = '\0';
				else eprintf ("No ')'\n");
				if (p->get_enumname) 
					enumvalue = p->get_enumname (p->user, enumname, addr);
				if (enumvalue && *enumvalue) {
					p->printf (" %s (enum) = 0x%"PFMT64x" ; %s\n",
						name, addr, enumvalue);
				} else {
					p->printf (" %s (enum) = `te %s 0x%x`\n",
						name, enumname, addr);
				}
				i+= (size==-1) ? 1 : size;
				free (osn);
				free (enumvalue);
				}
				break;
			case '?':
				{
				int s;
				char *structname, *osn;
				structname = osn = strdup (r_str_word_get0 (args, idx-1));
				if (*structname == '(') {
					name = strchr (structname, ')');
				} else {
					eprintf ("Struct name missing (%s)\n", structname);
					free (structname);
					goto beach;
				}
				structname++;
				if (name) *(name++) = '\0';
				else eprintf ("No ')'\n");
				p->printf ("<struct>\n");
				if (flag) slide+=STRUCTFLAG;
				slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT;
				s = r_print_format_struct (p, seeki,
					buf+i, len, structname--, slide);
				i+= (isptr) ? 4 : s;
				slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT;
				if (flag) slide-=STRUCTFLAG;
				free (osn);
				break;
				}
			default:
				/* ignore unknown chars */
				invalid = 1;
				break;
			}
			if (!flag && (!MUSTSEE || MUSTSET))
				idx++;
			if (viewflags && p->offname) {
				const char *s = p->offname (p->user, seeki);
				if (s)
					p->printf ("@(%s)", s);
				s = p->offname (p->user, addr);
				if (s)
					p->printf ("*(%s)", s);
			}
			if (tmp != 'D' && !invalid && name==NULL)
				p->printf ("\n");
			last = tmp;
		}
		if (otimes>1)
			p->printf ("}\n");
		arg = orig;
	}
	if (oldprintf)
		p->printf = oldprintf;
beach:
	free (buf);
	if (args)
		free (args);
	return i;
}
コード例 #15
0
ファイル: rtr.c プロジェクト: dialeth/radare2
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
	char buf[32];
	RSocketHTTPRequest *rs;
	int iport, oldsandbox = -1;
	int timeout = r_config_get_i (core->config, "http.timeout");
	int x = r_config_get_i (core->config, "scr.html");
	int y = r_config_get_i (core->config, "scr.color");
	int z = r_config_get_i (core->config, "asm.bytes");
	int u = r_config_get_i (core->config, "scr.interactive");
	int v = r_config_get_i (core->config, "asm.cmtright");
	const char *port = r_config_get (core->config, "http.port");
	char *allow = (char *)r_config_get (core->config, "http.allow");
	if (core->http_up) {
		eprintf ("http server is already running\n");
		return 1;
	}
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return 1;
	}
	if (path && atoi (path)) {
		port = path;
		path = NULL;
	}
	if (!strcmp (port, "0")) {
		r_num_irand ();
		iport = 1024+r_num_rand (45256);
		snprintf (buf, sizeof (buf), "%d", iport);
		port = buf;
	}
	s = r_socket_new (R_FALSE);
	s->local = !r_config_get_i (core->config, "http.public");
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on http.port\n");
		return 1;
	}
	if (launch) {
		char cmd[128];
		const char *browser = r_config_get (core->config, "http.browser");
		snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &",
			browser, atoi (port), path?path:"");
		r_sys_cmd (cmd);
	}
	r_config_set (core->config, "asm.cmtright", "false");
	r_config_set (core->config, "scr.html", "true");
	r_config_set (core->config, "scr.color", "false");
	r_config_set (core->config, "asm.bytes", "false");
	r_config_set (core->config, "scr.interactive", "false");
	if (r_config_get_i (core->config, "http.sandbox")) {
		oldsandbox = r_config_get_i (core->config, "cfg.sandbox");
		r_config_set (core->config, "cfg.sandbox", "true");
	}
	eprintf ("Starting http server...\n");
	eprintf ("http://localhost:%d/\n", atoi (port));
	core->http_up = R_TRUE;
	while (!r_cons_singleton ()->breaked) {
		r_cons_break ((RConsBreak)http_break, core);
		rs = r_socket_http_accept (s, timeout);
		if (!rs) {
			if (!s) break;
			r_sys_usleep (100);
			continue;
		}
		if (allow && *allow) {
			int accepted = R_FALSE;
			const char *host;
			char *p, *peer = r_socket_to_string (rs->s);
			char *allows = strdup (allow);
			//eprintf ("Firewall (%s)\n", allows);
			int i, count = r_str_split (allows, ',');
			p = strchr (peer, ':');
			if (p) *p = 0;
			for (i=0; i<count; i++) {
				host = r_str_word_get0 (allows, i);
				//eprintf ("--- (%s) (%s)\n", host, peer);
				if (!strcmp (host, peer)) {
					accepted = R_TRUE;
					break;
				}
			}
			free (peer);
			free (allows);
			if (!accepted) {
				r_socket_http_close (rs);
				continue;
			}
		}
		if (!rs->method || !rs->path) {
			eprintf ("Invalid http headers received from client\n");
			r_socket_http_close (rs);
			continue;
		}
		char *dir = NULL;

		if (r_config_get_i (core->config, "http.dirlist"))
			if (r_file_is_directory (rs->path))
				dir = strdup (rs->path);
		if (!strcmp (rs->method, "GET")) {
			if (!memcmp (rs->path, "/up", 3)) {
				if (r_config_get_i (core->config, "http.upget")) {
					const char *uproot = r_config_get (core->config, "http.uproot");
					if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) {
						char *ptr = rtr_dir_files (uproot);
						r_socket_http_response (rs, 200, ptr, 0, NULL);
						free (ptr);
					} else {
						char *path = r_file_root (uproot, rs->path + 4);
						if (r_file_exists (path)) {
							int sz = 0;
							char *f = r_file_slurp (path, &sz);
							if (f) {
								r_socket_http_response (rs, 200, f, sz, NULL);
								free (f);
							} else {
								r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
								eprintf ("http: Cannot open '%s'\n", path);
							}
						} else {
							if (dir) {
								char *resp = rtr_dir_files (dir);
								r_socket_http_response (rs, 404, resp, 0, NULL);
								free (resp);
							} else {
								eprintf ("File '%s' not found\n", path);
								r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
							}
						}
						free (path);
					}
				} else {
					r_socket_http_response (rs, 403,
							"Permission denied\n", 0, NULL);
				}
			} else if (!memcmp (rs->path, "/cmd/", 5)) {
				char *cmd = rs->path +5;
				char foo[32];
				const char *httpcmd = r_config_get (core->config, "http.uri");
				while (*cmd=='/') cmd++;
				if (httpcmd && *httpcmd) {
					int len;
					char *res;
					// do remote http query and proxy response
					snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd);
					res = r_socket_http_get (foo, NULL, &len);
					if (res) {
						res[len]=0;
						r_cons_printf ("%s\n", res);
					}
				} else {
					char *out, *cmd = rs->path+5;
					r_str_uri_decode (cmd);
					// eprintf ("CMD (%s)\n", cmd);
					out = r_core_cmd_str_pipe (core, cmd);
					// eprintf ("\nOUT LEN = %d\n", strlen (out));
					if (out) {
						char *res = r_str_uri_encode (out);
						r_socket_http_response (rs, 200, out, 0,
							"Content-Type: text/plain\n");
						free (out);
						free (res);
					} else r_socket_http_response (rs, 200, "", 0, NULL);
				}
			} else {
				const char *root = r_config_get (core->config, "http.root");
				char *path = r_file_root (root, rs->path);
				// FD IS OK HERE
				if (rs->path [strlen (rs->path)-1] == '/') {
					path = r_str_concat (path, "index.html");
					//rs->path = r_str_concat (rs->path, "index.html");
				} else {
					//snprintf (path, sizeof (path), "%s/%s", root, rs->path);
					if (r_file_is_directory (path)) {
						char res[128];
						snprintf (res, sizeof (res),
							"Location: %s/\n", rs->path);
						r_socket_http_response (rs, 302,
							NULL, 0, res);
						r_socket_http_close (rs);
						free (path);
						free (dir);
						dir = NULL;
						continue;
					}
				}
				if (r_file_exists (path)) {
					int sz = 0;
					char *f = r_file_slurp (path, &sz);
					if (f) {
						const char *contenttype = NULL;
						if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n";
						if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n";
						if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n";
						r_socket_http_response (rs, 200, f, sz, contenttype);
						free (f);
					} else {
						r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
						eprintf ("http: Cannot open '%s'\n", path);
					}
				} else {
					if (dir) {
						char *resp = rtr_dir_files (dir);
						eprintf ("Dirlisting %s\n", dir);
						r_socket_http_response (rs, 404, resp, 0, NULL);
						free (resp);
					} else {
						eprintf ("File '%s' not found\n", path);
						r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
					}
				}
				free (path);
			}
		} else 
		if (!strcmp (rs->method, "POST")) {
			ut8 *ret;
			int retlen;
			char buf[128];
			if (r_config_get_i (core->config, "http.upload")) {
				ret = r_socket_http_handle_upload (
					rs->data, rs->data_length, &retlen);
				if (ret) {
					ut64 size = r_config_get_i (core->config, "http.maxsize");
					if (size && retlen > size) {
						r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL);
					} else {
						char *filename = r_file_root (
							r_config_get (core->config, "http.uproot"),
							rs->path + 4);
						eprintf ("UPLOADED '%s'\n", filename);
						r_file_dump (filename, ret, retlen);
						free (filename);
						snprintf (buf, sizeof (buf),
							"<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen);
							r_socket_http_response (rs, 200, buf, 0, NULL);
					}
					free (ret);
				}
			} else {
				r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL);
			}
		} else {
			r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL);
		}
		r_socket_http_close (rs);
		free (dir);
	}
	core->http_up = R_FALSE;
	r_socket_free (s);
	r_cons_break_end ();
	r_config_set_i (core->config, "scr.html", x);
	r_config_set_i (core->config, "scr.color", y);
	r_config_set_i (core->config, "asm.bytes", z);
	r_config_set_i (core->config, "scr.interactive", u);
	r_config_set_i (core->config, "asm.cmtright", v);
	if (oldsandbox != -1)
		r_config_set_i (core->config, "cfg.sandbox", oldsandbox);
	return 0;
}
コード例 #16
0
ファイル: p_format.c プロジェクト: jody-frankowski/radare2
// 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;
}
コード例 #17
0
ファイル: p_format.c プロジェクト: KarjamP/radare2
/* TODO: needs refactoring */
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, int len, const char *fmt, int elem, const char *setval) {
	int nargs, i, j, nexti, idx, times, otimes, endian, isptr = 0;
	int (*realprintf)(const char *str, ...);
	int (*oldprintf)(const char *str, ...);
	const char *argend = fmt+strlen (fmt);
	ut64 addr = 0, addr64 = 0, seeki = 0;;
	char *args = NULL, *bracket, tmp, last = 0;
	const char *arg = fmt;
	int viewflags = 0;
	char namefmt[8];
	ut8 *buf, buffer[256];

	nexti = nargs = endian = i = j = 0;

	if (len<1) return 0;
	buf = malloc (len);
	if (!buf) return 0;
	memcpy (buf, b, len);
	endian = p->big_endian;

	oldprintf = NULL;
	realprintf = p->printf;

	while (*arg && iswhitechar (*arg)) arg++;
	/* get times */
	otimes = times = atoi (arg);
	if (times > 0)
		while ((*arg>='0'&&*arg<='9')) arg++;
	bracket = strchr (arg,'{');
	if (bracket) {
		char *end = strchr (arg,'}');
		if (end == NULL) {
			eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
			goto beach;
		}
		*end='\0';
		times = r_num_math (NULL, bracket+1);
		arg = end + 1;
	}

	if (*arg=='\0') {
		print_format_help (p);
		goto beach;
	}
	/* get args */
	args = strchr (arg, ' ');
	if (args) {
		int l=0, maxl = 0;
		argend = args;
		args = strdup (args+1);
		nargs = r_str_word_set0 (args+1);
		if (nargs == 0)
			R_FREE (args);
		for (i=0; i<nargs; i++) {
			int len = strlen (r_str_word_get0 (args+1, i));
			if (len>maxl) maxl = len;
		}
		l++;
		snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl);
	}

	/* go format */
	i = 0;
	if (!times) otimes = times = 1;
	for (; times; times--) { // repeat N times
		const char * orig = arg;
		if (otimes>1)
			p->printf ("0x%08"PFMT64x" [%d] {\n", seek+i, otimes-times);
		idx = 0;
		arg = orig;
		for (idx=0; i<len && arg<argend && *arg; idx++, arg++) {
			seeki = seek+i;
			addr = 0LL;
			if (endian)
				 addr = (*(buf+i))<<24   | (*(buf+i+1))<<16 | *(buf+i+2)<<8 | *(buf+i+3);
			else     addr = (*(buf+i+3))<<24 | (*(buf+i+2))<<16 | *(buf+i+1)<<8 | *(buf+i);
			if (endian)
				 addr64 = (ut64)(*(buf+i))<<56 | (ut64)(*(buf+i+1))<<48
					| (ut64)*(buf+i+2)<<40 | (ut64)(*(buf+i+3))<<32
				 	| (*(buf+i+4))<<24 | (*(buf+i+5))<<16 | *(buf+i+6)<<8 | *(buf+i+7);
			else addr64 = ((ut64)(*(buf+i+7)))<<56 | (ut64)(*(buf+i+6))<<48
					| (ut64)(*(buf+i+5))<<40 | (ut64)(*(buf+i+4))<<32
				 	| (*(buf+i+3))<<24 | (*(buf+i+2))<<16 | *(buf+i+1)<<8 | *(buf+i);
			tmp = *arg;
		feed_me_again:
			switch (isptr) {
			case 1:
				nexti = i + (p->bits/8);
				i = 0;
				tmp = *arg;
				memset (buf, '\0', len);
				p->printf ("(*0x%"PFMT64x") ", addr);
				if (p->iob.read_at) {
					p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4);
				} else {
					eprintf ("(cannot read memory)\n");
					break;
				}
				isptr = 2;
				break;
			case 2:
				// restore state after pointer seek
				i = nexti;
				seeki = seek+i;
				memcpy (buf, b, len);
				isptr = 0;
				arg--;
				idx--;
				continue;
			}
			if (tmp == 0 && last != '*')
				break;
			/* skip chars */
			switch (tmp) {
			case '*':
				isptr = 1;
				if (i<=0 || !arg[1]) break;
				arg++;
				tmp = *arg; //last;
			//	arg--;
			//	idx--;
				goto feed_me_again;
			case '+':
				idx--;
				viewflags = !viewflags;
				continue;
			case 'e': // tmp swap endian
				idx--;
				endian ^= 1;
				continue;
			case ':': // skip char
				i+=4;
				idx-=4;
				continue;
			case '.': // skip char
				i++;
				idx--;
				continue;
			case 'p':
				tmp = (p->bits==64)?'q': 'x';
				//tmp = (sizeof (void*)==8)? 'q': 'x';
				break;
			case '?': // help
				print_format_help (p);
				idx--;
				i = len; // exit
				continue;
			}
			if (otimes>1)
				p->printf ("   ");
#define MUSTSET (setval && elem == idx)
#define MUSTSEE (elem == -1 || elem == idx)
			if (MUSTSEE) {
				if (!(MUSTSET)) {
					if (oldprintf)
						p->printf = oldprintf;
					if (idx<nargs)
						p->printf (namefmt, r_str_word_get0 (args, idx));
				}
			} else {
				if (!oldprintf)
					oldprintf = p->printf;
				p->printf = nullprintf;
			}
			/* cmt chars */
			switch (tmp) {
	#if 0
			case 'n': // enable newline
				j ^= 1;
				continue;
	#endif
#if 0
			case 't':
				/* unix timestamp */
				D cons_printf("0x%08x = ", config.seek+i);
				{
				/* dirty hack */
				int oldfmt = last_print_format;
				ut64 old = config.seek;
				radare_seek(config.seek+i, SEEK_SET);
				radare_read(0);
				print_data(config.seek+i, "8", buf+i, 4, FMT_TIME_UNIX);
				last_print_format=oldfmt;
				radare_seek(old, SEEK_SET);
				}
				break;
#endif
			case 'e':
				if (MUSTSET) {
					realprintf ("?e pf e not yet supported\n");
				} else {
					double doub;
					memcpy (&doub, buf+i, sizeof (double));
					p->printf ("0x%08"PFMT64x" = (double) ", seeki);
					p->printf ("%e", doub);
					i += 8;
				}
				break;
			case 'q':
				if (MUSTSET) {
					realprintf ("wv8 %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					p->printf ("(qword) ");
					p->printf ("0x%08"PFMT64x" ", addr64);
				}
				i += 8;
				break;
			case 'b':
				if (MUSTSET) {
					realprintf ("w %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					p->printf ("%d ; 0x%02x ; '%c' ", 
						buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:0);
				}
				i++;
				break;
			case 'c':
				if (MUSTSET) {
					realprintf ("?e pf c not yet implemented\n");
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					p->printf ("%d ; %d ; '%c' ",
						buf[i], (char)buf[i],
						IS_PRINTABLE (buf[i])?buf[i]:0);
				}
				i++;
				break;
			case 'B':
				if (MUSTSET) {
					realprintf ("?e pf B not yet implemented\n");
				} else {
					memset (buffer, '\0', 255);
					if (!p->iob.read_at) {
						printf ("(cannot read memory)\n");
						break;
					} else p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248);
					p->printf ("0x%08"PFMT64x" = ", seeki);
					for (j=0; j<10; j++) p->printf ("%02x ", buf[j]);
					p->printf (" ... (");
					for (j=0; j<10; j++)
						if (IS_PRINTABLE (buf[j]))
							p->printf ("%c", buf[j]);
					p->printf (")");
				}
				i += 4;
				break;
			case 'f':
				if (MUSTSET) {
					realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = %f", seeki,
						(float)(addr));
				}
				i += 4;
				break;
			case 'i':
			case 'd': // TODO: support unsigned int?
				if (MUSTSET) {
					realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					p->printf ("%"PFMT64d" ", addr);
				}
				i += 4;
				break;
			case 'D':
				if (p->disasm && p->user)
					i += p->disasm (p->user, seeki);
				break;
			case 'x':
				if (MUSTSET) {
					realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					ut32 addr32 = (ut32)addr;
					p->printf ("0x%08"PFMT64x" = ", seeki);
					p->printf ("0x%08"PFMT64x" ", addr32);
				}
				//if (string_flag_offset(buf, (ut64)addr32, -1))
				//	p->printf("; %s", buf);
				i += 4;
				break;
			case 'w':
			case '1': // word (16 bits)
				if (MUSTSET) {
					realprintf ("wv2 %s @ 0x%08"PFMT64x"\n", setval, seeki);
				} else {
					p->printf ("0x%08x = ", seeki);
					if (endian)
						 addr = (*(buf+i))<<8 | (*(buf+i+1));
					else     addr = (*(buf+i+1))<<8 | (*(buf+i));
					p->printf ("0x%04x ", addr);
				}
				i+=2;
				break;
			case 'z': // zero terminated string
				if (MUSTSET) {
					realprintf ("?e pf z not yet supported\n");
				} else {
					p->printf ("0x%08"PFMT64x" = ", seeki);
					for (; buf[i]&&i<len; i++) {
						if (IS_PRINTABLE (buf[i]))
							p->printf ("%c", buf[i]);
						else p->printf (".");
					}
				}
				break;
			case 'Z': // zero terminated wide string
				p->printf ("0x%08"PFMT64x" = ", seeki);
				for (; buf[i] && i<len; i+=2) {
					if (IS_PRINTABLE (buf[i]))
						p->printf ("%c", buf[i]);
					else p->printf (".");
				}
				p->printf (" ");
				break;
			case 's':
				p->printf ("0x%08"PFMT64x" = ", seeki);
				memset (buffer, '\0', 255);
				if (p->iob.read_at) {
					p->iob.read_at (p->iob.io, (ut64)addr,
						buffer, sizeof (buffer)-8);
				} else {
					printf ("(cannot read memory)\n");
					break;
				}
				p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ",
					seeki, addr);
				p->printf ("%s ", buffer);
				i += 4;
				break;
			case 'S':
				p->printf ("0x%08"PFMT64x" = ", seeki);
				memset (buffer, '\0', 255);
				if (p->iob.read_at) {
					p->iob.read_at (p->iob.io, addr64,
						buffer, sizeof (buffer)-8);
				} else {
					printf ("(cannot read memory)\n");
					break;
				}
				p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ",
					seeki, addr);
				p->printf ("%s ", buffer);
				i += 8;
				break;
			default:
				/* ignore unknown chars */
				break;
			}
			if (viewflags && p->offname) {
				const char *s = p->offname (p->user, seeki);
				if (s) p->printf ("@(%s)", s);
				s = p->offname (p->user, addr);
				if (s) p->printf ("*(%s)", s);
			}
			if (tmp != 'D')
				p->printf ("\n");
			last = tmp;
		}
		if (otimes>1)
			p->printf ("}\n");
		arg = orig;
		idx = 0;
	}
	if (oldprintf)
		p->printf = oldprintf;
beach:
	free (buf);
	if (args) {
		free (args);
	}
	return i;
}
コード例 #18
0
ファイル: ctype.c プロジェクト: csarn/radare2
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;
}
コード例 #19
0
ファイル: str.c プロジェクト: djpohly/radare2
/* hack from print */
R_API int r_print_format_length (const char *fmt) {
	int nargs, i, j, idx, times, endian;
	char *args, *bracket, tmp, last = 0;
	const char *arg = fmt;
	const char *argend = arg+strlen (fmt);
	char namefmt[8];
	int viewflags = 0;
	nargs = endian = i = j = 0;

	while (*arg && iswhitechar (*arg)) arg++;
	/* get times */
	times = atoi (arg);
	if (times > 0)
		while ((*arg>='0'&&*arg<='9')) arg++;
	bracket = strchr (arg,'{');
	if (bracket) {
		char *end = strchr (arg,'}');
		if (end == NULL) {
			eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
			return 0;
		}
		*end='\0';
		times = r_num_math (NULL, bracket+1);
		arg = end + 1;
	}

	if (*arg=='\0')
		return 0;

	/* get args */
	args = strchr (arg, ' ');
	if (args) {
		int l=0, maxl = 0;
		argend = args;
		args = strdup (args+1);
		nargs = r_str_word_set0 (args+1);
		if (nargs == 0)
			R_FREE (args);
		for (i=0; i<nargs; i++) {
			int len = strlen (r_str_word_get0 (args+1, i));
			if (len>maxl) maxl = len;
		}
		l++;
		snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl);
	}

	/* go format */
	i = 0;
	if (!times) times = 1;
	for (; times; times--) { // repeat N times
		const char * orig = arg;
		idx = 0;
		arg = orig;
		for (idx=0; arg<argend && *arg; idx++, arg++) {
			tmp = *arg;
		feed_me_again:
			if (tmp == 0 && last != '*')
				break;
			/* skip chars */
			switch (tmp) {
			case '*':
				if (i<=0) break;
				tmp = last;
				arg--;
				idx--;
				goto feed_me_again;
			case '+':
				idx--;
				viewflags = !viewflags;
				continue;
			case 'e': // tmp swap endian
				idx--;
				endian ^= 1;
				continue;
			case '.': // skip char
				i++;
				idx--;
				continue;
			case 'p':
				tmp = (sizeof (void*)==8)? 'q': 'x';
				break;
			case '?': // help
				idx--;
				return 0;
			}
			switch (tmp) {
			case 'e': i += 8; break;
			case 'q': i += 8; break;
			case 'b': i++; break;
			case 'c': i++; break;
			case 'B': i += 4; break;
			case 'i': i += 4; break;
			case 'd': i += 4; break;
			case 'x': i += 4; break;
			case 'w':
			case '1': i+=2; break;
			case 'z': // XXX unsupported
			case 'Z': // zero terminated wide string
				break;
			case 's': i += 4; break; // S for 8?
			case 'S': i += 8; break; // S for 8?
			default:
				/* ignore unknown chars */
				break;
			}
			last = tmp;
		}
		arg = orig;
		idx = 0;
	}
//	free((void *)&args);
	return i;
}