Exemple #1
0
R_API int r_core_log_list(RCore *core, int n, int nth, char fmt) {
	int printed = 0;
	int count = 0, i, idx, id = core->log->first;
	RStrpool *sp = core->log->sp;
	char *str = sp->str;

	if (fmt == 'j') {
		r_cons_printf ("[");
	}
	for (i = idx = 0; str && *str; i++, id++) {
		if ((n && n <= id) || !n) {
			switch (fmt) {
			case 'j': r_cons_printf ("%s[%d,\"%s\"]",
					printed? ",": "", id, str); break;
			case 't': r_cons_println (str); break;
			case '*': r_cons_printf ("\"l %s\"\n", str); break;
			default: r_cons_printf ("%d %s\n", id, str); break;
			}
			printed++;
			if (nth && printed >= nth) {
				break;
			}
		}
		str = r_strpool_next (sp, idx);
		if (!str) {
			break;
		}
		idx = r_strpool_get_index (sp, str);
		count++;
	}
	if (fmt == 'j') {
		r_cons_printf ("]\n");
	}
	return count;
}
Exemple #2
0
static bool nextpal_item(RCore *core, int mode, const char *file, int ctr) {
	const char *fn = r_str_lchr (file, '/');
	if (!fn) fn = file;
	switch (mode) {
	case 'j': // json
		r_cons_printf ("%s\"%s\"", ctr?",":"", fn);
		break;
	case 'l': // list
		r_cons_println (fn);
		break;
	case 'p': // previous
		// TODO: move logic here
		break;
	case 'n': // next
		if (getNext) {
			curtheme = r_str_dup (curtheme, fn);
			getNext = false;
			return false;
		} else if (curtheme) {
			if (!strcmp (curtheme, fn)) {
				getNext = true;
			}
		} else {
			curtheme = r_str_dup (curtheme, fn);
			return false;
		}
		break;
	}
	return true;
}
Exemple #3
0
R_API int r_core_project_list(RCore *core, int mode) {
	RListIter *iter;
	RList *list;
	int isfirst = 1;
	char *foo, *path = r_file_abspath (r_config_get (core->config, "dir.projects"));
	if (!path)
		return 0;
	list = r_sys_dir (path);
	switch (mode) {
	case 'j':
		r_cons_printf ("[");
		r_list_foreach (list, iter, foo) {
			// todo. escape string
			if (r_core_is_project (core, foo)) {
				r_cons_printf ("%s\"%s\"",
					isfirst?"":",", foo);
				isfirst = 0;
			}
		}
		r_cons_printf ("]\n");
		break;
	default:
		r_list_foreach (list, iter, foo) {
			if (r_core_is_project (core, foo))
				r_cons_println (foo);
		}
		break;
	}
	r_list_free (list);
	free (path);
	return 0;
}
Exemple #4
0
R_API int r_core_project_cat(RCore *core, const char *name) {
	char *path = r_core_project_file (core, name);
	if (path) {
		char *data = r_file_slurp (path, NULL);
		if (data) {
			r_cons_println (data);
			free (data);
		}
	}
	free (path);
	return 0;
}
Exemple #5
0
R_API int r_core_project_list(RCore *core, int mode) {
	PJ *pj = NULL;
	RListIter *iter;
	RList *list;

	char *foo, *path = r_file_abspath (r_config_get (core->config, "dir.projects"));
	if (!path) {
		return 0;
	}
	list = r_sys_dir (path);
	switch (mode) {
	case 'j':
		pj = pj_new ();
		if (!pj) {
			break;
		}
		pj_a (pj);
		r_list_foreach (list, iter, foo) {
			// todo. escape string
			if (r_core_is_project (core, foo)) {
				pj_s (pj, foo);
			}
		}
		pj_end (pj);
		r_cons_printf ("%s\n", pj_string (pj));
		pj_free (pj);
		break;
	default:
		r_list_foreach (list, iter, foo) {
			if (r_core_is_project (core, foo)) {
				r_cons_println (foo);
			}
		}
		break;
	}
	r_list_free (list);
	free (path);
	return 0;
}
Exemple #6
0
static int stdprintifstruct (void *p, const char *k, const char *v) {
	if (!strncmp (v, "struct", strlen ("struct") + 1))
		r_cons_println (k);
	return 1;
}
Exemple #7
0
//TODO
//look at the next couple of functions
//can be optimized into one right ... you see it you do it :P
static int sdbforcb (void *p, const char *k, const char *v) {
	if (!strncmp (v, "type", strlen ("type") + 1))
		r_cons_println (k);
	return 1;
}
Exemple #8
0
static int cmd_type(void *data, const char *input) {
	RCore *core = (RCore *)data;

	switch (input[0]) {
	// t [typename] - show given type in C syntax
	case 'u': // "tu"
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"USAGE tu[...]", "", "",
				"tu", "", "List all loaded unions",
				"tu?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
		} break;
		case 0:
			sdb_foreach (core->anal->sdb_types, stdprintifunion, core);
			break;
		}
		break;
	case 'k': // "tk"
		if (input[1] == ' ') {
			sdb_query (core->anal->sdb_types, input + 2);
		} else sdb_query (core->anal->sdb_types, "*");
		fflush (stdout);
		break;
	case 's': // "ts"
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"USAGE ts[...]", "", "",
				"ts", "", "List all loaded structs",
				"ts?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
		} break;
		case 0:
			sdb_foreach (core->anal->sdb_types, stdprintifstruct, core);
			break;
		}
		break;
	case 'b': {
		char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL;
		const char *isenum;
		p = s? strchr (s, ' '): NULL;
		if (p) {
			*p++ = 0;
			// dupp in core.c (see getbitfield())
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				*--p = '.';
				const char *res = sdb_const_get (core->anal->sdb_types, s, 0);
				if (res)
					r_cons_println (res);
				else eprintf ("Invalid enum member\n");
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			eprintf ("Missing value\n");
		}
		free (s);
	} break;
	case 'e': {
		if (!input[1]) {
			char *name = NULL;
			SdbKv *kv;
			SdbListIter *iter;
			SdbList *l = sdb_foreach_list (core->anal->sdb_types);
			ls_foreach (l, iter, kv) {
				if (!strcmp (kv->value, "enum")) {
					if (!name || strcmp (kv->value, name)) {
						free (name);
						name = strdup (kv->key);
						r_cons_println (name);
					}
				}
			}
			free (name);
			ls_free (l);
			break;
		}
		if (input[1] == '?') {
			const char *help_message[] = {
				"USAGE te[...]", "", "",
				"te", "", "List all loaded enums",
				"te", " <enum> <value>", "Show name for given enum number",
				"te?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
			break;
		}
		char *p, *s = strdup (input + 2);
		const char *isenum;
		p = strchr (s, ' ');
		if (p) {
			*p++ = 0;
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strncmp (isenum, "enum", 4)) {
				const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p));
				const char *res = sdb_const_get (core->anal->sdb_types, q, 0);
				if (res)
					r_cons_println (res);
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			//eprintf ("Missing value\n");
			r_core_cmdf (core, "t~&%s,=0x", s);
		}
		free (s);
	} break;
	case ' ': {
		const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0);
		if (isenum && !strcmp (isenum, "enum")) {
			eprintf ("IS ENUM! \n");
		} else {
			char *fmt = r_anal_type_format (core->anal, input + 1);
			if (fmt) {
				r_str_chop (fmt);
				r_cons_printf ("pf %s\n", fmt);
				free (fmt);
			} else eprintf ("Cannot find '%s' type\n", input + 1);
		}
	} break;
	// t* - list all types in 'pf' syntax
	case '*':
		sdb_foreach (core->anal->sdb_types, typelist, core);
		break;
	case 0:
		sdb_foreach (core->anal->sdb_types, sdbforcb, core);
		break;
	case 'o':
		if (!r_sandbox_enable (0)) {
			if (input[1] == ' ') {
				const char *filename = input + 2;
				char *homefile = NULL;
				if (*filename == '~') {
					if (filename[1] && filename[2]) {
						homefile = r_str_home (filename + 2);
						filename = homefile;
					}
				}
				if (!strcmp (filename, "-")) {
					char *out, *tmp;
					tmp = r_core_editor (core, NULL, "");
					if (tmp) {
						out = r_parse_c_string (tmp);
						if (out) {
							//		r_cons_strcat (out);
							save_parsed_type (core, out);
							free (out);
						}
						free (tmp);
					}
				} else {
					char *out = r_parse_c_file (filename);
					if (out) {
						//r_cons_strcat (out);
						save_parsed_type (core, out);
						free (out);
					}
					//r_anal_type_loadfile (core->anal, filename);
				}
				free (homefile);
			} else if (input[1] == 's') {
				const char *dbpath = input + 3;
				if (r_file_exists (dbpath)) {
					Sdb *db_tmp = sdb_new (0, dbpath, 0);
					sdb_merge (core->anal->sdb_types, db_tmp);
					sdb_close (db_tmp);
					sdb_free (db_tmp);
				}
			}
		} else {
			eprintf ("Sandbox: system call disabled\n");
		}
		break;
	// td - parse string with cparse engine and load types from it
	case 'd':
		if (input[1] == '?') {
			const char *help_message[] = {
				"Usage:", "\"td [...]\"", "",
				"td", "[string]", "Load types from string",
				NULL };
			r_core_cmd_help (core, help_message);
			r_cons_printf ("Note: The td command should be put between double quotes\n"
				"Example: \" td struct foo {int bar;int cow};\""
				"\nt");

		} else if (input[1] == ' ') {
			char tmp[8192];
			snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2);
			//const char *string = input + 2;
			//r_anal_str_to_type (core->anal, string);
			char *out = r_parse_c_string (tmp);
			if (out) {
				//r_cons_strcat (out);
				save_parsed_type (core, out);
				free (out);
			}
		} else {
			eprintf ("Invalid use of td. See td? for help\n");
		}
		break;
	// tl - link a type to an address
	case 'l':
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"Usage:", "", "",
				"tl", "", "list all links in readable format",
				"tl", "[typename]", "link a type to current adress.",
				"tl", "[typename] = [address]", "link type to given address.",
				"tls", "[address]", "show link at given address",
				"tl-*", "", "delete all links.",
				"tl-", "[address]", "delete link at given address.",
				"tl*", "", "list all links in radare2 command format",
				"tl?", "", "print this help.",
				NULL };
			r_core_cmd_help (core, help_message);
			} break;
		case ' ': {
			char *type = strdup (input + 2);
			char *ptr = strchr (type, '=');
			ut64 addr;

			if (ptr) {
				*ptr++ = 0;
				r_str_chop (ptr);
				if (ptr && *ptr) {
					addr = r_num_math (core->num, ptr);
				} else {
					eprintf ("address is unvalid\n");
					free (type);
					break;
				}
			} else {
				addr = core->offset;
			}
			r_str_chop (type);
			char *tmp = sdb_get (core->anal->sdb_types, type, 0);
			if (tmp && *tmp) {
				r_anal_type_link (core->anal, type, addr);
				free (tmp);
			} else {
				eprintf ("unknown type %s\n", type);
			}
			free (type);
			}
			break;
		case 's': {
			int ptr;
			char *addr = strdup (input + 2);
			SdbKv *kv;
			SdbListIter *sdb_iter;
			SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types);
			r_str_chop (addr);
			ptr = r_num_math (NULL, addr);
			//r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr);
			ls_foreach (sdb_list, sdb_iter, kv) {
				char *linkptr;
				if (strncmp (kv->key, "link.", strlen ("link."))) {
					continue;
				}
				linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link."));
				if (ptr == r_num_math (NULL, linkptr)) {
					linklist_readable (core, kv->key, kv->value);
				}
			}
			free (addr);
			ls_free (sdb_list);
			}
			break;
		case '-':
			switch (input[2]) {
			case '*':
				sdb_foreach (core->anal->sdb_types, sdbdeletelink, core);
				break;
			case ' ': {
				const char *ptr = input + 3;
				ut64 addr = r_num_math (core->num, ptr);
				r_anal_type_unlink (core->anal, addr);
				}
				break;
			}
			break;
		case '*':
			sdb_foreach (core->anal->sdb_types, linklist, core);
			break;
		case '\0':
			sdb_foreach (core->anal->sdb_types, linklist_readable, core);
			break;
		}
Exemple #9
0
static void print_format_values(RCore *core, const char *fmt, bool onstack, ut64 src, bool color) {
	char opt;
	ut64 bval = src;
	int i;
	int endian = core->print->big_endian;
	int width = (core->anal->bits == 64)? 8: 4;
	int bsize = R_MIN (64, core->blocksize);

	ut8 *buf = malloc (bsize);
	if (!buf) {
		eprintf ("Cannot allocate %d byte(s)\n", bsize);
		free (buf);
		return;
	}
	if (fmt) {
		opt = *fmt;
	} else {
		opt = 'p'; // void *ptr
	}
	if (onstack || ((opt != 'd' && opt != 'x') && !onstack)) {
		if (color) {
			r_cons_printf (Color_BGREEN"0x%08"PFMT64x Color_RESET" --> ", bval);
		} else {
			r_cons_printf ("0x%08"PFMT64x" --> ", bval);
		}
		r_io_read_at (core->io, bval, buf, bsize);
	}
	if (onstack) { // Fetch value from stack
		bval = get_buf_val (buf, endian, width);
		if (opt != 'd' && opt != 'x') {
			r_io_read_at (core->io, bval, buf, bsize); // update buf with val from stack
		}
	}
	r_cons_print (color? Color_BGREEN: "");
	switch (opt) {
	case 'z' : // Null terminated string
		r_cons_print (color ?Color_RESET Color_BWHITE:"");
		r_cons_print ("\"");
		for (i = 0; i < MAXSTRLEN; i++) {
			if (buf[i] == '\0') {
				break;
			}
			ut8 b = buf[i];
			if (IS_PRINTABLE (b)) {
				r_cons_printf ("%c", b);
			} else {
				r_cons_printf ("\\x%02x", b);
			}
			if (i == MAXSTRLEN - 1) {
				 r_cons_print ("..."); // To show string is truncated
			}
		}
		r_cons_print ("\"");
		r_cons_newline ();
		break;
	case 'd' : // integer
	case 'x' :
		r_cons_printf ("0x%08" PFMT64x, bval);
		r_cons_newline ();
		break;
	case 'c' : // char
		r_cons_print ("\'");
		ut8 ch = buf[0];
		if (IS_PRINTABLE (ch)) {
			r_cons_printf ("%c", ch);
		} else {
			r_cons_printf ("\\x%02x", ch);
		}
		r_cons_print ("\'");
		r_cons_newline ();
		break;
	case 'p' : // pointer
		{
		// Try to deref the pointer once again
		r_cons_printf ("0x%08"PFMT64x, get_buf_val (buf, endian, width));
		r_cons_newline ();
		break;
		}
	default:
		//TODO: support types like structs and unions
		r_cons_println ("unk_format");
	}
	r_cons_print (Color_RESET);
	free (buf);
}
Exemple #10
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;
			}
		}
	}
Exemple #11
0
static int cmd_project(void *data, const char *input) {
	RCore *core = (RCore *) data;
	const char *file, *arg = (input && *input)? input + 1: NULL;
	const char *fileproject = r_config_get (core->config, "prj.name");
	char *str = NULL;

	if (!input) {
		return false;
	}
	str = strdup (fileproject);
	arg = strchr (input, ' ');
	if (arg) {
		arg++;
	} else {
		if (*input) {
			arg = input + 1;
			if (*arg == '&') {
				arg++;
			}
		}
	}
	file = arg;
	switch (input[0]) {
	case 'c':
		if (input[1] == ' ') {
			r_core_project_cat (core, input + 2);
		} else {
			eprintf ("Usage: Pc [prjname]\n");
		}
		break;
	case 'o':
		//	if (r_file_is_regular (file))
		if (input[1] == '&') {
			r_core_project_open (core, file, true);
		} else if (input[1]) {
			r_core_project_open (core, file, false);
		} else {
			if (file && *file) {
				r_cons_println (file);
			}
		}
		break;
	case 'l':
		r_core_project_list (core, input[1]);
		break;
	case 'd':
	case '-':
		r_core_project_delete (core, file);
		break;
	case 's':
		if (!file || !file[0]) { /* if no argument specified use current project */
			file = str;
		}
		if (r_core_project_save (core, file)) {
			r_config_set (core->config, "prj.name", file);
			r_cons_println (file);
		}
		break;
	case 'S':
		if (input[1] == ' ') {
			r_core_project_save_rdb (core, input + 2, R_CORE_PRJ_ALL);
		} else {
			eprintf ("Usage: PS [file]\n");
		}
		break;
	case 'n':
		if (!fileproject || !*fileproject) {
			eprintf ("No project\n");
		} else {
			switch (input[1]) {
			case '-':
				/* remove lines containing specific words */
			{
				FILE *fd = r_sandbox_fopen (str, "w");
				if (!fd) {
					eprintf ("Cannot open %s\n", str);
				} else {
					char *str = r_core_project_notes_file (core, fileproject);
					char *data = r_file_slurp (str, NULL);
					int del = 0;
					if (data) {
						char *ptr, *nl;
						for (ptr = data; ptr; ptr = nl)  {
							nl = strchr (ptr, '\n');
							if (nl) {
								*nl++ = 0;
								if (strstr (ptr, input + 2)) {
									del++;
								} else {
									fprintf (fd, "%s\n", ptr);
								}
							}
						}
						free (data);
					}
					if (del > 0) {
						eprintf ("Deleted %d lines\n", del);
					}
					free (str);
					fclose (fd);
				}
			}
			break;
			case ' ':
				if (input[2] == '-') {
					char *str = r_core_project_notes_file (core, fileproject);
					// edit with cfg.editor
					const char *editor = r_config_get (core->config, "cfg.editor");
					if (str && *str && editor && *editor) {
						r_sys_cmdf ("%s %s", editor, str);
					} else {
						eprintf ("No cfg.editor configured\n");
					}
					free (str);
				} else {
					//char *str = r_core_project_notes_file (core, fileproject);
					// append line to project notes
					char *str = r_core_project_notes_file (core, fileproject);
					char *data = r_file_slurp (str, NULL);
					FILE *fd = r_sandbox_fopen (str, "a");
					if (fd) {
						fprintf (fd, "%s\n", input + 2);
						fclose (fd);
					}
					free (str);
					free (data);
				}
				break;
			case 'j':
				if (!input[2]) {
					int len = 0;
					/* get base64 string */
					char *str = r_core_project_notes_file (core, fileproject);
					if (str) {
						char *data = r_file_slurp (str, &len);
						char *res = r_base64_encode_dyn (data, len);
						if (res) {
							r_cons_println (res);
							free (res);
						}
						free (data);
						free (str);
					}
				} else if (input[2] == ' ') {
					/* set base64 string */
					ut8 *data = r_base64_decode_dyn (input + 3, -1);
					if (data) {
						char *str = r_core_project_notes_file (core, fileproject);
						if (str) {
							r_file_dump (str, data, strlen ((const char *) data), 0);
							free (str);
						}
						free (data);
					}
				} else {
					eprintf ("Usage: `Pnj` or `Pnj ...`\n");
				}
				break;
			case 'x':
				r_core_project_execute_cmds (core, fileproject);
				break;
			case 0:
			{
				char *str = r_core_project_notes_file (core, fileproject);
				char *data = r_file_slurp (str, NULL);
				if (data) {
					r_cons_println (data);
					free (data);
				}
				free (str);
			}
			break;
			case '?':
			{
				const char *help_msg[] = {
					"Usage:", "Pn[j-?] [...]", "Project Notes",
					"Pn", "", "show project notes",
					"Pn", " -", "edit notes with cfg.editor",
					"Pn-", "", "delete notes",
					"Pn-", "str", "delete lines matching /str/ in notes",
					"Pnx", "", "run project note commands",
					"Pnj", "", "show notes in base64",
					"Pnj", " [base64]", "set notes in base64",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
			}
		}
		break;
	case 'i':
		if (file && *file) {
			char *prjName = r_core_project_info (core, file);
			r_cons_println (prjName);
			free (prjName);
		}
		break;
	default: {
		const char *help_msg[] = {
			"Usage:", "P[?osi] [file]", "Project management",
			"Pc", " [file]", "show project script to console",
			"Pd", " [file]", "delete project",
			"Pi", " [file]", "show project information",
			"Pl", "", "list all projects",
			"Pn", "[j]", "show project notes (Pnj for json)",
			"Pn", " [base64]", "set notes text",
			"Pn", " -", "edit notes with cfg.editor",
			"Po", " [file]", "open project",
			"Ps", " [file]", "save project",
			"PS", " [file]", "save script file",
			"P-", " [file]", "delete project (alias for Pd)",
			"NOTE:", "", "See 'e??prj.'",
			"NOTE:", "", "project are stored in ~/.config/radare2/projects",
			NULL
		};
		r_core_cmd_help (core, help_msg);
	}
		break;
	}
	free (str);
	return true;
}
Exemple #12
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len;
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename = "";
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa","[?] push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wao"," [?] op","modify opcode (change conditional of jump. nop, etc)",
		"wA"," [?] r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[?][ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[?] [nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo","[?] hex","write in block with operation. 'wo?' fmi",
		"wp"," [?] -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt[f]"," [?] file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"wts"," host:port [sz]", "send data to remote host:port via tcp://",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx","[?][fs] 9090","write two intel nops (from wxfile or wxseek)",
		"wv","[?] eip+34","write 32-64 bit value",
		"wz"," string","write zero terminated string (like w + \\x00)",
		NULL
	};

	if (!input) {
		return 0;
	}

	len = strlen (input);
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup (*input? input + 1: "");
	_fn[0] = 0;

	switch (*input) {
	case 'B':
		switch (input[1]) {
		case ' ':
			cmd_write_bits (core, 1, r_num_math (core->num, input + 2));
			break;
		case '-':
			cmd_write_bits (core, 0, r_num_math (core->num, input + 2));
			break;
		default:
			eprintf ("Usage: wB 0x2000  # or wB-0x2000\n");
			break;
		}
		break;
	case '0':
		{
			ut64 len = r_num_math (core->num, input+1);
			if (len>0) {
				ut8 *buf = calloc (1, len);
				if (buf) {
					r_io_write_at (core->io, core->offset, buf, len);
					r_core_block_read (core);
					free (buf);
				} else eprintf ("Cannot allocate %d bytes\n", (int)len);
			}
		}
		break;
	case '1':
	case '2':
	case '4':
	case '8':
		if (input[1] && input[2]) {
			if (input[1]==input[2]) {
				num = 1;
			} else num = r_num_math (core->num, input+2);
		}
		switch (input[2] ? input[1] : 0) {
		case '+':
			cmd_write_inc (core, *input-'0', num);
			break;
		case '-':
			cmd_write_inc (core, *input-'0', -num);
			break;
		default:
			eprintf ("Usage: w[1248][+-][num]   # inc/dec byte/word/..\n");
		}
		break;
	case '6':
		{
		int fail = 0;
		ut8 *buf = NULL;
		int len = 0, str_len;
		const char *str;

		if (input[1] && input[2] != ' ')
			fail = 1;

		if (input[1] && input[2] && input[3])
			str = input + 3;
		else
			str = "";
		str_len = strlen (str) + 1;
		if (!fail) {
			switch (input[1]) {
			case 'd':
				buf = malloc (str_len);
				len = r_base64_decode (buf, str, 0);
				if(len == 0) {
					free(buf);
					fail = 1;
				}
				break;
			case 'e':
				{
				ut8 *bin_buf = malloc (str_len);
				const int bin_len = r_hex_str2bin (str, bin_buf);
				if (bin_len <= 0) {
					fail = 1;
				} else {
					buf = calloc (str_len + 1, 4);
					len = r_base64_encode ((char *)buf, bin_buf, bin_len);
					if(len == 0) {
						free (buf);
						fail = 1;
					}
				}
				free (bin_buf);
				break;
				}
			default:
				fail = 1;
				break;
			}
		}
		if (!fail) {
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (buf);
		} else {
			eprintf ("Usage: w6[de] base64/hex\n");
		}
		break;
		}
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_println (p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = false;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
		case 'n':
			if (input[2] == ' ') {
				len = *input ? r_num_math (core->num, input+3) : 0;
				if (len > 0) {
					const ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, core->offset, len);
					core->offset = cur_off;
					r_core_block_read (core);
				}
			}
			break;
		case 'N':
			if (input[2] == ' ') {
				input += 3;
				while (*input && *input == ' ') input++;
				addr = r_num_math (core->num, input);
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? r_num_math (core->num, input) : 0;
				if (len > 0){
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					cmd_suc = r_core_seek (core, cur_off, 1);
					core->offset = addr;
					r_core_block_read (core);
				}
			}
			break;
		case 'x':
			if (input[2] == ' ') {
				input += 2;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, cur_off, len);
					if (cmd_suc) {
						r_core_write_at (core, cur_off, bytes, len);
					}
					core->offset = cur_off;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 'X':
			if (input[2] == ' ') {
				addr = r_num_math (core->num, input+3);
				input += 3;
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					//ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					if (cmd_suc) {
						r_core_write_at (core, addr, bytes, len);
					}
					core->offset = addr;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 's':
			input +=  3;
			while (*input && *input == ' ') input++;
			len = strlen (input);
			input_shadow = len > 0? malloc (len+1): 0;

			// since the distance can be negative,
			// the r_num_math will perform an unwanted operation
			// the solution is to tokenize the string :/
			if (input_shadow) {
				strncpy (input_shadow, input, len+1);
				p = strtok (input_shadow, " ");
				addr = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				dist = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				b_size = p && *p ? r_num_math (core->num, p) : 0;
				if (dist != 0){
					r_core_shift_block (core, addr, b_size, dist);
					r_core_seek (core, addr, 1);
					cmd_suc = true;
				}
			}
			free (input_shadow);
			break;
		case '?':
		default:
			cmd_suc = false;
		}


		if (cmd_suc == false) {
			const char* help_msg[] = {
			"Usage", "", "write extend",
			"wen", " <num>", "insert num null bytes at current offset",
			"wex", " <hex_bytes>", "insert bytes at current offset",
			"weN", " <addr> <len>", "insert bytes at address",
			"weX", " <addr> <hex_bytes>", "insert bytes at address",
			"wes", " <addr>  <dist> <block_size>", "shift a blocksize left or write in the editor",
			NULL};
			r_core_cmd_help (core, help_msg);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				r_cons_printf ("Usage: wp [-|r2patch-file]\n"
					" ^# -> comments\n"
					" . -> execute command\n"
					" ! -> execute command\n"
					" OFFSET { code block }\n"
					" OFFSET \"string\"\n"
					" OFFSET 01020304\n"
					" OFFSET : assembly\n"
					" + {code}|\"str\"|0210|: asm\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r': //wr
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len > 0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			{
			const char* help_msg[] = {
				"Usage:", " wA", "[type] [value]",
				"Types", "", "",
				"r", "", "raw write value",
				"v", "", "set value (taking care of current address)",
				"d", "", "destination register",
				"0", "", "1st src register",
				"1", "", "2nd src register",
				"Example:",  "wA r 0", "# e800000000",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core);
			break;
		case 'r':
			r_io_cache_reset (core->io, true);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, true);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				from = r_num_math (core->num, input+3);
				if (p) {
					*p = 0;
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, true);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '?':
			{
				const char* help_msg[] = {
					"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
					"wc","","list all write changes",
					"wc-"," [from] [to]","remove write op at curseek or given addr",
					"wc+"," [addr]","commit change from cache to io",
					"wc*","","\"\" in radare commands",
					"wcr","","reset all write changes in cache",
					"wci","","commit write cache",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
		case '*':
			r_io_cache_list (core->io, 1);
			break;
		case 'j':
			r_io_cache_list (core->io, 2);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, 0);
			break;
		}
		break;
	case ' ': // "w"
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core);
		break;
	case 'z': // "wz"
		/* write zero-terminated string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str + 1, len);
		if (len > 0) {
			core->num->value = len;
		} else {
			core->num->value = 0;
		}
#if 0
		r_io_use_desc (core->io, core->file->desc);
#endif
		WSEEK (core, len + 1);
		r_core_block_read (core);
		break;
	case 't': // "wt"
		if (*str == 's') { // "wts"
			if (str[1] == ' ') {
				eprintf ("Write to server\n");
				st64 sz = r_io_size (core->io);
				if (sz > 0) {
					ut64 addr = 0;
					char *host = str + 2;
					char *port = strchr (host, ':');
					if (port) {
						*port ++= 0;
						char *space = strchr (port, ' ');
						if (space) {
							*space++ = 0;
							sz = r_num_math (core->num, space);
							addr = core->offset;
						}
						ut8 *buf = calloc (1, sz);
						r_io_read_at (core->io, addr, buf, sz);
						RSocket *s = r_socket_new (false);
						if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, 0)) {
							int done = 0;
							eprintf ("Transfering file to the end-point...\n");
							while (done < sz) {
								int rc = r_socket_write (s, buf + done, sz - done);
								if (rc <1) {
									eprintf ("oops\n");
									break;
								}
								done += rc;
							}
						} else {
							eprintf ("Cannot connect\n");
						}
						r_socket_free (s);
						free (buf);
					} else {
						eprintf ("Usage wts host:port [sz]\n");
					}
				} else {
					eprintf ("Unknown file size\n");
				}
			} else {
				eprintf ("Usage wts host:port [sz]\n");
			}
		} else if (*str == '?' || *str == '\0') {
			const char* help_msg[] = {
				"Usage:", "wt[a] file [size]", " Write 'size' bytes in current blok to 'file'",
				"wta", " [filename]", "append to 'filename'",
				"wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')",
				"wtf!", " [filename]", "write to file from current addresss to eof",
				NULL};
			r_core_cmd_help (core, help_msg);
			free (ostr);
			return 0;
		} else {
			bool append = false;
			bool toend = false;
			st64 sz = core->blocksize;
			if (*str == 'f') { // "wtf"
				str++;
				if (*str == '!') {
					toend = true;
					str++;
				}
				if (*str) {
					filename = str + ((*str == ' ')? 1: 0);
				} else {
					filename = "";
				}
			} else if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0] == ' ') {
					filename = str + 1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else {
				filename = str + 1;
			}
			tmp = strchr (str + 1, ' ');
			if (!filename || !*filename) {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			}
			if (tmp) {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
				} else {
					sz = (st64) r_num_math (core->num, tmp + 1);
					if (!sz) {
						sz = core->blocksize;
					}
					*tmp = 0;
				}
				if (sz < 1) {
					eprintf ("Invalid length\n");
				} else {
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				}
			} else {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				} else {
					if (!r_file_dump (filename, core->block, core->blocksize, append)) {
						sz = 0;
					} else {
						sz = core->blocksize;
					}
				}
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		cmd_wf (core, input);
		break;
	case 'w':
		str++;
		len = (len - 1) << 1;
		tmp = (len > 0) ? malloc (len + 1) : NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (tmp);
		} else {
			eprintf ("Cannot malloc %d\n", len);
		}
		break;
	case 'x': // "wx"
		switch (input[1]) {
		case 'f': // "wxf"
			arg = (const char *)(input + ((input[2]==' ')? 3: 2));
			if (!strcmp (arg, "-")) {
				int len;
				ut8 *out;
				char *in = r_core_editor (core, NULL, NULL);
				if (in) {
					out = (ut8 *)strdup (in);
					if (out) {
						len = r_hex_str2bin (in, out);
						if (len > 0) {
							r_io_write_at (core->io, core->offset, out, len);
							core->num->value = len;
						} else {
							core->num->value = 0;
						}
						free (out);
					}
					free (in);
				}
			} else if (r_file_exists (arg)) {
				if ((buf = r_file_slurp_hexpairs (arg, &size))) {
					r_io_use_desc (core->io, core->file->desc);
					if (r_io_write_at (core->io, core->offset, buf, size) > 0) {
						core->num->value = size;
						WSEEK (core, size);
					}
					free (buf);
					r_core_block_read (core);
				} else {
					eprintf ("This file doesnt contains hexpairs\n");
				}
			} else {
				eprintf ("Cannot open file '%s'\n", arg);
			}
			break;
		case 's': // "wxs"
			{
				int len = cmd_write_hexpair (core, input + 2);
				if (len > 0) {
					r_core_seek_delta (core, len);
					core->num->value = len;
				} else {
					core->num->value = 0;
				}
			}
			break;
		case ' ': // "wx ..."
			cmd_write_hexpair (core, input + 1);
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wx[f] [arg]", "",
				"wx", " 9090", "write two intel nops",
				"wxf", " -|file", "write contents of hexpairs file here",
				"wxs", " 9090", "write hexpairs and seek at the end",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'a': // "wa"
		switch (input[1]) {
		case 'o': // "wao"
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					cmd_write_hexpair(core, acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f': // "wof"
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						cmd_write_hexpair(core, acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wa[of*] [arg]", "",
				"wa", " nop", "write nopcode using asm.arch and asm.bits",
				"wa*", " mov eax, 33", "show 'wx' op with hexpair bytes of assembled opcode",
				"\"wa nop;nop\"", "" , "assemble more than one instruction (note the quotes)",
				"waf", "foo.asm" , "assemble file and write bytes",
				"wao?", "", "show help for assembler operation on current opcode (hack)",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'b': // "wb"
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Exemple #13
0
static int cmd_eval(void *data, const char *input) {
	char *p;
	RCore *core = (RCore *)data;
	switch (input[0]) {
	case 't': // env
		if (input[1] == 'a') {
			r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son");
		} else if (input[1]==' ' && input[2]) {
			RConfigNode *node = r_config_node_get (core->config, input+2);
			if (node) {
				const char *type = r_config_node_type (node);
				if (type && *type) {
					r_cons_println (type);
				}
			}
		} else {
			eprintf ("Usage: et [varname]  ; show type of eval var\n");
		}
		break;
	case 'n': // env
		if (!strchr (input, '=')) {
			char *var, *p;
			var = strchr (input, ' ');
			if (var) while (*var==' ') var++;
			p = r_sys_getenv (var);
			if (p) {
				r_cons_println (p);
				free (p);
			} else {
				char **e = r_sys_get_environ ();
				while (e && *e) {
					r_cons_println (*e);
					e++;
				}
			}
		} else if (strlen (input)>3) {
			char *v, *k = strdup (input+3);
			if (!k) break;
			v = strchr (k, '=');
			if (v) {
				*v++ = 0;
				r_sys_setenv (k, v);
			}
			free (k);
		}
		return true;
	case 'x': // exit
		// XXX we need headers for the cmd_xxx files.
		return cmd_quit (data, "");
	case 'j': // json
		r_config_list (core->config, NULL, 'j');
		break;
	case 'v': // verbose
		r_config_list (core->config, input + 1, 'v');
		break;
	case 'q': // quiet list of eval keys
		r_config_list (core->config, NULL, 'q');
		break;
	case '\0': // "e"
		r_config_list (core->config, NULL, 0);
		break;
	case 'c': // "ec"
		switch (input[1]) {
		case 'd':
			r_cons_pal_init (NULL);
			break;
		case '?': {
			const char *helpmsg[] = {
			"Usage ec[s?] [key][[=| ]fg] [bg]","","",
			"ec","","list all color keys",
			"ec*","","same as above, but using r2 commands",
			"ecd","","set default palette",
			"ecr","","set random palette",
			"ecs","","show a colorful palette",
			"ecj","","show palette in JSON",
			"ecc"," [prefix]","show palette in CSS",
			"eco"," dark|white","load white color scheme template",
			"ecp","","load previous color theme",
			"ecn","","load next color theme",
			"ec"," prompt red","change color of prompt",
			"ec"," prompt red blue","change color and background of prompt",
			""," ","",
			"colors:","","rgb:000, red, green, blue, ...",
			"e scr.rgbcolor","=1|0","for 256 color cube (boolean)",
			"e scr.truecolor","=1|0","for 256*256*256 colors (boolean)",
			"$DATADIR/radare2/cons","","~/.config/radare2/cons ./",
			NULL};
			r_core_cmd_help (core, helpmsg);
			}
			break;
		case 'o': // "eco"
			if (input[2] == 'j') {
				nextpal (core, 'j');
			} else if (input[2] == ' ') {
				bool failed = false;
				char *home, path[512];
				snprintf (path, sizeof (path), ".config/radare2/cons/%s", input + 3);
				home = r_str_home (path);
				snprintf (path, sizeof (path), R2_DATDIR"/radare2/"
					R2_VERSION"/cons/%s", input + 3);
				if (!load_theme (core, home)) {
					if (load_theme (core, path)) {
						//curtheme = r_str_dup (curtheme, path);
						curtheme = r_str_dup (curtheme, input + 3);
					} else {
						if (load_theme (core, input + 3)) {
							curtheme = r_str_dup (curtheme, input + 3);
						} else {
							eprintf ("eco: cannot open colorscheme profile (%s)\n", path);
							failed = true;
						}
					}
				}
				free (home);
				if (failed) {
					eprintf ("Something went wrong\n");
				}
			} else if (input[2] == '?') {
				eprintf ("Usage: eco [themename]  ;load theme from "R2_DATDIR"/radare2/"R2_VERSION"/cons/\n");

			} else {
				nextpal (core, 'l');
			}
			break;
		case 's': r_cons_pal_show (); break; // "ecs"
		case '*': r_cons_pal_list (1, NULL); break; // "ec*"
		case 'h': // echo
			if (( p = strchr (input, ' ') )) {
				r_cons_strcat (p+1);
				r_cons_newline ();
			} else {
				// "ech"
				r_cons_pal_list ('h', NULL);
			}
			break;
		case 'j': // "ecj"
			r_cons_pal_list ('j', NULL);
			break;
		case 'c': // "ecc"
			r_cons_pal_list ('c', input + 2);
			break;
		case '\0': // "ec"
			r_cons_pal_list (0, NULL);
			break;
		case 'r': // "ecr"
			r_cons_pal_random ();
			break;
		case 'n': // "ecn"
			nextpal (core, 'n');
			break;
		case 'p': // "ecp"
			nextpal (core, 'p');
			break;
		default: {
			char *p = strdup (input + 2);
			char *q = strchr (p, '=');
			if (!q) q = strchr (p, ' ');
			if (q) {
				// set
				*q++ = 0;
				r_cons_pal_set (p, q);
			} else {
				const char *k = r_cons_pal_get (p);
				if (k)
					eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k);
			}
			free (p);
		}
		}
		break;
	case 'e':
		if (input[1]==' ') {
			char *p;
			const char *val, *input2 = strchr (input+2, ' ');
			if (input2) input2++; else input2 = input+2;
			val = r_config_get (core->config, input2);
			p = r_core_editor (core, NULL, val);
			if (p) {
				r_str_replace_char (p, '\n', ';');
				r_config_set (core->config, input2, p);
			}
		} else eprintf ("Usage: ee varname\n");
		break;
	case '!':
		input = r_str_chop_ro (input+1);
		if (!r_config_toggle (core->config, input))
			eprintf ("r_config: '%s' is not a boolean variable.\n", input);
		break;
	case '-':
		r_core_config_init (core);
		//eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n");
		break;
	case '*': r_config_list (core->config, NULL, 1); break;
	case '?':
		switch (input[1]) {
		case '?': r_config_list (core->config, input+2, 2); break;
		default: r_config_list (core->config, input+1, 2); break;
		case 0:{
			const char* help_msg[] = {
			"Usage:", "e [var[=value]]", "Evaluable vars",
			"e","?asm.bytes", "show description",
			"e", "??", "list config vars with description",
			"ej", "", "list config vars in JSON",
			"e-", "", "reset config vars",
			"e*", "", "dump config vars in r commands",
			"e!", "a", "invert the boolean value of 'a' var",
			"ee", "var", "open editor to change the value of var",
			"er", " [key]", "set config key as readonly. no way back",
			"ec", " [k] [color]", "set color for given key (prompt, offset, ...)",
			"et", " [key]", "show type of given config variable",
			"ev", " [key]", "list config vars in verbose format",
			"evj", " [key]", "list config vars in verbose format in JSON",
			"e", " a", "get value of var 'a'",
			"e", " a=b", "set var 'a' the 'b' value",
			"e var=?", "", "print all valid values of var",
			"env", " [k[=v]]", "get/set environment variable",
			NULL};
			r_core_cmd_help (core, help_msg);
			}
		}
		break;
	case 'r':
		if (input[1]) {
			const char *key = input+((input[1]==' ')?2:1);
			if (!r_config_readonly (core->config, key))
				eprintf ("cannot find key '%s'\n", key);
		} else eprintf ("Usage: er [key]\n");
		break;
	case ' ': r_config_eval (core->config, input+1); break;
	default: r_config_eval (core->config, input); break;
	}
	return 0;
}
Exemple #14
0
static int cmd_eval(void *data, const char *input) {
	char *p;
	RCore *core = (RCore *)data;
	switch (input[0]) {
	case 't': // env
		if (input[1] == 'a') {
			r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son");
		} else if (input[1]==' ' && input[2]) {
			RConfigNode *node = r_config_node_get (core->config, input+2);
			if (node) {
				const char *type = r_config_node_type (node);
				if (type && *type) {
					r_cons_println (type);
				}
			}
		} else {
			eprintf ("Usage: et [varname]  ; show type of eval var\n");
		}
		break;
	case 'n': // env
		if (!strchr (input, '=')) {
			char *var, *p;
			var = strchr (input, ' ');
			if (var) while (*var==' ') var++;
			p = r_sys_getenv (var);
			if (p) {
				r_cons_println (p);
				free (p);
			} else {
				char **e = r_sys_get_environ ();
				while (e && *e) {
					r_cons_println (*e);
					e++;
				}
			}
		} else if (strlen (input)>3) {
			char *v, *k = strdup (input+3);
			if (!k) break;
			v = strchr (k, '=');
			if (v) {
				*v++ = 0;
				r_sys_setenv (k, v);
			}
			free (k);
		}
		return true;
	case 'x': // exit
		// XXX we need headers for the cmd_xxx files.
		return cmd_quit (data, "");
	case 'j': // json
		r_config_list (core->config, NULL, 'j');
		break;
	case 'v': // verbose
		r_config_list (core->config, input + 1, 'v');
		break;
	case 'q': // quiet list of eval keys
		r_config_list (core->config, NULL, 'q');
		break;
	case '\0': // "e"
		r_config_list (core->config, NULL, 0);
		break;
	case 'c': // "ec"
		switch (input[1]) {
		case 'd':
			r_cons_pal_init (NULL);
			break;
		case '?': {
			const char *helpmsg[] = {
			"Usage ec[s?] [key][[=| ]fg] [bg]","","",
			"ec","","list all color keys",
			"ec*","","same as above, but using r2 commands",
			"ecd","","set default palette",
			"ecr","","set random palette (see also scr.randpal)",
			"ecs","","show a colorful palette",
			"ecj","","show palette in JSON",
			"ecc"," [prefix]","show palette in CSS",
			"eco"," dark|white","load white color scheme template",
			"ecp","","load previous color theme",
			"ecn","","load next color theme",
			"ecH","[?]","highlight word or instruction",
			"ec"," prompt red","change color of prompt",
			"ec"," prompt red blue","change color and background of prompt",
			""," ","",
			"colors:","","rgb:000, red, green, blue, ...",
			"e scr.rgbcolor","=1|0","for 256 color cube (boolean)",
			"e scr.truecolor","=1|0","for 256*256*256 colors (boolean)",
			"$DATADIR/radare2/cons","","~/.config/radare2/cons ./",
			NULL};
			r_core_cmd_help (core, helpmsg);
			}
			break;
		case 'o': // "eco"
			if (input[2] == 'j') {
				nextpal (core, 'j');
			} else if (input[2] == ' ') {
				bool failed = false;
				char *home, path[512];
				snprintf (path, sizeof (path), ".config/radare2/cons/%s", input + 3);
				home = r_str_home (path);
				snprintf (path, sizeof (path), R2_DATDIR"/radare2/"
					R2_VERSION"/cons/%s", input + 3);
				if (!load_theme (core, home)) {
					if (load_theme (core, path)) {
						//curtheme = r_str_dup (curtheme, path);
						curtheme = r_str_dup (curtheme, input + 3);
					} else {
						if (load_theme (core, input + 3)) {
							curtheme = r_str_dup (curtheme, input + 3);
						} else {
							char *absfile = r_file_abspath (input + 3);
							eprintf ("eco: cannot open colorscheme profile (%s)\n", absfile);
							free (absfile);
							failed = true;
						}
					}
				}
				free (home);
				if (failed) {
					eprintf ("Something went wrong\n");
				}
			} else if (input[2] == '?') {
				eprintf ("Usage: eco [themename]  ;load theme from "R2_DATDIR"/radare2/"R2_VERSION"/cons/\n");

			} else {
				nextpal (core, 'l');
			}
			break;
		case 's': r_cons_pal_show (); break; // "ecs"
		case '*': r_cons_pal_list (1, NULL); break; // "ec*"
		case 'h': // echo
			if (( p = strchr (input, ' ') )) {
				r_cons_strcat (p+1);
				r_cons_newline ();
			} else {
				// "ech"
				r_cons_pal_list ('h', NULL);
			}
			break;
		case 'j': // "ecj"
			r_cons_pal_list ('j', NULL);
			break;
		case 'c': // "ecc"
			r_cons_pal_list ('c', input + 2);
			break;
		case '\0': // "ec"
			r_cons_pal_list (0, NULL);
			break;
		case 'r': // "ecr"
			r_cons_pal_random ();
			break;
		case 'n': // "ecn"
			nextpal (core, 'n');
			break;
		case 'p': // "ecp"
			nextpal (core, 'p');
			break;
		case 'H': { // "ecH"
			char *color_code = NULL;
			char *word = NULL;
			int argc = 0;
			char** argv = r_str_argv (input + 4, &argc);
			switch (input[2]) {
			case '?': {
				const char *helpmsg[] = {
					"Usage ecH[iw-?]","","",
					"ecHi","[color]","highlight current instruction with 'color' background",
					"ecHw","[word] [color]","highlight 'word ' in current instruction with 'color' background",
					"ecH-","","remove all highlights on current instruction",
					NULL
				};
				r_core_cmd_help (core, helpmsg);
				}
				break;
			case '-':
				r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, "");
				return false;
			case '\0':
			case 'i': // "ecHi
				if (argc) {
					char *dup = r_str_newf ("bgonly %s", argv[0]);
					color_code = r_cons_pal_parse (dup);
					R_FREE (dup);
				}
				break;
			case 'w': // "ecHw"
				if (!argc) {
					eprintf ("Usage: echw word [color]\n");
					r_str_argv_free (argv);
					return true;
				}
				word = strdup (argv[0]);
				if (argc > 1) {
					char *dup = r_str_newf ("bgonly %s", argv[1]);
					color_code = r_cons_pal_parse (dup);
					if (!color_code) {
						eprintf ("Unknown color %s\n", argv[1]);
						r_str_argv_free (argv);
						free (dup);
						free (word);
						return true;
					}
					R_FREE (dup);
				}
				break;
			default:
				eprintf ("See ecH?\n");
				r_str_argv_free (argv);
				return true;
			}
			char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset);
			char *dup = r_str_newf ("%s \"%s%s\"", str?str:"", word?word:"", color_code?color_code:r_cons_pal_get ("highlight"));
			r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, dup);
			r_str_argv_free (argv);
			R_FREE (word);
			R_FREE (dup);
			break;
		}
		default: {
			char *p = strdup (input + 2);
			char *q = strchr (p, '=');
			if (!q) {
				q = strchr (p, ' ');
			}
			if (q) {
				// set
				*q++ = 0;
				r_cons_pal_set (p, q);
			} else {
				const char *k = r_cons_pal_get (p);
				if (k) {
					eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k);
				}
			}
			free (p);
		}
		}
		break;
	case 'e':
		if (input[1] == ' ') {
			char *p;
			const char *val, *input2 = strchr (input+2, ' ');
			if (input2) input2++; else input2 = input+2;
			val = r_config_get (core->config, input2);
			p = r_core_editor (core, NULL, val);
			if (p) {
				r_str_replace_char (p, '\n', ';');
				r_config_set (core->config, input2, p);
			}
		} else {
			eprintf ("Usage: ee varname\n");
		}
		break;
	case '!':
		input = r_str_chop_ro (input+1);
		if (!r_config_toggle (core->config, input))
			eprintf ("r_config: '%s' is not a boolean variable.\n", input);
		break;
	case 's':
		r_config_list (core->config, (input[1])? input + 1: NULL, 's');
		break;
	case '-':
		r_core_config_init (core);
		//eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n");
		break;
	case '*': r_config_list (core->config, NULL, 1); break;
	case '?':
		switch (input[1]) {
		case '?': r_config_list (core->config, input+2, 2); break;
		default: r_config_list (core->config, input+1, 2); break;
		case 0:
			r_core_cmd_help (core, help_msg_e);
		}
		break;
	case 'r':
		if (input[1]) {
			const char *key = input+((input[1]==' ')?2:1);
			if (!r_config_readonly (core->config, key)) {
				eprintf ("cannot find key '%s'\n", key);
			}
		} else {
			eprintf ("Usage: er [key]\n");
		}
		break;
	case ' ': r_config_eval (core->config, input+1); break;
	default: r_config_eval (core->config, input); break;
	}
	return 0;
}
Exemple #15
0
static int stdprintiffunc (void *p, const char *k, const char *v) {
	if (!strncmp (v, "func", strlen ("func") + 1))
		r_cons_println (k);
	return 1;
}
Exemple #16
0
static int cmd_meta_comment(RCore *core, const char *input) {
	ut64 addr = core->offset;
	switch (input[1]) {
	case '?': {
		const char* help_msg[] = {
			"Usage:", "CC[-+!*au] [base64:..|str] @ addr", "",
			"CC", "", "list all comments in human friendly form",
			"CC*", "", "list all comments in r2 commands",
			"CC.", "", "show comment at current offset",
			"CC,", " [file]", "show or set comment file",
			"CC", " or maybe not", "append comment at current address",
			"CC+", " same as above", "append comment at current address",
			"CC!", "", "edit comment using cfg.editor (vim, ..)",
			"CC-", " @ cmt_addr", "remove comment at given address",
			"CCu", " good boy @ addr", "add good boy comment at given address",
			"CCu", " base64:AA== @ addr", "add comment in base64",
			NULL};
		r_core_cmd_help (core, help_msg);
		} break;
	case ',': // "CC,"
		if (input[2]=='?') {
			eprintf ("Usage: CC, [file]\n");
		} else if (input[2]==' ') {
			const char *fn = input+2;
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			while (*fn== ' ')fn++;
			if (comment && *comment) {
				// append filename in current comment
				char *nc = r_str_newf ("%s ,(%s)", comment, fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
				free (nc);
			} else {
				char *comment = r_str_newf (",(%s)", fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment);
				free (comment);
			}
		} else {
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			if (comment && *comment) {
				char *cmtfile = r_str_between (comment, ",(", ")");
				if (cmtfile && *cmtfile) {
					char *getcommapath(RCore *core);
					char *cwd = getcommapath (core);
					r_cons_printf ("%s"R_SYS_DIR"%s\n", cwd, cmtfile);
					free (cwd);
				}
				free (cmtfile);
			}
			free (comment);
		}
		break;
	case '.':
		  {
			  char *comment = r_meta_get_string (
					  core->anal, R_META_TYPE_COMMENT, addr);
			  if (comment) {
				  r_cons_println (comment);
				  free (comment);
			  }
		  }
		break;
	case 0:
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 0);
		break;
	case 'j':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 'j');
		break;
	case '!':
		{
			char *out, *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			out = r_core_editor (core, NULL, comment);
			if (out) {
				//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
				r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
				//r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL);
				r_meta_set_string (core->anal,
						R_META_TYPE_COMMENT, addr, out);
				free (out);
			}
			free (comment);
		}
		break;
	case '+':
	case ' ':
		{
		const char* newcomment = r_str_chop_ro (input + 2);
		char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
		char *nc = strdup (newcomment);
		r_str_unescape (nc);
		if (comment) {
			text = malloc (strlen (comment)+strlen (newcomment)+2);
			if (text) {
				strcpy (text, comment);
				strcat (text, "\n");
				strcat (text, nc);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text);
				free (text);
			} else {
				r_sys_perror ("malloc");
			}
		} else {
			r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
		}
		free (nc);
		}
		break;
	case '*':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 1);
		break;
	case '-': // "CC-"
		r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL);
		break;
	case 'u':
		//
		{
		char *newcomment;
		const char *arg = input + 2;
		while (*arg && *arg == ' ') arg++;
		if (!strncmp (arg, "base64:", 7)) {
			char *s = (char *)sdb_decode (arg+7, NULL);
			if (s) {
				newcomment = s;
			} else {
				newcomment = NULL;
			}
		} else {
			newcomment = strdup (arg);
		}
		if (newcomment) {
			char *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			if (!comment || (comment && !strstr (comment, newcomment))) {
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
						addr, newcomment);
			}
			free (comment);
			free (newcomment);
		}
		}
		break;
	case 'a':
		{
		char *s, *p;
		s = strchr (input, ' ');
		if (s) {
			s = strdup (s+1);
		} else {
			eprintf ("Usage\n");
			return false;
		}
		p = strchr (s, ' ');
		if (p) *p++ = 0;
		ut64 addr;
		if (input[2]=='-') {
			if (input[3]) {
				addr = r_num_math (core->num, input+3);
				r_meta_del (core->anal,
						R_META_TYPE_COMMENT,
						addr, 1, NULL);
			} else eprintf ("Usage: CCa-[address]\n");
			free (s);
			return true;
		}
		addr = r_num_math (core->num, s);
		// Comment at
		if (p) {
			if (input[2]=='+') {
				char *comment = r_meta_get_string (
						core->anal, R_META_TYPE_COMMENT,
						addr);
				if (comment) {
					char* text = r_str_newf ("%s\n%s", comment, p);
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, text);
					free (text);
				} else {
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, p);
				}
			} else {
				r_meta_add (core->anal,
						R_META_TYPE_COMMENT,
						addr, addr+1, p);
			}
		} else eprintf ("Usage: CCa [address] [comment]\n");
		free (s);
		return true;
		}
	}

	return true;
}
Exemple #17
0
static int stdprintifunion (void *p, const char *k, const char *v) {
	if (!strncmp (v, "union", strlen ("union") + 1))
		r_cons_println (k);
	return 1;
}
Exemple #18
0
void r_comment_vars(RCore *core, const char *input) {
	//TODO enable base64 and make it the default for C*
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
	int idx;
	char *oname = NULL, *name = NULL;
	char *oldcomment = NULL;
	char *heap_comment = NULL;
	RAnalVar *var;

	if (input[1] == '?' || (input[0] != 'b' && input[0] != 'r' && input[0] != 's') ) {
		r_comment_var_help (core, input[0]);
		return;
	}
	if (!fcn) {
		eprintf ("Cant find function here\n");
		return;
	}
	oname = name = strdup (input + 2);
	while (*name == ' ') {
		name++;
	}
	switch (input[1]) {
	case '*':
	case '\0': {
		RList *var_list;
		RListIter *iter;
		var_list = r_anal_var_list (core->anal, fcn, input[0]);
		r_list_foreach (var_list, iter, var) {
			oldcomment = r_meta_get_var_comment (core->anal, input[0], var->delta, fcn->addr);
			if (!oldcomment) {
				continue;
			}
			if (!input[1]) {
				r_cons_printf ("%s : %s\n", var->name, oldcomment);
			} else {
				r_cons_printf ("\"Cv%c %s base64:%s @ 0x%08"PFMT64x"\"\n", input[0], var->name,
					sdb_encode ((const ut8 *) oldcomment, strlen(oldcomment)), fcn->addr);
			}
		}
		}
		break;
	case ' ': {
		// TODO check that idx exist
		char *comment = strstr (name, " ");
		if (comment) { // new comment given
			if (*comment) {
				*comment++ = 0;
			}
			if (!strncmp (comment, "base64:", 7)) {
				heap_comment = (char *)sdb_decode (comment + 7, NULL);
				comment = heap_comment;
			}
		}
		var = r_anal_var_get_byname (core->anal, fcn, name);
		if (var) {
			idx = var->delta;
		} else if (!strncmp (name, "0x", 2))  {
			idx = (int) r_num_get (NULL, name);
		} else if (!strncmp (name, "-0x", 3)) {
			idx = -(int) r_num_get (NULL, name+1);
		} else {
			eprintf ("cant find variable named `%s`\n",name);
			free (heap_comment);
			break;
		}
		r_anal_var_free (var);
		if (!r_anal_var_get (core->anal, fcn->addr, input[0], 1, idx)) {
			eprintf ("cant find variable at given offset\n");
		} else {
			oldcomment = r_meta_get_var_comment (core->anal, input[0], idx, fcn->addr);
			if (oldcomment) {
				if (comment && *comment) {
					char *text = r_str_newf ("%s\n%s", oldcomment, comment);
					r_meta_set_var_comment (core->anal, input[0], idx, fcn->addr, text);
					free (text);
				} else {
					r_cons_println (oldcomment);
				}
			} else {
				r_meta_set_var_comment (core->anal, input[0], idx, fcn->addr, comment);
			}
		}
		free (heap_comment);
		}
		break;
	case '-':
		var = r_anal_var_get_byname (core->anal,fcn, name);
		if (var) {
			idx = var->delta;
		} else if (!strncmp (name, "0x", 2)) {
			idx = (int) r_num_get (NULL, name);
		} else if (!strncmp (name, "-0x", 3)) {
			idx = -(int) r_num_get (NULL, name+1);
		 }else {
			eprintf ("cant find variable named `%s`\n",name);
			break;
		}
		r_anal_var_free (var);
		//XXX TODO here we leak a var
		if (!r_anal_var_get (core->anal, fcn->addr, input[0],1,idx)) {
			eprintf ("cant find variable at given offset\n");
			break;
		}
		r_meta_var_comment_del (core->anal, input[0], idx, fcn->addr);
		break;
	case '!': {
		char *comment;
		var = r_anal_var_get_byname (core->anal,fcn, name);
		if (!var) {
			eprintf ("cant find variable named `%s`\n",name);
			break;
		}
		oldcomment = r_meta_get_var_comment (core->anal, input[0], var->delta, fcn->addr);
		comment = r_core_editor (core, NULL, oldcomment);
		if (comment) {
			r_meta_var_comment_del (core->anal, input[0], var->delta, fcn->addr);
			r_meta_set_var_comment (core->anal, input[0], var->delta, fcn->addr, comment);
			free (comment);
		}
		r_anal_var_free (var);
		}
		break;
	}
Exemple #19
0
R_API int r_cons_grepbuf(char *buf, int len) {
	RCons *cons = r_cons_singleton ();
	char *tline, *tbuf, *p, *out, *in = buf;
	int ret, total_lines = 0, buffer_len = 0, l = 0, tl = 0;
	bool show = false;
	if (cons->filter) {
		cons->buffer_len = 0;
		R_FREE (cons->buffer);
		return 0;
	}

	if ((!len || !buf || buf[0] == '\0') &&
	    (cons->grep.json || cons->grep.less)) {
		cons->grep.json = 0;
		cons->grep.less = 0;
		return 0;
	}
	if (cons->grep.json) {
		if (cons->grep.json_path) {
			char *u = sdb_json_get_str (cons->buffer, cons->grep.json_path);
			if (u) {
				cons->buffer = u;
				cons->buffer_len = strlen (u);
				cons->buffer_sz = cons->buffer_len + 1;
				cons->grep.json = 0;
				r_cons_newline ();
			}
			R_FREE (cons->grep.json_path);
		} else {
			const char *palette[] = {
				cons->pal.graph_false, // f
				cons->pal.graph_true, // t
				cons->pal.num, // k
				cons->pal.comment, // v
				Color_RESET,
				NULL
			};
			char *out = r_print_json_indent (buf, I (color), "  ", palette);
			if (!out) {
				return 0;
			}
			free (cons->buffer);
			cons->buffer = out;
			cons->buffer_len = strlen (out);
			cons->buffer_sz = cons->buffer_len + 1;
			cons->grep.json = 0;
			if (cons->grep.less) {
				cons->grep.less = 0;
				r_cons_less_str (cons->buffer, NULL);
			}
		}
		return 3;
	}
	if (cons->grep.less) {
		int less = cons->grep.less;
		cons->grep.less = 0;
		if (less == 2) {
			char *res = r_cons_hud_string (buf);
			r_cons_println (res);
			free (res);
		} else {
			r_cons_less_str (buf, NULL);
			buf[0] = 0;
			cons->buffer_len = 0;
			if (cons->buffer) {
				cons->buffer[0] = 0;
			}
			R_FREE (cons->buffer);
		}
		return 0;
	}
	if (!cons->buffer) {
		cons->buffer_len = len + 20;
		cons->buffer = malloc (cons->buffer_len);
		cons->buffer[0] = 0;
	}
	out = tbuf = calloc (1, len);
	if (!out) {
		return 0;
	}
	tline = malloc (len);
	if (!tline) {
		free (out);
		return 0;
	}
	cons->lines = 0;
	// used to count lines and change negative grep.line values
	while ((int) (size_t) (in - buf) < len) {
		p = strchr (in, '\n');
		if (!p) {
			break;
		}
		l = p - in;
		if (l > 0) {
			in += l + 1;
		} else {
			in++;
		}
		total_lines++;
	}
	if (!cons->grep.range_line && cons->grep.line < 0) {
		cons->grep.line = total_lines + cons->grep.line;
	}
	if (cons->grep.range_line == 1) {
		if (cons->grep.f_line < 0) {
			cons->grep.f_line = total_lines + cons->grep.f_line;
		}
		if (cons->grep.l_line < 0) {
			cons->grep.l_line = total_lines + cons->grep.l_line;
		}
	}
	in = buf;
	while ((int) (size_t) (in - buf) < len) {
		p = strchr (in, '\n');
		if (!p) {
			free (tbuf);
			free (tline);
			return 0;
		}
		l = p - in;
		if (l > 0) {
			memcpy (tline, in, l);
			if (cons->grep_color) {
				tl = l;
			} else {
				tl = r_str_ansi_filter (tline, NULL, NULL, l);
			}
			if (tl < 0) {
				ret = -1;
			} else {
				ret = r_cons_grep_line (tline, tl);
				if (!cons->grep.range_line) {
					if (cons->grep.line == cons->lines) {
						show = true;
					}
				} else if (cons->grep.range_line == 1) {
					if (cons->grep.f_line == cons->lines) {
						show = true;
					}
					if (cons->grep.l_line == cons->lines) {
						show = false;
					}
				} else {
					show = true;
				}
			}
			if (ret > 0) {
				if (show) {
					memcpy (out, tline, ret);
					memcpy (out + ret, "\n", 1);
					out += ret + 1;
					buffer_len += ret + 1;
				}
				if (!cons->grep.range_line) {
					show = false;
				}
				cons->lines++;
			} else if (ret < 0) {
				free (tbuf);
				free (tline);
				return 0;
			}
			in += l + 1;
		} else {
			in++;
		}
	}
	memcpy (buf, tbuf, len);
	cons->buffer_len = buffer_len;
	free (tbuf);
	free (tline);
	if (cons->grep.counter) {
		int cnt = cons->grep.charCounter? strlen (cons->buffer): cons->lines;
		if (cons->buffer_len < 10) {
			cons->buffer_len = 10; // HACK
		}
		snprintf (cons->buffer, cons->buffer_len, "%d\n", cnt);
		cons->buffer_len = strlen (cons->buffer);
		cons->num->value = cons->lines;
	}
	if (cons->grep.sort != -1) {
#define INSERT_LINES(list)\
	do {\
		r_list_foreach (list, iter, str) {\
			int len = strlen (str);\
			memcpy (ptr, str, len);\
			memcpy (ptr + len, "\n", 2);\
			ptr += len + 1;\
			nl++;\
		}\
	}\
	while (false)

		RListIter *iter;
		int nl = 0;
		char *ptr = cons->buffer;
		char *str;
		sorted_column = cons->grep.sort;
		r_list_sort (sorted_lines, cmp);
		if (cons->grep.sort_invert) {
			r_list_reverse (sorted_lines);
		}
		INSERT_LINES (unsorted_lines);
		INSERT_LINES (sorted_lines);
		cons->lines = nl;
		r_list_free (sorted_lines);
		sorted_lines = NULL;
		r_list_free (unsorted_lines);
		unsorted_lines = NULL;
	}
	return cons->lines;
}
Exemple #20
0
static int cmd_eval(void *data, const char *input) {
	RCore *core = (RCore *)data;
	switch (input[0]) {
	case '\0': // "e"
		r_config_list (core->config, NULL, 0);
		break;
	case '?': // "e?"
	default:
		switch (input[1]) {
		case '\0': r_core_cmd_help (core, help_msg_e); break;
		case '?': r_config_list (core->config, input + 2, 2); break;
		default: r_config_list (core->config, input + 1, 2); break;
		}
		break;
	case 't': // "et"
		if (input[1] == 'a') {
			r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son");
		} else if (input[1]==' ' && input[2]) {
			RConfigNode *node = r_config_node_get (core->config, input+2);
			if (node) {
				const char *type = r_config_node_type (node);
				if (type && *type) {
					r_cons_println (type);
				}
			}
		} else {
			eprintf ("Usage: et [varname]  ; show type of eval var\n");
		}
		break;
	case 'n': // "en"
		if (!strchr (input, '=')) {
			char *var, *p;
			var = strchr (input, ' ');
			if (var) while (*var==' ') var++;
			p = r_sys_getenv (var);
			if (p) {
				r_cons_println (p);
				free (p);
			} else {
				char **e = r_sys_get_environ ();
				while (e && *e) {
					r_cons_println (*e);
					e++;
				}
			}
		} else if (strlen (input)>3) {
			char *v, *k = strdup (input+3);
			if (!k) break;
			v = strchr (k, '=');
			if (v) {
				*v++ = 0;
				r_sys_setenv (k, v);
			}
			free (k);
		}
		return true;
	case 'x': // exit
		// XXX we need headers for the cmd_xxx files.
		return cmd_quit (data, "");
	case 'j': // json
		r_config_list (core->config, NULL, 'j');
		break;
	case 'v': // verbose
		r_config_list (core->config, input + 1, 'v');
		break;
	case 'q': // quiet list of eval keys
		r_config_list (core->config, NULL, 'q');
		break;
	case 'c': // "ec"
		switch (input[1]) {
		case 'd': // "ecd"
			r_cons_pal_init (core->cons->context);
			break;
		case '?':
			r_core_cmd_help (core, help_msg_ec);
			break;
		case 'o': // "eco"
			if (input[2] == 'j') {
				nextpal (core, 'j');
			} else if (input[2] == ' ') {
				cmd_load_theme (core, input + 3);
			} else if (input[2] == 'o') {
				cmd_load_theme (core, r_core_get_theme ());
			} else if (input[2] == 'c' || input[2] == '.') {
				r_cons_printf ("%s\n", r_core_get_theme ());
			} else if (input[2] == '?') {
				r_core_cmd_help (core, help_msg_eco);
			} else if (input[2] == 'q') {
				RList *themes_list = r_core_list_themes (core);
				RListIter *th_iter;
				const char *th;
				r_list_foreach (themes_list, th_iter, th) {
					r_cons_printf ("%s\n", th);
				}
			} else {