Пример #1
0
R_API void r_cons_visual_flush() {
	if (I.noflush)
		return;
	r_cons_highlight (I.highlight);
	if (!I.null) {
/* TODO: this ifdef must go in the function body */
#if __WINDOWS__ && !__CYGWIN__
		r_cons_w32_print ((const ut8*)I.buffer, I.buffer_len, 1);
#else
		r_cons_visual_write (I.buffer);
#endif
	}
	r_cons_reset ();
	if (I.fps) {
		int w = r_cons_get_size (NULL);
		int fps = 0;
		static ut64 prev = 0LL; //r_sys_now ();
		fps = 0;
		if (prev) {
			ut64 now = r_sys_now ();
			ut64 diff = now-prev;
			fps = (diff<1000000)? (1000000/diff): 0;
			prev = now;
		} else prev = r_sys_now ();
		eprintf ("\x1b[0;%dH[%d FPS] \n", w-10, fps);
	}
}
Пример #2
0
static void cmd_fz(RCore *core, const char *input) {
	switch (*input) {
	case '?':
		r_core_cmd_help (core, help_msg_fz);
		break;
	case '.':
		{
			const char *a = NULL, *b = NULL;
			r_flag_zone_around (core->flags, core->offset, &a, &b);
			r_cons_printf ("%s %s\n", a?a:"~", b?b:"~");
		}
		break;
	case ':':
		{
			const char *a, *b;
			int a_len = 0;
			int w = r_cons_get_size (NULL);
			r_flag_zone_around (core->flags, core->offset, &a, &b);
			if (a) {
				r_cons_printf ("[<< %s]", a);
				a_len = strlen (a) + 4;
			}
			int padsize = (w / 2)  - a_len;
			int title_size = 12;
			if (a || b) {
				char *title = r_str_newf ("[ 0x%08"PFMT64x" ]", core->offset);
				title_size = strlen (title);
				padsize -= strlen (title) / 2;
				const char *halfpad = r_str_pad (' ', padsize);
				r_cons_printf ("%s%s", halfpad, title);
				free (title);
			}
			if (b) {
				padsize = (w / 2) - title_size - strlen (b) - 4;
				const char *halfpad = padsize > 1? r_str_pad (' ', padsize): "";
				r_cons_printf ("%s[%s >>]", halfpad, b);
			}
			if (a || b) {
				r_cons_newline();
			}
		}
		break;
	case ' ':
		r_flag_zone_add (core->flags, r_str_trim_ro (input + 1), core->offset);
		break;
	case '-':
		if (input[1] == '*') {
			r_flag_zone_reset (core->flags);
		} else {
			r_flag_zone_del (core->flags, input + 1);
		}
		break;
	case '*':
		r_flag_zone_list (core->flags, '*');
		break;
	case 0:
		r_flag_zone_list (core->flags, 0);
		break;
	}
}
Пример #3
0
R_API void r_cons_less_str(const char *str) {
	int lines_count;
	int w, h, ch, to, ui = 1, from = 0;
	char *p = strdup (str);
	int *lines = splitlines (p, &lines_count);
	r_cons_set_raw (R_TRUE);
	r_cons_show_cursor (R_FALSE);
	r_cons_reset ();
	h = 0;
	while (ui) {
		w = r_cons_get_size (&h);
		to = R_MIN (lines_count, from+h);
		if (from+3>lines_count)
			from = lines_count-3;
		printpage (p, lines, from, to);
		ch = r_cons_readchar ();
		ch = r_cons_arrow_to_hjkl (ch);
		switch (ch) {
		case ' ': from += h; break;
		case 'g': from = 0; break;
		case 'G': from = lines_count-1-h; break;
		case 'q': ui = 0; break;
		case '\r':
		case '\n':
		case 'j': from++; break;
		case 'J': from+=h; break;
		case 'k': if (from>0) from--; break;
		case 'K': from = (from>=h)? from-h: 0;
			break;
		}
	}
	free (lines);
	r_cons_set_raw (R_FALSE);
	r_cons_show_cursor (R_TRUE);
}
Пример #4
0
R_API RCons *r_cons_new () {
	I.refcnt++;
	if (I.refcnt != 1)
		return &I;
	I.line = r_line_new ();
	I.highlight = NULL;
	I.event_interrupt = NULL;
	I.is_wine = -1;
	I.fps = 0;
	I.blankline = R_TRUE;
	I.teefile = NULL;
	I.fix_columns = 0;
	I.fix_rows = 0;
	I.mouse_event = 0;
	I.force_rows = 0;
	I.force_columns = 0;
	I.event_resize = NULL;
	I.data = NULL;
	I.event_data = NULL;
	I.is_interactive = R_TRUE;
	I.noflush = R_FALSE;
	I.fdin = stdin;
	I.fdout = 1;
	I.breaked = R_FALSE;
	//I.lines = 0;
	I.buffer = NULL;
	I.buffer_sz = 0;
	I.buffer_len = 0;
	r_cons_get_size (NULL);
	I.num = NULL;
	I.null = 0;
#if EMSCRIPTEN
	/* do nothing here :? */
#elif __UNIX__ || __CYGWIN__
	tcgetattr (0, &I.term_buf);
	memcpy (&I.term_raw, &I.term_buf, sizeof (I.term_raw));
	I.term_raw.c_iflag &= ~(BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
	I.term_raw.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
	I.term_raw.c_cflag &= ~(CSIZE|PARENB);
	I.term_raw.c_cflag |= CS8;
	I.term_raw.c_cc[VMIN] = 1; // Solaris stuff hehe
	signal (SIGWINCH, resize);
#elif __WINDOWS__
	h = GetStdHandle (STD_INPUT_HANDLE);
	GetConsoleMode (h, (PDWORD) &I.term_buf);
	I.term_raw = 0;
	if (!SetConsoleCtrlHandler ((PHANDLER_ROUTINE)__w32_control, TRUE))
		eprintf ("r_cons: Cannot set control console handler\n");
#endif
	I.pager = NULL; /* no pager by default */
	I.truecolor = 0;
	I.mouse = 0;
	I.newline = R_TRUE;
	r_cons_pal_null ();
	r_cons_pal_init (NULL);
	r_cons_rgb_init ();
	r_cons_reset ();
	return &I;
}
Пример #5
0
static void flagbars(RCore *core, const char *glob) {
	int cols = r_cons_get_size (NULL);
	cols -= 80;
	if (cols < 0) {
		cols += 80;
	}

	struct flagbar_t u = { .core = core, .cols = cols };
	r_flag_foreach_glob (core->flags, glob, flagbar_foreach, &u);
}
Пример #6
0
// TODO: Add fmt support
R_API char *r_cons_message(const char *msg) {
	int cols, rows;
	int len = strlen (msg);
	cols = r_cons_get_size (&rows);

	r_cons_clear ();
	r_cons_gotoxy ((cols-len)/2, rows/2); // XXX
	/// TODO: add square, or talking clip here
	r_cons_printf ("%s\n", msg);
	r_cons_flush ();
	r_cons_gotoxy (0, rows-2); // XXX
	r_cons_any_key ();
	return NULL;
}
Пример #7
0
static void Layout_run(Panel *panels) {
	int h, w = r_cons_get_size (&h);
	int i, j;
	int colpos = w-COLW;

	can->sx = 0;
	can->sy = 0;

	n_panels = 0;
	for (i=0; panels[i].text; i++) {
		if (panels[i].type == PANEL_TYPE_FRAME)
			n_panels++;
	}
	for (i=j=0; panels[i].text; i++) {
		switch (panels[i].type) {
		case PANEL_TYPE_FLOAT:
			panels[i].w = r_str_bounds (
				panels[i].text,
				&panels[i].h);
			panels[i].h += 4;
			break;
		case PANEL_TYPE_FRAME:
			if (j == 0) {
				panels[i].x = 0;
				panels[i].y = 1;
				if (panels[j+1].text) {
					panels[i].w = colpos;
				} else {
					panels[i].w = w;
				}
				panels[i].h = h-1;
			} else {
				int ph = ((h-1)/(n_panels-1));
				panels[i].x = colpos;
				panels[i].y = 1 + (ph*(j-1));
				panels[i].w = w-colpos;
				if (panels[i].w<0)
					panels[i].w = 0;
				panels[i].h = ph;
				if (!panels[i+1].text) {
					panels[i].h = h - panels[i].y;
				}
			}
			j++;
		}
	}
}
Пример #8
0
R_API void r_core_visual_prompt_input (RCore *core) {
	int ret;
	ut64 addr = core->offset;
	ut64 bsze = core->blocksize;
	int h;
	(void)r_cons_get_size (&h);
	r_cons_gotoxy (0, h-2);
	r_cons_reset_colors();
	r_cons_printf("\nPress <enter> to return to Visual mode.\n");

	r_cons_show_cursor (true);
	core->vmode = false;
	ut64 newaddr = addr;
	if (curset) {
		if (ocursor != -1) {
			newaddr = core->offset + ocursor;
			r_core_block_size (core, cursor-ocursor);
		} else newaddr = core->offset + cursor;
		r_core_seek (core, newaddr, 1);
	}
	do {
		ret = r_core_visual_prompt (core);
		if (core->offset != newaddr) {
			// do not restore seek anymore
			newaddr = addr;
		}
	} while (ret);
	if (curset) {
		if (addr != newaddr) {
			r_core_seek (core, addr, 1);
			r_core_block_size (core, bsze);
		}
	}
	r_cons_show_cursor (false);
	core->vmode = true;
}
Пример #9
0
// damn singletons.. there should be only one screen and therefor
// only one visual instance of the graph view. refactoring this
// into a struct makes the code to reference pointers unnecesarily
// we can look for a non-global solution here in the future if
// necessary
static void r_core_panels_refresh (RCore *core) {
	char title[128];
	int i, j, h, w = r_cons_get_size (&h);
	if (instep && core->io->debug) {
		r_core_cmd0 (core, "sr pc");
	}
	r_cons_clear00 ();
	if (!can) {
		return;
	}
	r_cons_canvas_resize (can, w, h);
	r_cons_canvas_clear (can);
	if (panels) {
		if (menu_y>0) {
			panels[menu_pos].x = menu_x * 6;
		} else {
			panels[menu_pos].x = w;
		}
		panels[menu_pos].y = 1;
		free (panels[menu_pos].text);
		panels[menu_pos].text = malloc(1024); //r_str_newf ("%d", menu_y);
		panels[menu_pos].text[0] = 0;
		int maxsub = 0;
		for (i=0; menus_sub[i]; i++) { maxsub = i; }
		if (menu_x >= 0 && menu_x <maxsub && menus_sub[menu_x]) {
			for (j = 0; menus_sub[menu_x][j]; j++) {
				if (menu_y-1 == j) {
					strcat (panels[menu_pos].text, "> ");
				} else {
					strcat (panels[menu_pos].text, "  ");
				}
				strcat (panels[menu_pos].text,
					menus_sub[menu_x][j]);
				strcat (panels[menu_pos].text, "        \n");
			}
		}
		for (i=0; panels[i].text; i++) {
		  if (i != curnode) {
		    Panel_print (can, &panels[i], i==curnode);
		  }
		}
	}

	if (menu_y) {
		curnode = menu_pos;
	}
	// redraw current node to make it appear on top
	if (curnode >= 0) {
		Panel_print (can, &panels[curnode], 1);
	}
	Panel_print (can, &panels[menu_pos], menu_y);

	(void)G (-can->sx, -can->sy);
	char str[128];
	title[0] = 0;
	for (i=0; menus[i]; i++) {
		if (menu_x == i) {
			snprintf (str, sizeof (title)-1, "[%s]", menus[i]);
		} else {
			snprintf (str, sizeof (title)-1, " %s ", menus[i]);
		}
		strcat (title, str);
	}
	W (title);

	snprintf (title, sizeof (title)-1,
		"[0x%08"PFMT64x"]", core->offset);
	(void)G (-can->sx + w-strlen (title), -can->sy);
	W (title);

	r_cons_canvas_print (can);
	r_cons_flush_nonewline ();
}
Пример #10
0
R_API int r_core_visual_panels(RCore *core) {
#define OS_INIT() ostack.size = 0; ostack.panels[0] = 0;
#define OS_PUSH(x) if (ostack.size<LIMIT) {ostack.panels[++ostack.size]=x;}
#define OS_POP() ((ostack.size>0)? ostack.panels[--ostack.size]:0)
	int okey, key, wheel;
	int w, h;
	int asm_comments = 0;
	int asm_bytes = 0;
	n_panels = 0;
	panels = NULL;
	callgraph = 0;
	_core = core;

	OS_INIT();
	w = r_cons_get_size (&h);
	can = r_cons_canvas_new (w, h);
	can->linemode = 1;
	can->color = r_config_get_i (core->config, "scr.color");
	// disable colors in disasm because canvas doesnt supports ansi text yet
	r_config_set_i (core->config, "scr.color", 0);
	//can->color = 0; 
	if (!can) {
		eprintf ("Cannot create RCons.canvas context\n");
		return R_FALSE;
	}
	n_panels = bbPanels (core, &panels);
	if (!panels) {
		r_config_set_i (core->config, "scr.color", can->color);
		free (can);
		return R_FALSE;
	}

	reloadPanels (core);

	asm_comments = r_config_get_i (core->config, "asm.comments");
	r_config_set_i (core->config, "asm.comments", 0);
	asm_bytes = r_config_get_i (core->config, "asm.bytes");
	r_config_set_i (core->config, "asm.bytes", 0);

repeat:
	core->cons->event_data = core;
	core->cons->event_resize = \
		(RConsEvent)r_core_panels_refresh;
	w = r_cons_get_size (&h);
	Layout_run (panels);
	r_core_panels_refresh (core);
	wheel = r_config_get_i (core->config, "scr.wheel");
	if (wheel)
		r_cons_enable_mouse (R_TRUE);

	// r_core_graph_inputhandle()
	okey = r_cons_readchar ();
	key = r_cons_arrow_to_hjkl (okey);

	switch (key) {
	case ' ':
	case '\n':
		if (menu_y) {
			const char *action = menus_sub[menu_x][menu_y-1];
			eprintf ("ACTION %s\n", action);
			if (strstr (action, "New")) {
				int i;
				// add new panel for testing
				for (i=0; panels[i].text; i++) {
					// find last panel
				}
				panels[i].text = strdup ("Test");
				panels[i].cmd = r_str_newf ("pxW $r-2");
				panels[i].addr = core->offset;
				panels[i].type = PANEL_TYPE_FRAME;
				i++;
				n_panels++;
				panels[i].text = NULL;
			}
			if (strstr (action, "Quit")) {
				goto beach;
			}
		}
		break;
	case '?':
		r_cons_clear00 ();
		r_cons_printf ("Visual Ascii Art Panels:\n"
		" !    run r2048 game\n"
		" .    - center graph to the current node\n"
		" :    - run r2 command in prompt\n"
		" hl   - toggle scr.color\n"
		" HL   - move vertical column split\n"
		" JK   - select prev/next panels\n"
		" jk   - scroll/select menu\n"
		" q    - quit, back to visual mode\n"
		);
		r_cons_flush ();
		r_cons_any_key (NULL);
		break;
	case ':':
		core->vmode = R_FALSE;
		r_core_visual_prompt_input (core);
		core->vmode = R_TRUE;
		break;
	case 'C':
		can->color = !!!can->color;				//WTF
		//r_config_swap (core->config, "scr.color");
		// refresh graph
	//	reloadPanels (core);
		break;
	case '!':
		r_cons_2048 ();
		break;
	case 'j':
		if (panels[curnode].type == PANEL_TYPE_FLOAT) {
			if (menus_sub[menu_x][menu_y])
				menu_y ++;
		}
		break;
	case 'k':
		if (panels[curnode].type == PANEL_TYPE_FLOAT) {
			menu_y --;
			if (menu_y<0)
				menu_y = 0;
		}
		break;
	case 'J':
		curnode++;
		if (!panels[curnode].text) {
			curnode--;
		}
		break;
	case 'K':
		curnode--;
		if (curnode<0)
			curnode = 0;
		break;
	case 'H':
		COLW += 4;
		break;
	case 'L':
		COLW -= 4;
		if (COLW<0)
			COLW=0;
		break;
	case 'h':
		if (menu_x) {
			menu_x --;
			menu_y = menu_y?1:0;
		}
		break;
	case 'l':
		if (menus[menu_x + 1]) {
			menu_x ++;
			menu_y = menu_y?1:0;
		}
		break;
	case 'q':
	case -1: // EOF
		goto beach;
	case 27: // ESC
		if (r_cons_readchar () == 91) {
			if (r_cons_readchar () == 90) {
			}
		}
		break;
	default:
		//eprintf ("Key %d\n", key);
		//sleep (1);
		break;
	}
	goto repeat;
beach:
	free (panels);
	r_config_set_i (core->config, "scr.color", can->color);
	free (can);
	r_config_set_i (core->config, "asm.comments", asm_comments);
	r_config_set_i (core->config, "asm.bytes", asm_bytes);
	return R_TRUE;
}
Пример #11
0
R_API int r_cons_less_str(const char *str, const char *exitkeys) {
	static int in_help = false;
	static const char *r_cons_less_help = \
		" u/space  - page up/down\n"
		" jk       - line down/up\n"
		" gG       - begin/end buffer\n"
		" /        - search in buffer\n"
		" _        - enter the hud mode\n"
		" n/p      - next/prev search result\n"
		" q        - quit\n"
		" ?        - show this help\n"
		"\n";
	int lines_count = 0;
	RRegex *rx = NULL;
	int w, h, ch, to, ui = 1, from = 0, i;
	const char *sreg;
	RList **mla;

	if (!str || !*str) {
		return 0;
	}
	// rcons kills str after flushing the buffer, so we must keep a copy
	char *ostr = strdup (str);
	if (!ostr) {
		return 0;
	}
	char *p = strdup (str);
	if (!p) {
		free (ostr);
		return 0;
	}
	int *lines = pager_splitlines (p, &lines_count);
	if (lines_count < 1) {
		mla = NULL;
	} else {
		mla = calloc (lines_count, sizeof (RList *));
		if (!mla) {
			free (p);
			free (ostr);
			free (lines);
			return 0;
		}
	}
	for (i = 0; i < lines_count; i++) {
		mla[i] = r_list_new ();
	}
	r_cons_set_raw (true);
	r_cons_show_cursor (false);
	r_cons_reset ();
	h = 0;
	while (ui) {
		w = r_cons_get_size (&h);
		to = R_MIN (lines_count, from + h);
		if (from + 3 > lines_count) {
			from = lines_count - 3;
		}
		if (from < 0) {
			from = 0;
		}
		pager_printpage (p, lines, mla, from, to, w);
		ch = r_cons_readchar ();
		if (exitkeys && strchr (exitkeys, ch)) {
			for (i = 0; i < lines_count; i++) {
				r_list_free (mla[i]);
			}
			free (p);
			free (mla);
			free (ostr);
			free (lines);
			return ch;
		}
		ch = r_cons_arrow_to_hjkl (ch);
		switch (ch) {
		case '_':
			r_cons_hud_string (ostr);
			break;
		case '?':
			if (!in_help) {
				in_help = true;
				r_cons_less_str (r_cons_less_help, NULL);
				in_help = false;
			}
			break;
		case 'u':
			from -= h;
			if (from < 0) {
				from = 0;
			}
			break;
		case ' ': from += h; break;
		case 'g': from = 0; break;
		case 'G': from = lines_count-h; break;
		case -1: // EOF
		case '\x03': // ^C
		case 'q': ui = 0; break;
		case '\r':
		case '\n':
		case 'j': from++; break;
		case 'J': from+=h; break;
		case 'k':
			if (from > 0) {
				from--;
			}
			break;
		case 'K': from = (from>=h)? from-h: 0;
			break;
		case '/': 	/* search */
			r_cons_reset_colors ();
			r_line_set_prompt ("/");
			sreg = r_line_readline ();
			from = R_MIN (lines_count - 1, from);
			/* repeat last search if empty string is provided */
			if (sreg[0]) { /* prepare for a new search */
				if (rx) {
					r_regex_free (rx);
				}
				rx = r_regex_new (sreg, "");
			} else { /* we got an empty string */
				from = pager_next_match (from, mla, lines_count);
				break;
			}
			if (!rx) {
				break;
			}
			/* find all occurences */
			if (pager_all_matches (p, rx, mla, lines, lines_count)) {
				from = pager_next_match (from, mla, lines_count);
			}
			break;
		case 'n': 	/* next match */
			/* search already performed */
			if (rx) {
				from = pager_next_match (from, mla, lines_count);
			}
			break;
		case 'N':
		case 'p': 	/* previous match */
			if (rx) {
				from = pager_prev_match (from, mla);
			}
			break;
		}
	}
	for (i = 0; i < lines_count; i++) {
		r_list_free (mla[i]);
	}
	free (mla);
	r_regex_free (rx);
	free (lines);
	free (p);
	r_cons_reset_colors ();
	r_cons_set_raw (false);
	r_cons_show_cursor (true);
	free (ostr);
	return 0;
}
Пример #12
0
R_API void r_cons_less_str(const char *str) {
	int lines_count;
	RRegex *rx = NULL;
	int w, h, ch, to, ui = 1, from = 0, i;
	const char *sreg;

	if(str == NULL || str[0] == '\0') return;
	char *p = strdup (str);
	int *lines = splitlines (p, &lines_count);

	RRegexMatch **ms = malloc(lines_count * sizeof(void *));
	for(i = 0; i < lines_count; i++)
		ms[i] = calloc(NMATCHES, sizeof(RRegexMatch));

	r_cons_set_raw (R_TRUE);
	r_cons_show_cursor (R_FALSE);
	r_cons_reset ();
	w = h = 0;
	while (ui) {
		w = r_cons_get_size (&h);
		to = R_MIN (lines_count, from+h);
		if (from+3>lines_count)
			from = lines_count-3;
		if (from<0) from = 0;
		printpage (p, lines, ms, from, to, w);
		ch = r_cons_readchar ();
		ch = r_cons_arrow_to_hjkl (ch);
		switch (ch) {
		case ' ': from += h; break;
		case 'g': from = 0; break;
		case 'G': from = lines_count-1-h; break;
		case -1: // EOF
		case 'q': ui = 0; break;
		case '\r':
		case '\n':
		case 'j': from++; break;
		case 'J': from+=h; break;
		case 'k': if (from>0) from--; break;
		case 'K': from = (from>=h)? from-h: 0;
			break;
		case '/': 	/* search */
			r_cons_reset_colors();
			r_line_set_prompt("/");
			sreg = r_line_readline();
			from = R_MIN(lines_count - 1, from);
			/* repeat last search if empty string is provided */
			if(sreg[0]){ /* prepare for a new search */
				if(rx) r_regex_free(rx);
				rx = r_regex_new(sreg, "");
			} else { /* we got an empty string */
				from = next_match(from, ms, lines_count);
				break;
			}
			if(!rx) break;
			/* find all occurences */
			if(all_matches(p, rx, ms, lines, lines_count))
				from = next_match(from, ms, lines_count);
			break;
		case 'n': 	/* next match */
			/* search already performed */
			if(rx) from = next_match(from, ms, lines_count);
			break;
		case 'p': 	/* previous match */
			if(rx) from = prev_match(from, ms);
			break;
		}
	}
	for(i = 0; i < lines_count; i++) free(ms[i]);
	free(ms);
	if(rx) r_regex_free(rx);
	free (lines);
	free (p);
	r_cons_reset_colors();
	r_cons_set_raw (R_FALSE);
	r_cons_show_cursor (R_TRUE);
}
Пример #13
0
static void print_debug_maps_ascii_art(RDebug *dbg, RList *maps, ut64 addr, int colors) {
	ut64 mul; // The amount of address space a single console column will represent in bar graph
	ut64 min = -1, max = 0;
	int width = r_cons_get_size (NULL) - 90;
	RListIter *iter;
	RDebugMap *map;
	if (width < 1) {
		width = 30;
	}
	r_list_sort (maps, cmp);
	mul = findMinMax (maps, &min, &max, 0, width);
	ut64 last = min;
	if (min != -1 && mul != 0) {
		const char *color_prefix = ""; // Color escape code prefixed to string (address coloring)
		const char *color_suffix = ""; // Color escape code appended to end of string
		const char *fmtstr;
		char size_buf[56]; // Holds the human formatted size string [124K]
		int skip = 0; // Number of maps to skip when re-calculating the minmax
		r_list_foreach (maps, iter, map) {
			r_num_units (size_buf, map->size); // Convert map size to human readable string
			if (colors) {
				color_suffix = Color_RESET;
				if (map->perm & 2) { // Writable maps are red
					color_prefix = Color_RED;
				} else if (map->perm & 1) { // Executable maps are green
					color_prefix = Color_GREEN;
				} else {
					color_prefix = "";
					color_suffix = "";
				}
			} else {
				color_prefix = "";
				color_suffix = "";
			}
			if ((map->addr - last) > UT32_MAX) { // TODO: Comment what this is for
				mul = findMinMax (maps, &min, &max, skip, width); //  Recalculate minmax
			}
			skip++;
			fmtstr = dbg->bits & R_SYS_BITS_64 ? // Prefix formatting string (before bar)
				"map %4.8s %c %s0x%016"PFMT64x"%s |" :
				"map %4.8s %c %s0x%08"PFMT64x"%s |";
			dbg->cb_printf (fmtstr, size_buf,
				(addr >= map->addr && \
				addr < map->addr_end) ? '*' : '-',
				color_prefix, map->addr, color_suffix); // * indicates map is within our current seeked offset
			int col;
			for (col = 0; col < width; col++) { // Iterate over the available width/columns for bar graph
				ut64 pos = min + (col * mul); // Current address space to check
				ut64 npos = min + ((col + 1) * mul); // Next address space to check
				if (map->addr < npos && map->addr_end > pos) {
					dbg->cb_printf ("#"); // TODO: Comment what a # represents
				} else {
					dbg->cb_printf ("-");
				}
			}
			fmtstr = dbg->bits & R_SYS_BITS_64 ? // Suffix formatting string (after bar)
				"| %s0x%016"PFMT64x"%s %s %s\n" :
				"| %s0x%08"PFMT64x"%s %s %s\n";
			dbg->cb_printf (fmtstr, color_prefix, map->addr_end, color_suffix,
				r_str_rwx_i (map->perm), map->name);
			last = map->addr;
		}
	}
Пример #14
0
// Display a list of entries in the hud, filtered and emphasized based
// on the user input.
R_API char *r_cons_hud(RList *list, const char *prompt) {
	const int buf_size = 128;
	int ch, nch, first_line, current_entry_n, j, i = 0;
	char *p, *x, user_input[buf_size], mask[buf_size];
	int last_color_change, top_entry_n = 0;
	char *selected_entry = NULL;
	char tmp, last_mask = 0;
	void *current_entry;
	RListIter *iter;

	user_input[0] = 0;
	r_cons_clear ();
	// Repeat until the user exits the hud
	for (;;) {
		first_line = 1;
		r_cons_gotoxy (0, 0);
		current_entry_n = 0;
		if (top_entry_n < 0) {
			top_entry_n = 0;
		}
		selected_entry = NULL;
		if (prompt && *prompt) {
			r_cons_print (">> ");
			r_cons_println (prompt);
		}
		r_cons_printf ("%d> %s|\n", top_entry_n, user_input);
		int counter = 0;
		int rows;
		(void)r_cons_get_size (&rows);
		// Iterate over each entry in the list
		r_list_foreach (list, iter, current_entry) {
			memset (mask, 0, buf_size);
			if (!user_input[0] || strmatch (current_entry, user_input, mask, buf_size)) {
				counter++;
				if (counter == rows + top_entry_n) {
					break;
				}
				// if the user scrolled down the list, do not print the first entries
				if (!top_entry_n || current_entry_n >= top_entry_n) {
					// remove everything after a tab (in ??, it contains the commands)
					x = strchr (current_entry, '\t');
					if (x) {
						*x = 0;
					}
					p = strdup (current_entry);
					// if the filter is empty, print the entry and move on
					if (!user_input[0]) {
						r_cons_printf (" %c %s\n", first_line? '-': ' ', current_entry);
					} else {
						// otherwise we need to emphasize the matching part
						if (I(use_color)) {
							last_color_change = 0;
							last_mask = 0;
							r_cons_printf (" %c ", first_line? '-': ' ');
							// Instead of printing one char at the time
							// (which would be slow), we group substrings of the same color
							for (j = 0; p[j] && j < buf_size; j++) {
								if (mask[j] != last_mask) {
									tmp = p[j];
									p[j] = 0;
									if (mask[j]) {
										r_cons_printf (Color_RESET"%s", p + last_color_change);
									} else {
										r_cons_printf (Color_GREEN"%s", p + last_color_change);
									}
									p[j] = tmp;
									last_color_change = j;
									last_mask = mask[j];
								} 
							}
							if (last_mask) {
								r_cons_printf (Color_GREEN"%s\n"Color_RESET, p + last_color_change);
							} else {
								r_cons_printf (Color_RESET"%s\n", p + last_color_change);
							}
						} else {
							// Otherwise we print the matching characters uppercase
							for (j = 0; p[j]; j++) {
								if (mask[j])
									p[j] = toupper ((unsigned char)p[j]);
							}
							r_cons_printf (" %c %s\n", first_line? '-': ' ', p);
						}
					}
					// Clean up and restore the tab character (if any)
					free (p);
					if (x) {
						*x = '\t';
					}
					if (first_line) {
						selected_entry = current_entry;
					}	
					first_line = 0;
				}
				current_entry_n++;
			}
		}

		r_cons_visual_flush ();
		ch = r_cons_readchar ();
		nch = r_cons_arrow_to_hjkl (ch);
		(void)r_cons_get_size (&rows);
		if (nch == 'J' && ch != 'J') {
			top_entry_n += (rows - 1);
			if (top_entry_n + 1 >= current_entry_n) {
				top_entry_n = current_entry_n;
			}
		} else if (nch == 'K' && ch != 'K') {
			top_entry_n -= (rows - 1);
			if (top_entry_n < 0) {
				top_entry_n = 0;
			}
		} else if (nch == 'j' && ch != 'j') {
			if (top_entry_n + 1 < current_entry_n) {
				top_entry_n++;
			}
		} else if (nch == 'k' && ch != 'k') {
			if (top_entry_n >= 0) {
				top_entry_n--;
			}
		} else {
			switch (ch) {
			case 9: // \t
				if (top_entry_n + 1 < current_entry_n) {
					top_entry_n++;
				} else {
					top_entry_n = 0;
				}
				break;
			case 10: // \n
			case 13: // \r
				top_entry_n = 0;
				//		if (!*buf)
				//			return NULL;
				if (current_entry_n >= 1) {
					//eprintf ("%s\n", buf);
					//i = buf[0] = 0;
					return strdup (selected_entry);
				} // no match!
				break;
			case 23: // ^w
				top_entry_n = 0;
				i = user_input[0] = 0;
				break;
			case 0x1b: // ESC
				return NULL;
			case 8:   // bs
			case 127: // bs
				top_entry_n = 0;
				if (i < 1) return NULL;
				user_input[--i] = 0;
				break;
			default:
				if (IS_PRINTABLE (ch)) {
					if (i >= buf_size) {
						break;
					}
					top_entry_n = 0;
					if (i + 1 >= buf_size) {
						// too many
						break;
					}
					user_input[i++] = ch;
					user_input[i] = 0;
				}
				break;
			}
		}
	}
Пример #15
0
R_API int r_cons_w32_print(const ut8 *ptr, int len, int vmode) {
	HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
	int esc = 0;
	int bg = 0, fg = 1|2|4|8;
	const ut8 *ptr_end, *str = ptr;
	int ret = 0;
	int inv = 0;
	int linelen = 0;
	int ll = 0;
	int lines, cols = r_cons_get_size (&lines);
	if (I->is_wine==-1) {
		I->is_wine = r_file_is_directory ("/proc")? 1: 0;
	}
	if (len < 0) {
		len = strlen ((const char *)ptr);
	}
	ptr_end = ptr + len;
	if (ptr && hConsole)
	for (; *ptr && ptr < ptr_end; ptr++) {
		if (ptr[0] == 0xa) {
			ll = (size_t)(ptr - str);
			lines--;
			if (vmode && lines < 0) {
				break;
			}
			if (ll < 1) {
				continue;
			}
			if (vmode) {
				// TODO: Fix utf8 chop
				/* only chop columns if necessary */
				if (ll + linelen >= cols) {
					// chop line if too long
					ll = (cols - linelen) - 1;
					if (ll < 0) {
						continue;
					}
				}
			}
			if (ll > 0) {
				write (1, str, ll);
				linelen += ll;
			}
			esc = 0;
			str = ptr + 1;
			if (vmode) {
				int wlen = cols - linelen;
				char white[1024];
				if (wlen > 0 && wlen < sizeof (white)) {
					memset (white, ' ', sizeof (white));
					write (1, white, wlen-1);
				}
			}
			write (1, "\n\r", 2);
			// reset colors for next line
			SetConsoleTextAttribute (hConsole, 1 | 2 | 4 | 8);
			linelen = 0;
			continue;
		}
		if (ptr[0] == 0x1b) {
			ll = (size_t)(ptr-str);
			if (str[0] == '\n') {
				str++;
				ll--;
				if (vmode) {
					int wlen = cols - linelen - 1;
					char white[1024];
					//wlen = 5;
					if (wlen > 0) {
						memset (white, ' ', sizeof (white));
						write (1, white, wlen);
					}
				}
				write (1, "\n\r", 2);
				//write (1, "\r\n", 2);
				//lines--;
				linelen = 0;
			}
			if (vmode) {
				if (linelen + ll >= cols) {
					// chop line if too long
					ll = (cols-linelen) - 1;
					if (ll > 0) {
						// fix utf8 len here
						ll = wrapline ((const char*)str, cols - linelen - 1);
					}
				}
			}
			if (ll > 0) {
				write (1, str, ll);
				linelen += ll;
			}
			esc = 1;
			str = ptr + 1;
			continue;
		}
		if (esc == 1) {
			// \x1b[2J
			if (ptr[0] != '[') {
				eprintf ("Oops invalid escape char\n");
				esc = 0;
				str = ptr + 1;
				continue;
			}
			esc = 2;
			continue;
		} else if (esc == 2) {
			const char *ptr2 = NULL;
			int x, y, i, state = 0;
			for (i = 0; ptr[i] && state >= 0; i++) {
				switch (state) {
				case 0:
					if (ptr[i] == ';') {
						y = atoi ((const char *)ptr);
						state = 1;
						ptr2 = (const char *)ptr+i+1;
					} else if (ptr[i] >='0' && ptr[i]<='9') {
						// ok
					} else {
						state = -1; // END FAIL
					}
					break;
				case 1:
					if (ptr[i]=='H') {
						x = atoi (ptr2);
						state = -2; // END OK
					} else if (ptr[i] >='0' && ptr[i]<='9') {
						// ok
					} else {
						state = -1; // END FAIL
					}
					break;
				}
			}
			if (state == -2) {
				w32_gotoxy (x, y);
				ptr += i;
				str = ptr + 1;// + i-2;
				continue;
			}
			if (ptr[0]=='0' && ptr[1] == ';' && ptr[2]=='0') {
				// \x1b[0;0H
				/** clear screen if gotoxy **/
				if (vmode) {
					// fill row here
					fill_tail (cols, lines);
				}
				w32_gotoxy (0, 0);
				lines = 0;
				esc = 0;
				ptr += 3;
				str = ptr + 1;
				continue;
			} else if (ptr[0]=='2'&&ptr[1]=='J') {
				//fill_tail(cols, lines);
				w32_clear (); //r_cons_clear ();
				esc = 0;
				ptr = ptr + 1;
				str = ptr + 1;
				continue;
			} else if (ptr[0]=='0'&&(ptr[1]=='m' || ptr [1]=='K')) {
				SetConsoleTextAttribute (hConsole, 1|2|4|8);
				fg = 1|2|4|8;
				bg = 0;
				inv = 0;
				esc = 0;
				ptr++;
				str = ptr + 1;
				continue;
				// reset color
			} else if (ptr[0]=='2'&&ptr[1]=='7'&&ptr[2]=='m') {
				SetConsoleTextAttribute (hConsole, bg|fg);
				inv = 0;
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
				// invert off
			} else if (ptr[0]=='7'&&ptr[1]=='m') {
				SetConsoleTextAttribute (hConsole, bg|fg|128);
				inv = 128;
				esc = 0;
				ptr = ptr + 1;
				str = ptr + 1;
				continue;
				// invert
			} else if (ptr[0]=='3' && (ptr[2]=='m' || ptr[2] == ';')) {
				// http://www.betarun.com/Pages/ConsoleColor/
				switch (ptr[1]) {
				case '0': // BLACK
					fg = 0;
					break;
				case '1': // RED
					fg = 4;
					break;
				case '2': // GREEN
					fg = 2;
					break;
				case '3': // YELLOW
					fg = 2|4;
					break;
				case '4': // BLUE
					fg = 1;
					break;
				case '5': // MAGENTA
					fg = 1|4;
					break;
				case '6': // TURQOISE
					fg = 1|2|8;
					break;
				case '7': // WHITE
					fg = 1|2|4;
					break;
				case '8': // GRAY
					fg = 8;
					break;
				case '9': // ???
					break;
				}
				SetConsoleTextAttribute (hConsole, bg|fg|inv);
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
			} else if (ptr[0]=='4' && ptr[2]=='m') {
				/* background color */
				switch (ptr[1]) {
				case '0': // BLACK
					bg = 0;
					break;
				case '1': // RED
					bg = 40;
					break;
				case '2': // GREEN
					bg = 20;
					break;
				case '3': // YELLOW
					bg = 20|40;
					break;
				case '4': // BLUE
					bg = 10;
					break;
				case '5': // MAGENTA
					bg = 10|40;
					break;
				case '6': // TURQOISE
					bg = 10|20|80;
					break;
				case '7': // WHITE
					bg = 10|20|40;
					break;
				case '8': // GRAY
					bg = 80;
					break;
				case '9': // ???
					break;
				}
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
			}
		}
		ret++;
	}
	if (vmode) {
		/* fill partial line */
		int wlen = cols-linelen - 1;
		if (wlen > 0) {
			char white[1024];
			memset (white, ' ', sizeof (white));
			write (1, white, wlen);
		}
		/* fill tail */
		fill_tail (cols, lines);
	} else {
		int ll = (size_t)(ptr - str);
		if (ll > 0) {
			write (1, str, ll);
			linelen += ll;
		}
	}
	return ret;
}
Пример #16
0
int main(int argc, char **argv) {
	const char *addr = NULL;
	RCore *c, *c2;
	RDiff *d;
	const char *arch = NULL;
	int bits = 0;
	char *file, *file2;
	ut8 *bufa, *bufb;
	int o, sza, szb, /*diffmode = 0,*/ delta = 0;
	int mode = MODE_DIFF;
	int diffops = 0;
	int threshold = -1;
	int gdiff_mode = 0;
	double sim;

	while ((o = getopt (argc, argv, "a:b:Cnpg:Ojrhcdsvxt:")) != -1) {
		switch (o) {
		case 'a':
			arch = optarg;
			break;
		case 'b':
			bits = atoi (optarg);
			break;
		case 'p':
			useva = R_FALSE;
			break;
		case 'r':
			diffmode = 'r';
			break;
		case 'g':
			mode = MODE_GRAPH;
			addr = optarg;
			break;
		case 'c':
			showcount = 1;
			break;
		case 'C':
			mode = MODE_CODE;
			gdiff_mode++;
			break;
		case 'n':
			showbare = R_TRUE;
			break;
		case 'O':
			diffops = 1;
			break;
		case 't':
			threshold = atoi (optarg);
			printf ("%s\n", optarg);
			break;
		case 'd':
			delta = 1;
			break;
		case 'h':
			return show_help (1);
		case 's':
			mode = MODE_DIST;
			break;
		case 'x':
			mode = MODE_COLS;
			break;
		case 'v':
			printf ("radiff2 v"R2_VERSION"\n");
			return 0;
		case 'j':
			diffmode = 'j';
			break;
		default:
			return show_help (0);
		}
	}
	
	if (argc<3 || optind+2>argc)
		return show_help (0);

	if (optind<argc) {
		file = argv[optind];
	} else {
		file = NULL;
	}
	
	if (optind+1<argc) {
		file2 = argv[optind+1];
	} else {
		file2 = NULL;
	}

	switch (mode) {
	case MODE_GRAPH:
	case MODE_CODE:
		c = opencore (file);
		if (!c) eprintf ("Cannot open '%s'\n", r_str_get (file));
		c2 = opencore (file2);
		if (!c || !c2) {
			eprintf ("Cannot open '%s'\n", r_str_get (file2));
			return 1;
		}
		if (arch) {
			r_config_set (c->config, "asm.arch", arch);
			r_config_set (c2->config, "asm.arch", arch);
		}
		if (bits) {
			r_config_set_i (c->config, "asm.bits", bits);
			r_config_set_i (c2->config, "asm.bits", bits);
		}
		r_config_set_i (c->config, "diff.bare", showbare);
		r_config_set_i (c2->config, "diff.bare", showbare);
		r_anal_diff_setup_i (c->anal, diffops, threshold, threshold);
		r_anal_diff_setup_i (c2->anal, diffops, threshold, threshold);
		if (mode == MODE_GRAPH) {
			char *words = strdup (addr);
			char *second = strstr (words, ",");
			if (second) {
				ut64 off;
				*second++ = 0;
				off = r_num_math (c->num, words);
				// define the same function at each offset
				r_core_anal_fcn (c, off, UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_anal_fcn (c2, r_num_math (c2->num, second),
						UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_gdiff (c, c2, R_FALSE); // compute the diff
				r_core_anal_graph (c, off, R_CORE_ANAL_GRAPHBODY | R_CORE_ANAL_GRAPHDIFF);
			} else {
				r_core_anal_fcn (c, r_num_math (c->num, words), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_anal_fcn (c2, r_num_math (c2->num, words), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_gdiff (c, c2, gdiff_mode);
				r_core_anal_graph (c, r_num_math (c->num, addr),
					R_CORE_ANAL_GRAPHBODY | R_CORE_ANAL_GRAPHDIFF);
			}
			free (words);
		} else {
			r_core_gdiff (c, c2, gdiff_mode);
			r_core_diff_show (c, c2);
		}
		r_cons_flush ();
		return 0;
	}

	bufa = (ut8*)r_file_slurp (file, &sza);
	if (!bufa) {
		eprintf ("radiff2: Cannot open %s\n", r_str_get (file));
		return 1;
	}
	bufb = (ut8*)r_file_slurp (file2, &szb);
	if (!bufb) {
		eprintf ("radiff2: Cannot open: %s\n", r_str_get (file2));
		free (bufa);
		return 1;
	}

	switch (mode) {
	case MODE_COLS:
		{
			int cols = (r_cons_get_size (NULL)>112)?16:8;
			dump_cols (bufa, sza, bufb, szb, cols);
		}
		break;
	case MODE_DIFF:
		d = r_diff_new (0LL, 0LL);
		r_diff_set_delta (d, delta);
		if (diffmode == 'j') {
			printf("{\"files\":[{\"filename\":\"%s\", \"size\":%d, \"sha256\":\"", file, sza); 
			handle_sha256 (bufa, sza);
			printf("\"},\n{\"filename\":\"%s\", \"size\":%d, \"sha256\":\"", file2, szb);
			handle_sha256 (bufb, szb);
			printf("\"}],\n");
			printf("\"changes\":[");
		}
		r_diff_set_callback (d, &cb, 0);//(void *)(size_t)diffmode);
		r_diff_buffers (d, bufa, sza, bufb, szb);
		if (diffmode == 'j')
			printf("]\n");
		r_diff_free (d);
		break;
	case MODE_DIST:
		r_diff_buffers_distance (NULL, bufa, sza, bufb, szb, &count, &sim);
		printf ("similarity: %.2f\n", sim);
		printf ("distance: %d\n", count);
		break;
	}

	if (diffmode == 'j' && showcount)
		printf (",\"count\":%d}\n",count);
	else if (showcount && diffmode != 'j')
		printf ("%d\n", count);
	else if (!showcount && diffmode == 'j')
		printf ("}\n");
	free (bufa);
	free (bufb);

	return 0;
}
Пример #17
0
int main(int argc, char **argv) {
	const char *addr = NULL;
	RCore *c, *c2;
	RDiff *d;
	const char *arch = NULL;
	int bits = 0;
	char *file, *file2;
	ut8 *bufa, *bufb;
	int o, sza, szb, rad = 0, delta = 0;
	int mode = MODE_DIFF;
	int diffops = 0;
	int threshold = -1;
	double sim;

	while ((o = getopt (argc, argv, "a:b:Cnpg:Orhcdsvxt:")) != -1) {
		switch (o) {
		case 'a':
			arch = optarg;
			break;
		case 'b':
			bits = atoi (optarg);
			break;
		case 'p':
			useva = R_FALSE;
			break;
		case 'r':
			rad = 1;
			break;
		case 'g':
			mode = MODE_GRAPH;
			addr = optarg;
			break;
		case 'c':
			showcount = 1;
			break;
		case 'C':
			mode = MODE_CODE;
			break;
		case 'n':
			showbare = R_TRUE;
			break;
		case 'O':
			diffops = 1;
			break;
		case 't':
			threshold = atoi (optarg);
			break;
		case 'd':
			delta = 1;
			break;
		case 'h':
			return show_help (1);
		case 's':
			mode = MODE_DIST;
			break;
		case 'x':
			mode = MODE_COLS;
			break;
		case 'v':
			printf ("radiff2 v"R2_VERSION"\n");
			return 0;
		default:
			return show_help (0);
		}
	}
	
	if (argc<3 || optind+2>argc)
		return show_help (0);

	file = argv[optind];
	file2 = argv[optind+1];

	switch (mode) {
	case MODE_GRAPH:
	case MODE_CODE:
		c = opencore (file);
		if (!c) eprintf ("Cannot open '%s'\n", file);
		c2 = opencore (file2);
		if (!c || !c2) {
			eprintf ("Cannot open '%s'\n", file2);
			return 1;
		}
		if (arch) {
			r_config_set (c->config, "asm.arch", arch);
			r_config_set (c2->config, "asm.arch", arch);
		}
		if (bits) {
			r_config_set_i (c->config, "asm.bits", bits);
			r_config_set_i (c2->config, "asm.bits", bits);
		}
		r_config_set_i (c->config, "diff.bare", showbare);
		r_config_set_i (c2->config, "diff.bare", showbare);
		r_anal_diff_setup_i (c->anal, diffops, threshold, threshold);
		r_anal_diff_setup_i (c2->anal, diffops, threshold, threshold);
		if (mode == MODE_GRAPH) {
			const char* second = strstr (addr, ",");
			if (!second) {
				r_core_gdiff (c, c2, R_TRUE);
				r_core_anal_graph (c, r_num_math (c->num, addr),
					R_CORE_ANAL_GRAPHBODY|R_CORE_ANAL_GRAPHDIFF);
			} else {
				const ut64 off = strtoull(addr, 0, 16);
				// define the same function at each offset
				r_core_anal_fcn (c, off, UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_anal_fcn (c2, strtoull (second+1, 0, 16),
						UT64_MAX, R_ANAL_REF_TYPE_NULL, 0);
				r_core_gdiff (c, c2, R_FALSE); // compute the diff
				r_core_anal_graph (c, off, R_CORE_ANAL_GRAPHBODY|R_CORE_ANAL_GRAPHDIFF);
			}
		} else {
			r_core_gdiff (c, c2, R_TRUE);
			r_core_diff_show (c, c2);
		}
		return 0;
	}

	bufa = (ut8*)r_file_slurp (file, &sza);
	if (!bufa) {
		eprintf ("radiff2: Can not open %s\n", bufa);
		return 1;
	}
	bufb = (ut8*)r_file_slurp (file2, &szb);
	if (!bufb) {
		eprintf ("radiff2: Cannot open: %s\n", bufb);
		free (bufa);
		return 1;
	}

	switch (mode) {
	case MODE_COLS:
		{
			int cols = (r_cons_get_size (NULL)>112)?16:8;
			dump_cols (bufa, sza, bufb, szb, cols);
		}
		break;
	case MODE_DIFF:
		d = r_diff_new (0LL, 0LL);
		r_diff_set_delta (d, delta);
		r_diff_set_callback (d, &cb, (void *)(size_t)rad);
		r_diff_buffers (d, bufa, sza, bufb, szb);
		r_diff_free (d);
		break;
	case MODE_DIST:
		r_diff_buffers_distance (NULL, bufa, sza, bufb, szb, &count, &sim);
		printf ("similarity: %.2f\n", sim);
		printf ("distance: %d\n", count);
		break;
	}

	if (showcount)
		printf ("%d\n", count);
	free (bufa);
	free (bufb);

	return 0;
}
Пример #18
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr, *out;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	switch (*str) {
	case '[':
{
		ut64 n = 0LL;
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = NULL;
		if (strlen (str)>5)
			p = strchr (str+5, ':');
		// TODO: honor LE
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			if (str[0] && str[1]) {
				const char *q;
				char *o = strdup (str+1);
				if (o) {
					q = r_num_calc_index (core->num, NULL);
					if (q) {
						if (r_str_replace_char (o, ']', 0)>0) {
							n = r_num_math (core->num, o);
							r_num_calc_index (core->num, q);
						}
					}
					free (o);
				}
			}
		}
		// pop state
		if (ok) *ok = 1;
		ut32 num = 0;
		switch (refsz) {
		case 8:
		case 4:
		case 2:
		case 1:
			(void)r_io_read_at (core->io, n, (ut8*)&num, refsz);
			r_mem_copyendian ((ut8*)&num, (ut8*)&num, refsz, !core->assembler->big_endian);
			return num;
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			return 0LL;
		}
}
		break;
	case '$':
		if (ok) *ok = 1;
		// TODO: group analop-dependant vars after a char, so i can filter
		r_anal_op (core->anal, &op, core->offset,
			core->block, core->blocksize);
		switch (str[1]) {
		case '.': // can use pc, sp, a0, a1, ...
			return r_debug_reg_get (core->dbg, str+2);
		case 'k':
			if (str[2]!='{') {
				eprintf ("Expected '{' after 'k'.\n");
				break;
			}
			bptr = strdup (str+3);
			ptr = strchr (bptr, '}');
			if (ptr == NULL) {
				// invalid json
				free (bptr);
				break;
			}
			*ptr = '\0';
			ret = 0LL;
			out = sdb_querys (core->sdb, NULL, 0, bptr);
			if (out && *out) {
				if (strstr (out, "$k{")) {
					eprintf ("Recursivity is not permitted here\n");
				} else {
					ret = r_num_math (core->num, out);
				}
			}
			free (bptr);
			free (out);
			return ret;
			break;
		case '{':
			bptr = strdup (str+2);
			ptr = strchr (bptr, '}');
			if (ptr != NULL) {
				ut64 ret;
				ptr[0] = '\0';
				ret = r_config_get_i (core->config, bptr);
				free (bptr);
				return ret;
			}
			free (bptr);
			break;
		case 'c': return r_cons_get_size (NULL);
		case 'r': { int rows; r_cons_get_size (&rows); return rows; }
		case 'e': return r_anal_op_is_eob (&op);
		case 'j': return op.jump;
		case 'p': return r_sys_getpid ();
		case 'P': return (core->dbg->pid>0)? core->dbg->pid: 0;
		case 'f': return op.fail;
		case 'm': return op.ptr; // memref
		case 'v': return op.val; // immediate value
		case 'l': return op.size;
		case 'b': return core->blocksize;
		case 's':
			if (core->file) {
				return r_io_desc_size (core->io, core->file->desc);
			}
			return 0LL;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_vget (core->io, core->offset);
			return s? (str[2]=='S'? s->size: s->vaddr): 3;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return r_io_section_vaddr_to_offset (core->io,
				core->offset);
		case 'C': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CALL);
		case 'J': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CODE);
		case 'D': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_DATA);
		case 'X': return getref (core, atoi (str+2), 'x',
				R_ANAL_REF_TYPE_CALL);
		case 'I':
			fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
		break;
	default:
		if (*str>'A') {
			// NOTE: functions override flags
			RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, str);
			if (fcn) {
				if (ok) *ok = R_TRUE;
				return fcn->addr;
			}
#if 0
			ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str);
			if (addr != 0) {
				ret = addr;
			} else {
				...
			}
#endif
			if ((flag = r_flag_get (core->flags, str))) {
				ret = flag->offset;
				if (ok) *ok = R_TRUE;
			}
		}
		break;
	}
Пример #19
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	if (*str=='[') {
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = strchr (str+5, ':');
		ut64 n;
		// TODO: honor endian
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			char *o = strdup (str+1);
			const char *q = r_num_calc_index (core->num, NULL);
			r_str_replace_char (o, ']', 0);
			n = r_num_math (core->num, o);
			r_num_calc_index (core->num, q);
			free (o);
		}
		// pop state
		switch (refsz) {
		case 8: {
			ut64 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 4: {
			ut32 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 2: {
			ut16 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 1: {
			ut8 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			break;
		}
	} else
	if (str[0]=='$') {
		if (ok) *ok = 1;
		// TODO: group analop-dependant vars after a char, so i can filter
		r_anal_op (core->anal, &op, core->offset,
			core->block, core->blocksize);
		switch (str[1]) {
		case '.': // can use pc, sp, a0, a1, ...
			return r_debug_reg_get (core->dbg, str+2);
		case '{':
			bptr = strdup (str+2);
			ptr = strchr (bptr, '}');
			if (ptr != NULL) {
				ut64 ret;
				ptr[0] = '\0';
				ret = r_config_get_i (core->config, bptr);
				free (bptr);
				return ret;
			}
			break;
		case 'h': {
			int rows;
			r_cons_get_size (&rows);
			return rows;
			}
		case 'e': return op.eob;
		case 'j': return op.jump;
		case 'f': return op.fail;
		case 'r': return op.ref;
		case 'l': return op.length;
		case 'b': return core->blocksize;
		case 's': return core->file->size;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_get (core->io, 
				r_io_section_vaddr_to_offset (core->io,
				core->offset));
			return s? (str[2]=='S'? s->size: s->offset): 0;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return core->io->off;
		case 'C': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CALL);
		case 'J': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CODE);
		case 'D': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_DATA);
		case 'X': return getref (core, atoi (str+2), 'x',
				R_ANAL_REF_TYPE_CALL);
		case 'I':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
	} else
	if (*str>'A') {
		if ((flag = r_flag_get (core->flags, str))) {
			ret = flag->offset;
			if (ok) *ok = R_TRUE;
		}
	}
	return ret;
}
Пример #20
0
R_API int r_cons_w32_print(ut8 *ptr, int empty) {
	HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
	int esc = 0;
	int bg = 0, fg = 1|2|4|8;
	ut8 *str = ptr;
	int len = 0;
	int inv = 0;
	int linelen = 0;
	int lines, cols = r_cons_get_size (&lines);

	if (ptr && hConsole)
	for (; *ptr; ptr++) {
		if (ptr[0] == 0xa) {
			int ll = (size_t)(ptr-str);
			lines--;
			if (lines<0) 
				break; //return 0;
			if (ll<1)
				continue;
			if (empty) {
				// TODO: Fix utf8 chop
				/* only chop columns if necessary */
				if (linelen+ll>cols) {
					// chop line if too long
					ll = (cols-linelen)-1;
				}
			}
			write (1, str, ll);
			linelen += ll;
			esc = 0;
			str = ptr+1;
			if (empty) {
				int wlen = cols-linelen;
				char white[1024];
				//wlen = 5;
				if (wlen>0 && wlen<sizeof (white)) {
					memset (white, ' ', sizeof (white));
					write (1, white, wlen-1);
				}
			}
			write (1, "\n\r", 2);
			linelen = 0;
			continue;
		}
		if (ptr[0] == 0x1b) {
			int ll = (size_t)(ptr-str);
			if (str[0]=='\n') {
				str++;
				ll--;
				if (empty) {
					int wlen = cols-linelen-1;
					char white[1024];
					//wlen = 5;
					if (wlen>0) {
						memset (white, ' ', sizeof (white));
						write (1, white, wlen);
					}
				}
				write (1, "\n\r", 2);
				//write (1, "\r\n", 2);
				//lines--;
				linelen = 0;
			}
			if (linelen+ll>cols) {
				// chop line if too long
				ll = (cols-linelen)-1;
				// fix utf8 len here
				ll = wrapline (str, cols-linelen-1);
			}
			if (ll>0) {
				write (1, str, ll);
				linelen += ll;
			}
			esc = 1;
			str = ptr + 1;
			continue;
		}
		if (esc == 1) {
			// \x1b[2J
			if (ptr[0] != '[') {
				eprintf ("Oops invalid escape char\n");
				esc = 0;
				str = ptr + 1;
				continue;
			}
			esc = 2;
			continue;
		} else 
		if (esc == 2) {
			if (ptr[0]=='2'&&ptr[1]=='J') {
				//fill_tail(cols, lines);
				w32_clear (); //r_cons_clear ();
				esc = 0;
				ptr = ptr + 1;
				str = ptr + 1;
				continue;
			} else
			if (ptr[0]=='0'&&ptr[1]==';'&&ptr[2]=='0') {
				// \x1b[0;0H
				/** clear screen if gotoxy **/
				if (empty) {
					// fill row here
					fill_tail(cols, lines);
				}
				w32_gotoxy (0, 0);
				lines = 0;
				esc = 0;
				ptr += 3;
				str = ptr + 1;
				continue;
			} else
			if (ptr[0]=='0'&&(ptr[1]=='m' || ptr [1]=='K')) {
				SetConsoleTextAttribute (hConsole, 1|2|4|8);
				fg = 1|2|4|8;
				bg = 0;
				inv = 0;
				esc = 0;
				ptr++;
				str = ptr + 1;
				continue;
				// reset color
			} else
			if (ptr[0]=='2'&&ptr[1]=='7'&&ptr[2]=='m') {
				SetConsoleTextAttribute (hConsole, bg|fg);
				inv = 0;
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
				// invert off
			} else
			if (ptr[0]=='7'&&ptr[1]=='m') {
				SetConsoleTextAttribute (hConsole, bg|fg|128);
				inv = 128;
				esc = 0;
				ptr = ptr + 1;
				str = ptr + 1;
				continue;
				// invert
			} else
			if (ptr[0]=='3' && ptr[2]=='m') {
				// http://www.betarun.com/Pages/ConsoleColor/
				switch (ptr[1]) {
				case '0': // BLACK
					fg = 0;
					break;
				case '1': // RED
					fg = 4;
					break;
				case '2': // GREEN
					fg = 2;
					break;
				case '3': // YELLOW
					fg = 2|4;
					break;
				case '4': // BLUE
					fg = 1;
					break;
				case '5': // MAGENTA
					fg = 1|4;
					break;
				case '6': // TURQOISE
					fg = 1|2|8;
					break;
				case '7': // WHITE
					fg = 1|2|4;
					break;
				case '8': // GRAY
					fg = 8;
					break;
				case '9': // ???
					break;
				}
				SetConsoleTextAttribute (hConsole, bg|fg|inv);
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
			} else
			if (ptr[0]=='4' && ptr[2]=='m') {
				/* background color */
				switch (ptr[1]) {
				case '0': // BLACK
					bg = 0;
					break;
				case '1': // RED
					bg = 40;
					break;
				case '2': // GREEN
					bg = 20;
					break;
				case '3': // YELLOW
					bg = 20|40;
					break;
				case '4': // BLUE
					bg = 10;
					break;
				case '5': // MAGENTA
					bg = 10|40;
					break;
				case '6': // TURQOISE
					bg = 10|20|80;
					break;
				case '7': // WHITE
					bg = 10|20|40;
					break;
				case '8': // GRAY
					bg = 80;
					break;
				case '9': // ???
					break;
				}
				esc = 0;
				ptr = ptr + 2;
				str = ptr + 1;
				continue;
			}
		} 
		len++;
	}
	
	/* the ending padding */ {
		int ll = (size_t)(ptr-str);
		if (ll>0) {
			write (1, str, ll);
			linelen += ll;
		}
	}

	if (empty) {
		/* fill partial line */
		int wlen = cols-linelen-1;
		char white[1024];
		//wlen = 5;
		if (wlen>0) {
			memset (white, ' ', sizeof (white));
			write (1, white, wlen);
		}
		/* fill tail */
		fill_tail(cols, lines);
	}
	return len;
}
Пример #21
0
static RList *hud_filter(RList *list, char *user_input, int top_entry_n, int *current_entry_n, char **selected_entry) {
	RListIter *iter;
	char *current_entry;
	char mask[HUD_BUF_SIZE];
	char *p, *x;
	int j, rows;
	(void) r_cons_get_size (&rows);
	int counter = 0;
	bool first_line = true;
	RList *res = r_list_newf (free);
	r_list_foreach (list, iter, current_entry) {
		memset (mask, 0, HUD_BUF_SIZE);
		if (*user_input && !strmatch (current_entry, user_input, mask, HUD_BUF_SIZE)) {
			continue;
		}
		if (++counter == rows + top_entry_n) {
			break;
		}
		// if the user scrolled down the list, do not print the first entries
		if (!top_entry_n || *current_entry_n >= top_entry_n) {
			// remove everything after a tab (in ??, it contains the commands)
			x = strchr (current_entry, '\t');
			if (x) {
				*x = 0;
			}
			p = strdup (current_entry);
			// if the filter is empty, print the entry and move on
			if (!user_input[0]) {
				r_list_append (res, r_str_newf (" %c %s", first_line? '-': ' ', p));
			} else {
				// otherwise we need to emphasize the matching part
				if (I (context->color)) {
					int last_color_change = 0;
					int last_mask = 0;
					char *str = r_str_newf (" %c ", first_line? '-': ' ');
					// Instead of printing one char at the time
					// (which would be slow), we group substrings of the same color
					for (j = 0; p[j] && j < HUD_BUF_SIZE; j++) {
						if (mask[j] != last_mask) {
							char tmp = p[j];
							p[j] = 0;
							if (mask[j]) {
								str = r_str_appendf (str, Color_RESET "%s", p + last_color_change);
							} else {
								str = r_str_appendf (str, Color_GREEN "%s", p + last_color_change);
							}
							p[j] = tmp;
							last_color_change = j;
							last_mask = mask[j];
						}
					}
					if (last_mask) {
						str = r_str_appendf (str, Color_GREEN "%s"Color_RESET, p + last_color_change);
					} else {
						str = r_str_appendf (str, Color_RESET "%s", p + last_color_change);
					}
					r_list_append (res, str);
				} else {
					// Otherwise we print the matching characters uppercase
					for (j = 0; p[j]; j++) {
						if (mask[j]) {
							p[j] = toupper ((unsigned char) p[j]);
						}
					}
					r_list_append (res, r_str_newf (" %c %s", first_line? '-': ' ', p));
				}
			}
			// Clean up and restore the tab character (if any)
			free (p);
			if (x) {
				*x = '\t';
			}
			if (first_line) {
				*selected_entry = current_entry;
			}
			first_line = false;
		}
		(*current_entry_n)++;

	}