Exemple #1
0
void search_similar_pattern(int count)
{
	u8 *block = malloc (config.block_size);
	/* backup basic block */
	radare_read(0);
	memcpy (block, config.block, config.block_size);
	radare_controlc ();
	radare_read (1); // read next block
	while (!config.interrupted && config.seek<config.size) {
		int diff = memcmpdiff(config.block, block, config.block_size);
		int equal = config.block_size-diff;
// equal sera un numero petit quan diff sigui gran
// quan equal sigui gran diff sera petit
		if (equal >= count) { //count > equal) {
		//if (count > equal) {
			cons_printf("0x%08llx %d/%d\n", config.seek, equal, config.block_size);
			cons_flush();
			radare_read(1);
		} else {
			config.seek += 1; // skip diff bytes can be faster ??
			//config.seek += diff; // skip diff bytes can be faster ??
			int ret = radare_read(0);
			if (ret<config.block_size)break;
		}
	}
	radare_controlc_end ();
	free (block);
}
Exemple #2
0
// TODO: handle Control-C
void radare_search_aes()
{
	ut64 oseek  = config.seek;
	ut64 limit  = config.size;
	size_t bsize = config.block_size;
	int found = 0;
	int i;

	config.block_size = 512;

	if (config.limit)
		limit = config.limit;

	radare_controlc();
	while(!config.interrupted && (( limit != -1 && config.seek < limit) || limit == -1)) {
		radare_read(0);
		for(i=0;i<256;i++) {
			if (aes_key_test(config.block+i)) {
				printf("%03d 0x%08x\n", found, (uint)config.seek+i);
				fflush(stdout);
				found++;
			}
		}

		radare_seek(config.seek + 256, SEEK_SET);
	}
	eprintf("%d AES keys found\n",found );
	radare_controlc_end();

	config.seek = oseek;
	config.block_size = bsize;
}
Exemple #3
0
int search_from_file(char *file)
{
	int i, ret;
	ut64 tmp = config.seek;
	tokenizer *t;

	if (strchr(file, '?')) {
		printf("Usage: /. file\n");
		printf("File format:\n");
		printf(" token: keywordname\n");
		printf(" string: keyword\n");
		printf(" mask: binarymask\n");
		return 0;
	}
	t = binparse_new_from_file(file);
	if (t == NULL)
		return 0;
	t->callback = &radare_tsearch_callback;
	nhit = 0;
#if __UNIX__
	D go_alarm(search_alarm);
#endif
	radare_controlc();
	// TODO: do it generic (as for init)
	radare_cmd("fs search", 0);
	for(radare_read(0);!config.interrupted&& config.seek < config.size;radare_read(1)) {
		for(i=0;i<config.block_size;i++) {
			ret = update_tlist(t, config.block[i], config.seek+i);
			if (ret == -1)
				break;
		}
	}

	radare_controlc_end();
#if __UNIX__
	D go_alarm(SIG_IGN);
#endif
	binparser_free(t);

	radare_seek(tmp, SEEK_SET);

	return 1;
}
Exemple #4
0
static int radare_tsearch_callback(struct _tokenizer *t, int i, ut64 where)
{
	char flag_name[128];
	ut64 off = config.seek;

	if (align != 0 && where%align != 0)
		return 1;

	if (search_count && nhit >= search_count)
		return 1;

	nhit++;
	radare_flag_name (flag_name, i, nhit);

	radare_seek(where, SEEK_SET);
	radare_read(0);
	if (search_flag)
		flag_set(flag_name, where, 0);

	if (search_cmdhit && search_cmdhit[0]!='\0') {
		char *cmdhit = strdup(search_cmdhit);
		radare_seek(where, SEEK_SET);
		setenv("KEYWORD", search_last_keyword, 1); // XXX this is not last-keyword!! must array this!
		radare_cmd(cmdhit, 0);
		free(cmdhit);
		radare_controlc();
	}

	if (search_verbose) {
		u8 *ptr = config.block; //+(where-config.seek)-3;
		cons_printf("%03d  0x%08llx  %s ", nhit, where, flag_name);
		for(i=0;i<20;i++) {
			if (is_printable(ptr[i]))
				cons_printf("%c", ptr[i]);
		}
		cons_printf("\n");
	} 
	//D { fprintf(stderr, "\r%d\n", nhit); fflush(stderr); }

	fflush(stdout);
	config.seek = off;

	return 0;
}
Exemple #5
0
int search_range(char *range)
{
	int len, i,j;
	char str[128];
	int num = -1, num2 = -1;
	tokenizer *t;
	ut64 tmp = config.seek;
	ut64 search_from;
	ut64 search_to;
	ut64 limit;
	int range_n = 0;
	int f0 = 0;
	ut64 s;

	if (range == NULL)
		return 0;
	free(search_last_keyword);
	search_last_keyword = strdup(range);

	// init stuff
	search_cmdhit = config_get("cmd.hit");
	search_count = (int)(size_t)config_get_i("cfg.count");
	search_flag = (int)(size_t)config_get("search.flag");
	search_from = config_get_i("search.from");
	search_to = config_get_i("search.to");
	search_verbose = (int)(size_t)config_get("search.verbose");

	if (config_get("search.inar")) {
		if (! ranges_get_n(range_n++, &search_from, &search_to)) {
			eprintf("No ranges defined\n");
			return 0;
		}
		printf("Searching using ranges...\n");
	}
	// twice
	hit_idx = 1; // reset hit index
	radare_cmd("f -hit0_*", 0);
	radare_cmd("f -hit0_*", 0);
	radare_cmd("fs search", 0);
	do {
		nhit = 0;
		t = binparse_new(0);
		align = config_get_i("search.align");
		t->callback = &radare_tsearch_callback;
		len = strlen(range);
		// foreach token in range
		for(j=i=0;i<len;i++,j++) {
			str[j] = range[i];
			str[j+1] = '\0';
			switch(range[i+1]) {
			case '-':
				num = atoi(str);
				i++; j=-1;
				f0=1;
				break;
			case '\0':
			case ',':
				if (str[0]=='\0') break;
				num2 = atoi(str);
				if (f0) {
					f0=0;
					if (num == -1) {
						printf("syntax error\n");
						break;
					}
					for(j = num;j<=num2;j++)
						binparse_add_search(t, j);
				} else	binparse_add_search(t, num2);
				j=-1;
				str[0]='\0';
				i++;
				break;
			}
		}
#if __UNIX__
		go_alarm(search_alarm);
#endif
		/* search loop */
		radare_controlc();
		config.seek = search_from;
		limit = config.limit;
		if (search_to!=0)
			limit = search_to;

		//D eprintf("Searching from 0x%08llx to 0x%08llx\n", search_from, (search_to==0)?-1:search_to);
		for(i=1, radare_read(0); !config.interrupted; i = radare_read(1)) {
			s = config.seek;
			if (i==0) {
				//eprintf("read err at 0x%08llx\n", config.seek);
				break;
			}
			if (limit && config.seek >= limit) break;
			if (config.debug && config.seek == 0xFFFFFFFF) break;
			for(i=0;!config.interrupted && i<config.block_size;i++) {
				if (update_tlist(t, config.block[i], config.seek+i)) {
					config.seek = s;
					radare_read(0);
				}
			}
			config.seek = s;
		}
	} while(config_get("search.inar") && ranges_get_n(range_n++, &search_from, &search_to));
	binparser_free(t);
#if __UNIX__
	go_alarm(SIG_IGN);
#endif
	if (config.interrupted) {
		printf("\nStopped at 0x"OFF_FMTx" (flag search_stop)\n", config.seek);
		flag_set("search_stop",config.seek, 0);
	}
	radare_controlc_end();

	radare_seek(tmp, SEEK_SET);
	if (!search_verbose)
		printf("\n");

	return 1;
}
Exemple #6
0
int search_from_simple_file(char *file)
{
	FILE *fd;
	char *ptr, buf[4096], cmd[4096];
	//int i,ret;
	ut64 tmp = config.seek;
	//tokenizer *t;

	if (strchr(file, '?')) {
		cons_printf("Usage: /: file [file2] [file3] ...\n"
			"File format:\n"
			" puts 89823993982839\n"
			" scanf 89844483241839\n");
		return 0;
	}

	fd = fopen(file, "r");
	if (fd == NULL) {
		eprintf("Cannot open file '%s'\n", file);
		return 0;
	}
	config_set("cfg.verbose", "false");
	while(!feof(fd) && !config.interrupted) {
		/* read line */
		buf[0]='\0';
		fgets(buf, 4095, fd);
		if (buf[0]=='\0') continue;
		buf[strlen(buf)-1]='\0';
		ptr = strchr(buf, ' ');
		if (ptr) {
			ptr[0]='\0';
			sprintf(cmd, "hit.%s_%%d%%d", buf);
			config_set("search.flagname", cmd);
			sprintf(cmd, ":/x %s", ptr+1);
			radare_cmd_raw(cmd, 0);
			//eprintf("(%s)(%s)\n", buf, ptr+1);
		}
	}
	config_set("cfg.verbose", "true");
	config_set("search.flagname", "hit%d_%d");
	fclose(fd);
#if 0
	t = binparse_new_from_simple_file(file);
	if (t == NULL)
		return 0;
	t->callback = &radare_tsearch_callback;
	nhit = 0;
	radare_controlc();
	// TODO: do it generic (as for init)
	radare_cmd("fs search", 0);
	for(radare_read(0);!config.interrupted&& config.seek < config.size;radare_read(1)) {
		for(i=0;i<config.block_size;i++) {
			ret = update_tlist(t, config.block[i], config.seek+i);
			if (ret == -1)
				break;
		}
	}

	radare_controlc_end();
	binparser_free(t);
#endif
	radare_seek(tmp, SEEK_SET);
	radare_read(0);

	return 1;
}
Exemple #7
0
/* 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;
}
Exemple #8
0
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;
}