Example #1
0
R_API int r_core_bin_set_env (RCore *r, RBinFile *binfile) {
	RBinObject *binobj = binfile ? binfile->o: NULL;
	RBinInfo *info = binobj ? binobj->info: NULL;
	if (info) {
		int va = info->has_va;
		const char * arch = info->arch;
		ut16 bits = info->bits;
		ut64 loadaddr = r_config_get_i (r->config, "bin.laddr");
		ut64 baseaddr = binobj->baddr;
		/* Hack to make baddr work on some corner */
		r_config_set_i (r->config, "io.va",
			(binobj->info)? binobj->info->has_va: 0);
		r_config_set_i (r->config, "bin.laddr", loadaddr);
		r_config_set_i (r->config, "bin.baddr", baseaddr);
		r_config_set (r->config, "asm.arch", arch);
		r_config_set_i (r->config, "asm.bits", bits);
		r_config_set (r->config, "anal.arch", arch);
		if (strlen(info->cpu))
			r_config_set (r->config, "anal.cpu", info->cpu);
		else	r_config_set (r->config, "anal.cpu", arch);
		r_asm_use (r->assembler, arch);

		r_core_bin_info (r, R_CORE_BIN_ACC_ALL, R_CORE_BIN_SET,
			va, NULL, loadaddr, NULL);
		r_core_bin_set_cur (r, binfile);
		return R_TRUE;
	}
	return R_FALSE;
}
Example #2
0
R_API RAnalHint *r_core_hint_begin (RCore *core, RAnalHint* hint, ut64 at) {
// XXX not here
	static char *hint_arch = NULL;
	static int hint_bits = 0;
	if (hint) {
		r_anal_hint_free (hint);
		hint = NULL;
	}
	hint = r_anal_hint_get (core->anal, at);
	if (hint_arch) {
		r_config_set (core->config, "asm.arch", hint_arch);
		hint_arch = NULL;
	}
	if (hint_bits) {
		r_config_set_i (core->config, "asm.bits", hint_bits);
		hint_bits = 0;
	}
	if (hint) {
		/* arch */
		if (hint->arch) {
			if (!hint_arch) hint_arch = strdup (
				r_config_get (core->config, "asm.arch"));
			r_config_set (core->config, "asm.arch", hint->arch);
		}
		/* bits */
		if (hint->bits) {
			if (!hint_bits) hint_bits =
				r_config_get_i (core->config, "asm.bits");
			r_config_set_i (core->config, "asm.bits", hint->bits);
		}
	}
	return hint;
}
Example #3
0
static void setdiff (RCore *core) {
	char from[64], to[64];
	prompt_read ("diff from: ", from, sizeof (from));
	r_config_set (core->config, "diff.from", from);
	prompt_read ("diff to: ", to, sizeof (to));
	r_config_set (core->config, "diff.to", to);
}
Example #4
0
File: cio.c Project: f0829/radare2
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach) {
	int pid, *p = NULL;
	bool is_gdb = !strcmp (debugbackend, "gdb");
	RIODesc * fd = r->file ? r_io_desc_get (r->io, r->file->fd) : NULL;
	const char *prompt = NULL;

	p = fd ? fd->data : NULL;
	r_config_set_i (r->config, "cfg.debug", 1);
	if (!p) {
		eprintf ("Invalid debug io\n");
		return false;
	}

	r_config_set (r->config, "io.ff", "true");
	r_core_cmdf (r, "dL %s", debugbackend);
	if (!is_gdb) {
		pid = r_io_desc_get_pid (fd);
		r_core_cmdf (r, "dp=%d", pid);
		if (attach) {
			r_core_cmdf (r, "dpa %d", pid);
		}
	}
	//this makes to attach twice showing warnings in the output
	//we get "resource busy" so it seems isn't an issue
	r_core_cmd (r, ".dr*", 0);
	/* honor dbg.bep */
	{
		const char *bep = r_config_get (r->config, "dbg.bep");
		if (bep) {
			if (!strcmp (bep, "loader")) {
				/* do nothing here */
			} else if (!strcmp (bep, "entry")) {
				r_core_cmd (r, "dcu entry0", 0);
			} else {
				r_core_cmdf (r, "dcu %s", bep);
			}
		}
	}
	r_core_cmd (r, "sr PC", 0);

	/* set the prompt if it's not been set already by the callbacks */
	prompt = r_config_get (r->config, "cmd.prompt");
	if (prompt && !strcmp (prompt, "")) {
		if (r_config_get_i (r->config, "dbg.status")) {
			r_config_set (r->config, "cmd.prompt", ".dr*;drd;sr PC;pi 1;s-");
		} else {
			r_config_set (r->config, "cmd.prompt", ".dr*");
		}
	}
	r_config_set (r->config, "cmd.vprompt", ".dr*");
	return true;
}
static int cmd_quit(void *data, const char *input) {
	RCore *core = (RCore *)data;
	const char* help_msg[] = {
		"Usage:",  "q[!][!] [retval]", "",
		"q","","quit program",
		"q!","","force quit (no questions)",
		"q!!","","force quit without saving history",
		"q"," 1","quit with return value 1",
		"q"," a-b","quit with return value a-b",
		NULL};
	if (input)
	switch (*input) {
	case '?':
		r_core_cmd_help (core, help_msg);
		break;
	case '!':
		if (input[1] == '!')
			r_config_set (core->config, "scr.histsave", "false");
		core->num->value = -1;
		return -2;
	case '\0':
		core->num->value = 0LL;
		return -2;
	default:
		if (*input == ' ')
			input++;
		if (*input)
			r_num_math (core->num, input);
		else core->num->value = 0LL;
		//exit (*input?r_num_math (core->num, input+1):0);
		//if (core->http_up) return R_FALSE; // cancel quit when http is running
		return -2;
	}
	return R_FALSE;
}
Example #6
0
static int cmd_project(void *data, const char *input) {
	RCore *core = (RCore *)data;
	const char *file, *arg = input+1;
	char *str = strdup (r_config_get (core->config, "file.project"));
	if (*arg==' ') arg++;
	file = input[1]?arg:str;
	switch (input[0]) {
	case 'o':
	//	if (r_file_is_regular (file))
		r_core_project_open (core, file);
		break;
	case 's':
		r_core_project_save (core, file);
		r_config_set (core->config, "file.project", file);
		break;
	case 'i':
//		if (r_file_is_regular (file))
		free (r_core_project_info (core, file));
		break;
	default:
		r_cons_printf (
		"|Usage: P[?osi] [file]\n"
		"| Po [file]  open project\n"
		"| Ps [file]  save project\n"
		"| Pi [file]  show project information\n"
		"|NOTE: See 'e file.project'\n"
		"|NOTE: project files are stored in ~/.config/radare2/rdb\n");
		break;
	}
	free (str);
	return R_TRUE;
}
Example #7
0
static int config_dbgbackend_callback(void *user, void *data) {
	RCore *core = (RCore*) user;
	RConfigNode *node = (RConfigNode*) data;
	// XXX: remove this spagetti
	if (!strcmp (node->value, "bf"))
		r_config_set (core->config, "asm.arch", "bf");
	r_debug_use (core->dbg, node->value);
	return R_TRUE;
}
Example #8
0
static bool r_anal_emul_init(RCore *core, bool *state) {
	state[ROMEM] = r_config_get_i (core->config, "esil.romem");
	r_config_set (core->config, "esil.romem", "true");
	state[ASM_TRACE] = r_config_get_i (core->config, "asm.trace");
	r_config_set (core->config, "asm.trace", "true");
	state[ANAL_TRACE] = r_config_get_i (core->config, "anal.trace");
	r_config_set (core->config, "anal.trace", "true");
	state[DBG_TRACE] = r_config_get_i (core->config, "dbg.trace");
	r_config_set (core->config, "dbg.trace", "true");
	state[NONULL] = r_config_get_i (core->config, "esil.nonull");
	r_config_set (core->config, "esil.nonull", "true");
	const char *bp = r_reg_get_name (core->anal->reg, R_REG_NAME_BP);
	const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
	if ((bp && !r_reg_getv (core->anal->reg, bp)) || (sp && !r_reg_getv (core->anal->reg, sp))) {
		eprintf ("Stack isn't initiatized.\n");
		eprintf ("Try running aei and aeim commands before aftm for default stack initialization\n");
		return false;
	}
	return (core->anal->esil != NULL);
}
Example #9
0
static int config_asmarch_callback(void *user, void *data) {
	RCore *core = (RCore *) user;
	RConfigNode *node = (RConfigNode *) data;
	const char *asmos = r_config_get (core->config, "asm.os");
	r_egg_setup (core->egg, node->value, core->anal->bits, 0, R_SYS_OS);
	if (!r_asm_use (core->assembler, node->value))
		eprintf ("asm.arch: cannot find (%s)\n", node->value);
	if (!r_config_set (core->config, "anal.plugin", node->value)) {
		char *p, *s = strdup (node->value);
		p = strchr (s, '.');
		if (p) *p = 0;
		r_config_set (core->config, "anal.plugin", s);
		free (s);
	}
	if (!r_syscall_setup (core->anal->syscall, node->value,
			asmos, core->anal->bits)) {
		//eprintf ("asm.arch: Cannot setup syscall '%s/%s' from '%s'\n",
		//	node->value, asmos, R2_LIBDIR"/radare2/"R2_VERSION"/syscall");
	}
	//if (!strcmp (node->value, "bf"))
	//	r_config_set (core->config, "dbg.backend", "bf");
	return R_TRUE;
}
Example #10
0
File: cio.c Project: f0829/radare2
R_API void r_core_seek_archbits(RCore *core, ut64 addr) {
	int bits = 0;
	const char *arch = r_io_section_get_archbits (core->io, addr, &bits);
	if (!bits && !core->fixedbits) {
		//if we found bits related with anal hints pick it up
		__choose_bits_anal_hints (core, addr, &bits);
	}
	if (bits && !core->fixedbits) {
		r_config_set_i (core->config, "asm.bits", bits);
	}
	if (arch && !core->fixedarch) {
		r_config_set (core->config, "asm.arch", arch);
	}
}
Example #11
0
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
	RIOSection *newsection;
	ut64 old = core->offset;
	ut64 ret;

	/* XXX unnecesary call */
	//r_io_set_fd (core->io, core->file->fd);
	core->io->section = core->section; // HACK
	ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	newsection = core->io->section;

	if (ret == UT64_MAX) {
		//eprintf ("RET =%d %llx\n", ret, addr);
		/*
		   XXX handle read errors correctly
		   if (core->ffio) {
		   core->offset = addr;
		   } else return R_FALSE;
		 */
		//core->offset = addr;
		if (!core->io->va)
			return R_FALSE;
		memset (core->block, 0xff, core->blocksize);
	} else core->offset = addr;
	if (rb) {
		ret = r_core_block_read (core, 0);
		if (core->ffio) {
			if (ret<1 || ret > core->blocksize)
				memset (core->block, 0xff, core->blocksize);
			else memset (core->block+ret, 0xff, core->blocksize-ret);
			ret = core->blocksize;
			core->offset = addr;
		} else {
			if (ret<1) {
				core->offset = old;
				//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
			}
		}
	}
	if (core->section != newsection) {//&& core->io->section->arch) {
		int bits = 0;// = core->io->section->bits;
		const char *arch = r_io_section_get_archbits (core->io, core->offset, &bits);
		if (arch && bits) {
			r_config_set (core->config, "asm.arch", arch);
			r_config_set_i (core->config, "asm.bits", bits);
		}
		core->section = core->io->section;
	}
	return (ret==-1)? R_FALSE: R_TRUE;
}
Example #12
0
static int textlog_chat(RCore *core) {
	char prompt[64];
	char buf[1024];
	int lastmsg = 0;
	const char *me = r_config_get (core->config, "cfg.user");
	char msg[1024];

	eprintf ("Type '/help' for commands:\n");
	snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me);
	r_line_set_prompt (prompt);
	for (;;) {
		r_core_log_list (core, lastmsg, 0, 0);
		lastmsg = core->log->last;
		if (r_cons_fgets (buf, sizeof (buf) - 1, 0, NULL) < 0) {
			return 1;
		}
		if (!*buf) {
			continue;
		}
		if (!strcmp (buf, "/help")) {
			eprintf ("/quit           quit the chat (same as ^D)\n");
			eprintf ("/name <nick>    set cfg.user name\n");
			eprintf ("/log            show full log\n");
			eprintf ("/clear          clear text log messages\n");
		} else if (!strncmp (buf, "/name ", 6)) {
			snprintf (msg, sizeof (msg) - 1, "* '%s' is now known as '%s'", me, buf + 6);
			r_core_log_add (core, msg);
			r_config_set (core->config, "cfg.user", buf + 6);
			me = r_config_get (core->config, "cfg.user");
			snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me);
			r_line_set_prompt (prompt);
			return 0;
		} else if (!strcmp (buf, "/log")) {
			r_core_log_list (core, 0, 0, 0);
			return 0;
		} else if (!strcmp (buf, "/clear")) {
			// r_core_log_del (core, 0);
			r_core_cmd0 (core, "T-");
			return 0;
		} else if (!strcmp (buf, "/quit")) {
			return 0;
		} else if (*buf == '/') {
			eprintf ("Unknown command: %s\n", buf);
		} else {
			snprintf (msg, sizeof (msg) - 1, "[%s] %s", me, buf);
			r_core_log_add (core, msg);
		}
	}
	return 1;
}
Example #13
0
static int config_cfgdebug_callback(void *user, void *data) {
	RCore *core = (RCore*) user;
	RConfigNode *node = (RConfigNode*) data;
	if (!core) return R_FALSE;
	if (core->io)
		core->io->debug = node->i_value;
	if (core->dbg && node->i_value) {
		const char *dbgbackend = r_config_get (core->config, "dbg.backend");
		r_debug_use (core->dbg, dbgbackend);
		if (!strcmp (dbgbackend, "bf"))
			r_config_set (core->config, "asm.arch", "bf");
		if (core->file) {
			r_debug_select (core->dbg, core->file->fd->fd, core->file->fd->fd);
		}
	} else r_debug_use (core->dbg, NULL);
	return R_TRUE;
}
Example #14
0
R_API void r_core_seek_archbits(RCore *core, ut64 addr) {
	int bits = 0;
	const char *arch = NULL;
	RBinObject *o = r_bin_cur_object (core->bin);
	RBinSection *s = o? r_bin_get_section_at (o, addr, core->io->va): NULL;
	if (s) {
		arch = s->arch;
		bits = s->bits;
	}
	if (!bits && !core->fixedbits) {
		//if we found bits related with anal hints pick it up
		__choose_bits_anal_hints (core, addr, &bits);
	}
	if (bits && !core->fixedbits) {
		r_config_set_i (core->config, "asm.bits", bits);
	}
	if (arch && !core->fixedarch) {
		r_config_set (core->config, "asm.arch", arch);
	}
}
Example #15
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]==' ' && 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_printf ("%s\n", 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_printf ("%s\n", p);
				free (p);
			} else {
				char **e = r_sys_get_environ ();
				while (e && *e) {
					r_cons_printf ("%s\n", *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
		return cmd_quit (data, "");
	case 'j':
		r_config_list (core->config, NULL, 'j');
		break;
	case '\0':
		r_config_list (core->config, NULL, 0);
		break;
	case 'c':
		switch (input[1]) {
		case 'h': // echo
			if (( p = strchr (input, ' ') )) {
				r_cons_strcat (p+1);
				r_cons_newline ();
			}
			break;
		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","","show palette in CSS",
			"eco"," dark|white","load white color scheme template",
			"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] == ' ') {
				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 (!r_core_cmd_file (core, home)) {
					if (r_core_cmd_file (core, path)) {
						//curtheme = r_str_dup (curtheme, path);
						curtheme = r_str_dup (curtheme, input + 3);
					} else {
						if (r_core_cmd_file (core, input+3)) {
							curtheme = r_str_dup (curtheme, input + 3);
						} else {
							eprintf ("eco: cannot open colorscheme profile (%s)\n", path);
							failed = true;
						}
					}
				}
				free (home);
			} else {
				nextpal (core, 'l');
			}
			break;
		case 's': r_cons_pal_show (); break;
		case '*': r_cons_pal_list (1); break;
		case 'j': r_cons_pal_list ('j'); break;
		case 'c': r_cons_pal_list ('c'); break;
		case '\0': r_cons_pal_list (0); break;
		case 'r': // "ecr"
			r_cons_pal_random ();
			break;
		case 'n': // "ecn"
			nextpal (core, 'n');
			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 'v': eprintf ("Invalid command '%s'. Use 'e?'\n", input); 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",
			"e", "", "list config vars",
			"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",
			"e", " a", "get value of var 'a'",
			"e", " a=b", "set var 'a' the 'b' value",
			"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;
}
Example #16
0
R_API int r_core_config_init(RCore *core) {
	int i;
	char buf[128], *p;
	RConfig *cfg = cfg = core->config = r_config_new (core);
	cfg->printf = r_cons_printf;
	cfg->num = core->num;

	r_config_set (cfg, "dir.source", "");
	r_config_desc (cfg, "dir.source", "Path to find source files");
	r_config_set (cfg, "dir.magic", R_MAGIC_PATH);
	r_config_desc (cfg, "dir.magic", "Path to r_magic files");
	r_config_set (cfg, "dir.plugins", LIBDIR"/radare2/"R2_VERSION"/");
	r_config_desc (cfg, "dir.plugins", "Path to plugin files to be loaded at startup");
	/* anal */
	r_config_set (cfg, "anal.prelude", "");
	r_config_desc (cfg, "anal.prelude", "Specify an hexpair to find preludes in code");
	r_config_set_i (cfg, "anal.depth", 50); // XXX: warn if depth is > 50 .. can be problematic
	r_config_desc (cfg, "anal.depth", "Max depth at code analysis");
	r_config_set_i (cfg, "anal.ptrdepth", 3);
	r_config_set_cb (cfg, "anal.split", "true", &config_analsplit_callback);
	r_config_set_cb (cfg, "anal.plugin", R_SYS_ARCH, &config_analplugin_callback);
	r_config_desc (cfg, "anal.plugin", "Specify the anal plugin to use");
	/* asm */
	r_config_set_cb (cfg, "asm.arch", R_SYS_ARCH, &config_asmarch_callback);
	r_config_desc (cfg, "asm.arch", "Set the arch to be usedd by asm");
	// XXX: not portable
	r_parse_use (core->parser, "x86.pseudo");
	r_config_set_cb (cfg, "asm.parser", "x86.pseudo", &config_asmparser_callback);
	r_config_set_i_cb (cfg, "asm.bits", 32, &config_asmbits_callback);
	r_config_desc (cfg, "asm.bits", "Word size in bits at assembler");
	r_config_set (cfg, "asm.bytes", "true");
	r_config_desc (cfg, "asm.bytes", "Display the bytes of each instruction");
	r_config_set (cfg, "asm.flags", "true");
	r_config_desc (cfg, "asm.bytes", "Show flags in disassembly (pd)");
	r_config_set (cfg, "asm.size", "false");
	r_config_desc (cfg, "asm.size", "Show size of opcodes in disassembly (pd)");
	r_config_set (cfg, "asm.lbytes", "true");
	r_config_desc (cfg, "asm.lbytes", "Align disasm bytes to left");
	r_config_set (cfg, "asm.middle", "false"); // jump in the middle because of antidisasm tricks
	r_config_set (cfg, "asm.comments", "true");
	r_config_desc (cfg, "asm.comments", "Show comments in disassembly view");
	r_config_set (cfg, "asm.cmtright", "true");
	r_config_desc (cfg, "asm.cmtright", "Show comments at right of disassembly if they fit in screen");
	r_config_set (cfg, "asm.ucase", "false");
	r_config_desc (cfg, "asm.ucase", "Use uppercase syntax at disassembly");
	r_config_set (cfg, "asm.stackptr", "false");
	r_config_desc (cfg, "asm.stackptr", "Show stack pointer at disassembly");
	r_config_set (cfg, "asm.dwarf", "false");
	r_config_desc (cfg, "asm.dwarf", "Show dwarf comment at disassembly");
	r_config_set_i (cfg, "asm.nbytes", 8);
	r_config_set (cfg, "asm.tabs", "false");
	r_config_desc (cfg, "asm.nbytes", "Number of bytes for each opcode at disassembly");
	r_config_set (cfg, "asm.pseudo", "false");  // DEPRECATED ???
	r_config_desc (cfg, "asm.pseudo", "Enable pseudo syntax");
	r_config_set (cfg, "asm.filter", "true");
	r_config_desc (cfg, "asm.filter", "Show filtered flags at disassembly");
	r_config_set (cfg, "asm.varsub", "true");
	r_config_desc (cfg, "asm.varsub", "Substitute variables in disasm");
	r_config_set (cfg, "asm.trace", "true");
	r_config_desc (cfg, "asm.trace", "Show execution traces for each opcode");
	r_config_set (cfg, "asm.decode", "false");
	r_config_desc (cfg, "asm.decode", "Use code analysis as a disassembler");
	r_config_set (cfg, "asm.offset", "true");
	r_config_desc (cfg, "asm.offset", "Show offsets at disassembly");
	r_config_set (cfg, "asm.offseg", "false");
	r_config_desc (cfg, "asm.offseg", "Show offsets as in 16 bit segment addressing mode");
	r_config_set (cfg, "asm.lines", "true");
	r_config_desc (cfg, "asm.lines", "If enabled show ascci-art lines at disassembly");
	r_config_set (cfg, "asm.linesout", "true");
	r_config_desc (cfg, "asm.linesout", "If enabled show out of block lines");
	r_config_set (cfg, "asm.linesstyle", "false");
	r_config_desc (cfg, "asm.linesstyle", "If enabled iterate the jump list backwards");
	r_config_set (cfg, "asm.lineswide", "false");
	r_config_desc (cfg, "asm.lineswide", "If enabled put an space between lines");
	r_config_set_i_cb (cfg, "asm.lineswidth", 10, &config_asmlineswidth_callback);
	r_config_desc (cfg, "asm.lineswidth", "");
	r_config_set (cfg, "asm.linescall", "false");
	r_config_desc (cfg, "asm.linescall", "Enable call lines");
	r_config_set_cb (cfg, "asm.os", R_SYS_OS, &config_asmos_callback);
	r_config_desc (cfg, "asm.os", "Select operating system (kernel) (linux, darwin, w32,..)");
	r_config_set_cb (cfg, "asm.syntax", "intel", &config_asmsyntax_callback);
	r_config_desc (cfg, "asm.syntax", "Select assembly syntax");
	r_config_set_cb (cfg, "asm.profile", "default", &config_asmprofile_callback);
	r_config_desc (cfg, "asm.profile", "configure disassembler (default, simple, gas, smart, debug, full)");
	/* misc */
#if LIL_ENDIAN
	r_config_set_cb (cfg, "cfg.bigendian", "false", &config_bigendian_callback);
#else
	r_config_set_cb (cfg, "cfg.bigendian", "true", &config_bigendian_callback);
#endif
	r_config_desc (cfg, "cfg.bigendian", "Use little (false) or big (true) endiannes");
	r_config_set_cb (cfg, "cfg.debug", "false", &config_cfgdebug_callback);
	r_config_desc (cfg, "cfg.debug", "set/unset the debugger mode");
	r_config_set_cb (cfg, "cfg.datefmt", "%d:%m:%Y %H:%M:%S %z", &config_cfgdatefmt_callback);
	r_config_desc (cfg, "cfg.datefmt", "Date format (%d:%m:%Y %H:%M:%S %z)");
	r_config_set (cfg, "cfg.fortunes", "true");
	r_config_desc (cfg, "cfg.fortunes", "If enabled show tips at start");
	r_config_set (cfg, "cfg.wseek", "false");
	r_config_desc (cfg, "cfg.wseek", "Seek after write");
	r_config_set_i (cfg, "cfg.hashlimit", SLURP_LIMIT);
	r_config_desc (cfg, "cfg.hashlimit", "If the file its bigger than hashlimit don't calculate the hash");
	/* diff */
	r_config_set_i (cfg, "diff.from", 0);
	r_config_desc (cfg, "diff.from", "set source diffing address for px (uses cc command)");
	r_config_set_i (cfg, "diff.to", 0);
	r_config_desc (cfg, "diff.to", "set destination diffing address for px (uses cc command)");
	/* debug */
	if (core->cons->rows>30) // HACKY
		r_config_set_i (cfg, "dbg.follow", 64);
	else r_config_set_i (cfg, "dbg.follow", 32);
	r_config_desc (cfg, "dbg.follow", "Follow program counter when pc > core->offset + dbg.follow");
	r_config_set_cb (cfg, "dbg.backend", "native", &config_dbgbackend_callback);
	r_config_desc (cfg, "dbg.backend", "Select the debugger backend");
	r_config_set (cfg, "dbg.bep", "loader"); // loader, entry, constructor, main
	r_config_desc (cfg, "cfg.bep", "break on entrypoint (loader, entry, constructor, main)");
	r_config_set_cb (cfg, "dbg.stopthreads", "true", &config_stopthreads_callback);
	r_config_desc (cfg, "dbg.stopthreads", "stop all threads when debugger breaks");
	r_config_set_cb (cfg, "dbg.swstep", "false", &config_swstep_callback);
	r_config_desc (cfg, "dbg.swstep", "If enabled forces the use of software steps (code analysis+breakpoint)");
	r_config_set_cb (cfg, "dbg.trace", "true", &config_trace_callback);
	r_config_desc (cfg, "dbg.trace", "enable debugger trace (see asm.trace)");
	r_config_set_cb (cfg, "dbg.trace.tag", "0xff", &config_tracetag_callback);
	r_config_set_cb (cfg, "fs.view", "normal", &config_fsview_callback);
	r_config_desc (cfg, "fs.view", "Set visibility options for filesystems");
	r_config_set (cfg, "hud.once", "false");
	r_config_desc (cfg, "hud.once", "run");
	r_config_set (cfg, "bin.strings", "true");
	p = r_sys_getenv ("EDITOR");
#if __WINDOWS__
	r_config_set (cfg, "cfg.editor", p? p: "notepad");
#else
	r_config_set (cfg, "cfg.editor", p? p: "vi");
#endif
	r_config_desc (cfg, "cfg.editor", "Select default editor program");
	free (p);
	if (r_file_exist ("/usr/bin/xdot"))
		r_config_set (cfg, "cmd.graph", "!xdot a.dot");
	else
	if (r_file_exist ("/usr/bin/open"))
		r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!open a.gif");
	else
	if (r_file_exist ("/usr/bin/gqview"))
		r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!gqview a.gif");
	else
		r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!gqview a.gif");
	r_config_desc (cfg, "cmd.graph", "Command executed by 'agv' command to view graphs");
	r_config_set (cfg, "cmd.hit", "");
	r_config_desc (cfg, "cmd.hit", "Command to execute on every search hit");
	r_config_set (cfg, "cmd.open", "");
	r_config_desc (cfg, "cmd.open", "Command executed when file its opened");
	r_config_set_cb (cfg, "cmd.repeat", "true", &config_cmdrepeat_callback);
	r_config_desc (cfg, "cmd.repeat", "Alias newline (empty command) as '..'");
	r_config_set (cfg, "cmd.prompt", "");
	r_config_desc (cfg, "cmd.prompt", "Prompt commands");
	r_config_set (cfg, "cmd.cprompt", "");
	r_config_desc (cfg, "cmd.cprompt", "Column visual prompt commands");
	r_config_set (cfg, "cmd.vprompt", "");
	r_config_desc (cfg, "cmd.vprompt", "Visual prompt commands");
	r_config_set (cfg, "cmd.bp", "");
	r_config_desc (cfg, "cmd.bp", "Command to executed every breakpoint hitted");
	r_config_set (cfg, "graph.font", "Courier");
	r_config_desc (cfg, "graph.font", "font to be used by the dot graphs");
	r_config_set_cb (cfg, "scr.sparse", "false", config_scrsparse_callback);
	r_config_set_cb (cfg, "scr.interactive", "true", config_scrint_callback);
	r_config_set_cb (cfg, "scr.tee", "", config_teefile_callback);
	r_config_desc (cfg, "scr.tee", "Pipe console output to file if not empty");
	r_config_set_cb (cfg, "scr.prompt", "true", &config_scrprompt_callback);
	r_config_set_cb (cfg, "scr.color",
		(core->print->flags&R_PRINT_FLAGS_COLOR)?"true":"false",
		&config_color_callback);
	r_config_desc (cfg, "scr.color", "Enable/Disable colors");
	r_config_set_cb (cfg, "scr.pager", "", &config_pager_callback);
	r_config_desc (cfg, "scr.pager", "Select pager program (used if output doesn't fit on window)");
	//r_config_set_cb (cfg, "scr.fkey", "function", &config_scrfkey_callback);
	r_config_set_cb (cfg, "scr.fkey", "hit", &config_scrfkey_callback);
	r_config_desc (cfg, "scr.fkey", "Select the seek mode in visual");
	r_config_set (cfg, "scr.seek", "");
	r_config_set_i_cb (cfg, "scr.cols", 16, &config_scrcols_callback);
	r_config_desc (cfg, "scr.cols", "Configure the number of columns to print");
	r_config_set (cfg, "search.in", "file");
	r_config_desc (cfg, "search.in", "Specify search boundaries (raw, block, file, section)");
	r_config_set_i (cfg, "search.kwidx", 0);
	r_config_desc (cfg, "search.kwidx", "Store last search index count");
	r_config_set (cfg, "search.show", "true");
	r_config_desc (cfg, "search.show", "Show search results while found (disable if lot of hits)");
	r_config_set (cfg, "search.flags", "true");
	r_config_desc (cfg, "search.flags", "If enabled all search results are flagged, else just printed r2 commands");
	r_config_set_i (cfg, "search.count", 0);
	r_config_desc (cfg, "search.count", "Start index number at search hits");
	r_config_set (cfg, "search.prefix", "hit");
	r_config_desc (cfg, "search.prefix", "Prefix name in search hits label");
	r_config_set_i (cfg, "search.from", UT64_MAX);
	r_config_desc (cfg, "search.from", "Search start address");
	r_config_set_i (cfg, "search.to", UT64_MAX);
	r_config_desc (cfg, "search.to", "Search end address");
	r_config_set_i (cfg, "search.distance", 0); // TODO: use i_cb here and remove code in cmd.c
	r_config_desc (cfg, "search.distance", "Search string distance");
	r_config_set_i_cb (cfg, "search.align", 0, &config_searchalign_callback);
	r_config_desc (cfg, "search.align", "Only catch aligned search hits");
	r_config_set_cb (cfg, "scr.html", "false", &config_scrhtml_callback);
	r_config_desc (cfg, "scr.html", "If enabled disassembly use HTML syntax");

	sprintf (buf, "%d", R_CORE_BLOCKSIZE_MAX);
	r_config_set_cb (cfg, "io.maxblk", buf, &config_iomaxblk_callback);
	r_config_desc (cfg, "io.maxblk", "set max block size (soft limit)");

	r_config_set_cb (cfg, "io.ffio", "true", &config_ioffio_callback);
	r_config_desc (cfg, "io.ffio", "fill invalid buffers with 0xff instead of returning error");
	r_config_set_cb (cfg, "io.va", "true", &config_iova_callback);
	r_config_desc (cfg, "io.va", "If enabled virtual address layout can be used");
	r_config_set_cb (cfg, "io.cache", "false", &config_iocache_callback);
	r_config_desc (cfg, "io.cache", "Enable cache for io changes");
	r_config_set (cfg, "file.analyze", "false");
	r_config_desc (cfg, "file.analyze", "Analyze file on load. Same as r2 -c aa ..");
	r_config_set (cfg, "file.path", "");
	r_config_desc (cfg, "file.path", "Path of current file");
	r_config_set (cfg, "file.desc", "");
	r_config_desc (cfg, "file.desc", "User defined file description. Used by projects");
	r_config_set (cfg, "file.project", "");
	r_config_desc (cfg, "file.project", "Name of current project");
	r_config_set (cfg, "file.md5", "");
	r_config_desc (cfg, "file.md5", "md5 sum of current file");
	r_config_set (cfg, "file.sha1", "");
	r_config_desc (cfg, "file.sha1", "sha1 hash of current file");
	r_config_set (cfg, "file.type", "");
	r_config_desc (cfg, "file.type", "Type of current file");
	r_config_set_i (cfg, "magic.depth", 100);
	r_config_desc (cfg, "magic.depth", "Recursivity depth in magic description strings");
	r_config_set (cfg, "rap.loop", "true");
	r_config_desc (cfg, "rap.loop", "run rap as a forever-listening daemon");
	/* fkeys */
	for (i=1; i<13; i++) {
		snprintf (buf, sizeof (buf), "key.f%d", i);
		snprintf (buf+10, sizeof (buf)-10,
			"Run this when F%d key is pressed in visual mode", i);
		switch (i) {
		case 2: p = "dbs $$"; break;
		case 7: p = "ds"; break;
		case 8: p = "dso"; break;
		case 9: p = "dc"; break;
		default: p = ""; break;
		}
		r_config_set (cfg, buf, p);
		r_config_desc (cfg, buf, buf+10);
	}
	/* zoom */
	r_config_set_i (cfg, "zoom.maxsz", 512);
	r_config_desc (cfg, "zoom.maxsz", "Zoom max size of block");
	r_config_set_i (cfg, "zoom.from", 0);
	r_config_desc (cfg, "zoom.from", "Zoom start address");
	r_config_set_i (cfg, "zoom.to", 0);
	r_config_desc (cfg, "zoom.to", "Zoom end address");
	r_config_set_cb (cfg, "zoom.byte", "h", &config_zoombyte_callback);
	r_config_desc (cfg, "zoom.byte", "Zoom specific callback to calculate each byte (See pZ? for help)");
	/* TODO cmd */
#if 0
	config_set("asm.section", "true");
	config_set("asm.reladdr", "false"); // relative offset
	config_set("asm.functions", "true");
	config_set_i("asm.nlines", 6); // show left ref lines
	config_set("asm.lineswide", "false"); // show left ref lines
	config_set("asm.trace", "false"); // trace counter
	config_set("asm.split", "true"); // split code blocks
	config_set("asm.splitall", "false"); // split code blocks

	// config_set("asm.follow", "");
	config_set("cmd.wp", "");
	config_set("cmd.flag", "true");
	config_set("cmd.asm", "");
	config_set("cmd.user", "");
	config_set("cmd.trace", "");
	config_set("cmd.visual", "");
	config_set("cmd.visualbind", "");
	config_set("cmd.touchtrace", "");

	config_set("search.flag", "true");
	config_set("search.verbose", "true");

	config_set("file.id", "false");
	config_set("file.flag", "false");
	config_set("file.trace", "trace.log");
	config_set("file.project", "");
	config_set("file.entrypoint", "");
	node = config_set("file.scrfilter", "");
	node->callback = &config_filterfile_callback;
	config_set_i("file.size", 0);

	node = config_set_i("io.vaddr", 0); // OLD file.baddr
	node->callback = &config_vaddr_callback;
	node = config_set_i("io.paddr", 0); // physical address
	node->callback = &config_paddr_callback;

	config_set("dump.regs", "true");
	config_set("dump.user", "true");
	config_set("dump.libs", "true");
	config_set("dump.fds", "true");

	config_set("trace.bt", "false");
	config_set("trace.bps", "false");
	config_set("trace.calls", "false");
	config_set_i("trace.sleep", 0);
	config_set("trace.smart", "false");
	config_set("trace.libs", "true");
	config_set("trace.log", "false");
	config_set("trace.dup", "false");
	config_set("trace.cmtregs", "false");

	config_set("cfg.editor", "vi");
	node = config_set("cfg.debug", "false");
	node->callback = &config_debug_callback;
	config_set("cfg.noscript", "false");
	config_set("cfg.sections", "true");
	config_set("cfg.encoding", "ascii"); // cp850
	config_set_i("cfg.delta", 4096); // cp850
	node = config_set("cfg.verbose", "true");
	node->callback = &config_verbose_callback;

	config_set("cfg.inverse", "false");
	config_set_i("cfg.analdepth", 6);
	config_set("file.insert", "false");
	config_set("file.insertblock", "false");
	config_set("file.undowrite", "true");
	if (first) {
		node = config_set("file.write", "false");
		node->callback = &config_wmode_callback;
	}
	node = config_set("cfg.limit", "0");
	node->callback = &config_limit_callback;
#if __mips__
	// ???
	config_set("cfg.addrmod", "32");
#else
	config_set("cfg.addrmod", "4");
#endif
	config_set("cfg.datefmt", "%d:%m:%Y %H:%M:%S %z");
	config_set_i("cfg.count", 0);
	node = config_set_i("cfg.bsize", 512);
	node->callback = &config_bsize_callback;
	config_set_i("cfg.vbsize", 1024);
	config_set("cfg.vbsize_enabled", "false");

	config_set_i("range.from", 0);
	config_set_i("range.to", 0xffff);
	config_set("range.traces", "true");
	config_set("range.graphs", "true");
	config_set("range.functions", "true");

	config_set("child.stdio", "");
	config_set("child.stdin", "");
	config_set("child.stdout", "");
	config_set("child.stderr", "");
	config_set("child.setgid", ""); // must be int ?
	config_set("child.chdir", ".");
	config_set("child.chroot", "/");
	config_set("child.setuid", "");
#if __mips__
	config_set("dbg.fpregs", "true");
#else
	config_set("dbg.fpregs", "false");
#endif
	config_set("dbg.forks", "false"); // stop debugger in any fork or clone
	config_set("dbg.controlc", "true"); // stop debugger if ^C is pressed
	config_set_i("dbg.focus", 0); // focus on ps.pid or not (ignore events of rest of procs)
	config_set("dbg.syms", "true");
	config_set("dbg.stepo", "false"); // step over for !contu (debug_step())
	config_set("dbg.maps", "true");
	config_set("dbg.sections", "true");
	config_set("dbg.strings", "false");
	config_set("dbg.stop", "false");
	config_set("dbg.threads", "false");
	config_set("dbg.contscbt", "true");
	config_set("dbg.contsc2", "true"); // WTF?
	config_set("dbg.regs", "true");
	config_set("dbg.regs2", "false");
	config_set("dbg.stack", "true");
	config_set("dbg.vstack", "true");
	config_set("dbg.wptrace", "false");
	config_set_i("dbg.stacksize", 66);
	config_set("dbg.stackreg", "esp");
	config_set("dbg.bt", "false");
	config_set_i("dbg.btlast", 0);
	config_set("dbg.fullbt", "false"); // user backtrace or lib+user backtrace
	config_set("dbg.bttype", "default"); // default, st and orig or so!
#if __APPLE__ || __ARM__ || __mips__
	config_set("dbg.hwbp", "false"); // default, st and orig or so!
#else
	config_set("dbg.hwbp", "true"); // hardware breakpoints by default // ALSO BSD
#endif
	config_set("dir.home", getenv("HOME"));

	/* dir.monitor */
	ptr = getenv("MONITORPATH");
	if (ptr == NULL) {
		sprintf(buf, "%s/.radare/monitor/", ("HOME"));
		ptr = (const char *)&buf;
	}
	config_set("dir.monitor", ptr);

	config_set("graph.split", "false"); // split blocks // SHOULD BE TRUE, but true algo is buggy
	config_set("graph.jmpblocks", "true");
	config_set("graph.refblocks", "false"); // must be circle nodes
	config_set("graph.callblocks", "false");
	config_set("graph.flagblocks", "true");
	config_set_i("graph.depth", 9);
	config_set("graph.offset", "true");
	config_set("graph.render", "cairo");    // aalib/ncurses/text
	config_set("graph.layout", "default");  // graphviz
#endif
	r_config_lock (cfg, R_TRUE);
	return R_TRUE;
}
Example #17
0
static int cb(RDiff *d, void *user, RDiffOp *op) {
	int i; //, diffmode = (int)(size_t)user;
	if (showcount) {
		count++;
		return 1;
	}
	switch (diffmode) {
	case 'r':
		if (disasm) {
			eprintf ("r2cmds (-r) + disasm (-D) not yet implemented\n");
		}
		if (op->a_len == op->b_len) {
			printf ("wx ");
			for (i=0; i<op->b_len; i++)
				printf ("%02x", op->b_buf[i]);
			printf (" @ 0x%08"PFMT64x"\n", op->b_off);
		} else {
			if ((op->a_len)>0)
				printf ("r-%d @ 0x%08"PFMT64x"\n",
					op->a_len, op->a_off+delta);
			if (op->b_len> 0) {
				printf ("r+%d @ 0x%08"PFMT64x"\n",
					op->b_len, op->b_off+delta);
				printf ("wx ");
				for (i=0; i<op->b_len; i++)
					printf ("%02x", op->b_buf[i]);
				printf (" @ 0x%08"PFMT64x"\n", op->b_off+delta);
			}
			delta += (op->b_off - op->a_off);
		}
		return 1;
	case 'j':
		if (disasm) {
			eprintf ("JSON (-j) + disasm (-D) not yet implemented\n");
		}
		if (json_started)
			printf(",\n");
		json_started = 1;
		printf ("{\"offset\":%"PFMT64d",", op->a_off);
		printf("\"from\":\"");
		for (i = 0;i<op->a_len;i++)
			printf ("%02x", op->a_buf[i]);
		printf ("\", \"to\":\"");
		for (i=0; i<op->b_len; i++)
			printf ("%02x", op->b_buf[i]);
		printf ("\"}"); //,\n");
		return 1;
	case 0:
	default:
		if (disasm) {
			printf ("--- 0x%08"PFMT64x"\n", op->a_off);
			if (!core) {
				core = opencore (file);
				if (arch) {
					r_config_set (core->config, "asm.arch", arch);
				}
				if (bits) {
					r_config_set_i (core->config, "asm.bits", bits);
				}
			}
			if (core) {
				RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->a_buf, op->a_len);
				printf ("%s\n", ac->buf_asm);
				//r_asm_code_free (ac);
			}
		} else {
			printf ("0x%08"PFMT64x" ", op->a_off);
			for (i = 0; i < op->a_len; i++)
				printf ("%02x", op->a_buf[i]);
		}
		if (disasm) {
			printf ("+++ 0x%08"PFMT64x"\n", op->b_off);
			if (!core) {
				core = opencore (NULL);
			}
			if (core) {
				RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->b_buf, op->b_len);
				printf ("%s\n", ac->buf_asm);
				//r_asm_code_free (ac);
			}
		} else {
			printf (" => ");
			for (i=0; i < op->b_len; i++)
				printf ("%02x", op->b_buf[i]);
			printf (" 0x%08"PFMT64x"\n", op->b_off);
		}
		return 1;
	}
}
Example #18
0
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
	char buf[32];
	RSocketHTTPRequest *rs;
	int iport, oldsandbox = -1;
	int timeout = r_config_get_i (core->config, "http.timeout");
	int x = r_config_get_i (core->config, "scr.html");
	int y = r_config_get_i (core->config, "scr.color");
	int z = r_config_get_i (core->config, "asm.bytes");
	int u = r_config_get_i (core->config, "scr.interactive");
	int v = r_config_get_i (core->config, "asm.cmtright");
	const char *port = r_config_get (core->config, "http.port");
	char *allow = (char *)r_config_get (core->config, "http.allow");
	if (core->http_up) {
		eprintf ("http server is already running\n");
		return 1;
	}
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return 1;
	}
	if (path && atoi (path)) {
		port = path;
		path = NULL;
	}
	if (!strcmp (port, "0")) {
		r_num_irand ();
		iport = 1024+r_num_rand (45256);
		snprintf (buf, sizeof (buf), "%d", iport);
		port = buf;
	}
	s = r_socket_new (R_FALSE);
	s->local = !r_config_get_i (core->config, "http.public");
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on http.port\n");
		return 1;
	}
	if (launch) {
		char cmd[128];
		const char *browser = r_config_get (core->config, "http.browser");
		snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &",
			browser, atoi (port), path?path:"");
		r_sys_cmd (cmd);
	}
	r_config_set (core->config, "asm.cmtright", "false");
	r_config_set (core->config, "scr.html", "true");
	r_config_set (core->config, "scr.color", "false");
	r_config_set (core->config, "asm.bytes", "false");
	r_config_set (core->config, "scr.interactive", "false");
	if (r_config_get_i (core->config, "http.sandbox")) {
		oldsandbox = r_config_get_i (core->config, "cfg.sandbox");
		r_config_set (core->config, "cfg.sandbox", "true");
	}
	eprintf ("Starting http server...\n");
	eprintf ("http://localhost:%d/\n", atoi (port));
	core->http_up = R_TRUE;
	while (!r_cons_singleton ()->breaked) {
		r_cons_break ((RConsBreak)http_break, core);
		rs = r_socket_http_accept (s, timeout);
		if (!rs) {
			if (!s) break;
			r_sys_usleep (100);
			continue;
		}
		if (allow && *allow) {
			int accepted = R_FALSE;
			const char *host;
			char *p, *peer = r_socket_to_string (rs->s);
			char *allows = strdup (allow);
			//eprintf ("Firewall (%s)\n", allows);
			int i, count = r_str_split (allows, ',');
			p = strchr (peer, ':');
			if (p) *p = 0;
			for (i=0; i<count; i++) {
				host = r_str_word_get0 (allows, i);
				//eprintf ("--- (%s) (%s)\n", host, peer);
				if (!strcmp (host, peer)) {
					accepted = R_TRUE;
					break;
				}
			}
			free (peer);
			free (allows);
			if (!accepted) {
				r_socket_http_close (rs);
				continue;
			}
		}
		if (!rs->method || !rs->path) {
			eprintf ("Invalid http headers received from client\n");
			r_socket_http_close (rs);
			continue;
		}
		char *dir = NULL;

		if (r_config_get_i (core->config, "http.dirlist"))
			if (r_file_is_directory (rs->path))
				dir = strdup (rs->path);
		if (!strcmp (rs->method, "GET")) {
			if (!memcmp (rs->path, "/up", 3)) {
				if (r_config_get_i (core->config, "http.upget")) {
					const char *uproot = r_config_get (core->config, "http.uproot");
					if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) {
						char *ptr = rtr_dir_files (uproot);
						r_socket_http_response (rs, 200, ptr, 0, NULL);
						free (ptr);
					} else {
						char *path = r_file_root (uproot, rs->path + 4);
						if (r_file_exists (path)) {
							int sz = 0;
							char *f = r_file_slurp (path, &sz);
							if (f) {
								r_socket_http_response (rs, 200, f, sz, NULL);
								free (f);
							} else {
								r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
								eprintf ("http: Cannot open '%s'\n", path);
							}
						} else {
							if (dir) {
								char *resp = rtr_dir_files (dir);
								r_socket_http_response (rs, 404, resp, 0, NULL);
								free (resp);
							} else {
								eprintf ("File '%s' not found\n", path);
								r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
							}
						}
						free (path);
					}
				} else {
					r_socket_http_response (rs, 403,
							"Permission denied\n", 0, NULL);
				}
			} else if (!memcmp (rs->path, "/cmd/", 5)) {
				char *cmd = rs->path +5;
				char foo[32];
				const char *httpcmd = r_config_get (core->config, "http.uri");
				while (*cmd=='/') cmd++;
				if (httpcmd && *httpcmd) {
					int len;
					char *res;
					// do remote http query and proxy response
					snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd);
					res = r_socket_http_get (foo, NULL, &len);
					if (res) {
						res[len]=0;
						r_cons_printf ("%s\n", res);
					}
				} else {
					char *out, *cmd = rs->path+5;
					r_str_uri_decode (cmd);
					// eprintf ("CMD (%s)\n", cmd);
					out = r_core_cmd_str_pipe (core, cmd);
					// eprintf ("\nOUT LEN = %d\n", strlen (out));
					if (out) {
						char *res = r_str_uri_encode (out);
						r_socket_http_response (rs, 200, out, 0,
							"Content-Type: text/plain\n");
						free (out);
						free (res);
					} else r_socket_http_response (rs, 200, "", 0, NULL);
				}
			} else {
				const char *root = r_config_get (core->config, "http.root");
				char *path = r_file_root (root, rs->path);
				// FD IS OK HERE
				if (rs->path [strlen (rs->path)-1] == '/') {
					path = r_str_concat (path, "index.html");
					//rs->path = r_str_concat (rs->path, "index.html");
				} else {
					//snprintf (path, sizeof (path), "%s/%s", root, rs->path);
					if (r_file_is_directory (path)) {
						char res[128];
						snprintf (res, sizeof (res),
							"Location: %s/\n", rs->path);
						r_socket_http_response (rs, 302,
							NULL, 0, res);
						r_socket_http_close (rs);
						free (path);
						free (dir);
						dir = NULL;
						continue;
					}
				}
				if (r_file_exists (path)) {
					int sz = 0;
					char *f = r_file_slurp (path, &sz);
					if (f) {
						const char *contenttype = NULL;
						if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n";
						if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n";
						if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n";
						r_socket_http_response (rs, 200, f, sz, contenttype);
						free (f);
					} else {
						r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
						eprintf ("http: Cannot open '%s'\n", path);
					}
				} else {
					if (dir) {
						char *resp = rtr_dir_files (dir);
						eprintf ("Dirlisting %s\n", dir);
						r_socket_http_response (rs, 404, resp, 0, NULL);
						free (resp);
					} else {
						eprintf ("File '%s' not found\n", path);
						r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
					}
				}
				free (path);
			}
		} else 
		if (!strcmp (rs->method, "POST")) {
			ut8 *ret;
			int retlen;
			char buf[128];
			if (r_config_get_i (core->config, "http.upload")) {
				ret = r_socket_http_handle_upload (
					rs->data, rs->data_length, &retlen);
				if (ret) {
					ut64 size = r_config_get_i (core->config, "http.maxsize");
					if (size && retlen > size) {
						r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL);
					} else {
						char *filename = r_file_root (
							r_config_get (core->config, "http.uproot"),
							rs->path + 4);
						eprintf ("UPLOADED '%s'\n", filename);
						r_file_dump (filename, ret, retlen);
						free (filename);
						snprintf (buf, sizeof (buf),
							"<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen);
							r_socket_http_response (rs, 200, buf, 0, NULL);
					}
					free (ret);
				}
			} else {
				r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL);
			}
		} else {
			r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL);
		}
		r_socket_http_close (rs);
		free (dir);
	}
	core->http_up = R_FALSE;
	r_socket_free (s);
	r_cons_break_end ();
	r_config_set_i (core->config, "scr.html", x);
	r_config_set_i (core->config, "scr.color", y);
	r_config_set_i (core->config, "asm.bytes", z);
	r_config_set_i (core->config, "scr.interactive", u);
	r_config_set_i (core->config, "asm.cmtright", v);
	if (oldsandbox != -1)
		r_config_set_i (core->config, "cfg.sandbox", oldsandbox);
	return 0;
}
Example #19
0
static int bin_info(RCore *r, int mode) {
	int i, j;
	char str[R_FLAG_NAME_SIZE];
	char size_str[32];
	char baddr_str[32];
	RBinInfo *info = r_bin_get_info (r->bin);
	RBinFile *binfile = r_core_bin_cur (r);
	const char *compiled = NULL;

	if (!binfile || !info) {
		if (mode & R_CORE_BIN_JSON) r_cons_printf ("{}");
		return false;
	}

	compiled = get_compile_time (binfile->sdb);
	snprintf (size_str, sizeof (size_str),
		"%"PFMT64d,  r_bin_get_size (r->bin));
	snprintf (baddr_str, sizeof (baddr_str),
		"%"PFMT64d,  info->baddr);

	if (IS_MODE_SET (mode)) {
		r_config_set (r->config, "file.type", info->rclass);
		r_config_set (r->config, "cfg.bigendian", info->big_endian ? "true" : "false");
		if (info->rclass && !strcmp (info->rclass, "fs")) {
			r_config_set (r->config, "asm.arch", info->arch);
			r_core_cmdf (r, "m /root %s 0", info->arch);
		} else {
			if (info->lang) {
				r_config_set (r->config, "bin.lang", info->lang);
			}
			r_config_set (r->config, "asm.os", info->os);
			r_config_set (r->config, "asm.arch", info->arch);
			r_config_set (r->config, "anal.arch", info->arch);
			snprintf (str, R_FLAG_NAME_SIZE, "%i", info->bits);
			r_config_set (r->config, "asm.bits", str);
			r_config_set (r->config, "asm.dwarf",
				(R_BIN_DBG_STRIPPED &info->dbg_info) ? "false" : "true");
		}
	} else if (IS_MODE_SIMPLE (mode)) {
		r_cons_printf ("arch %s\n", info->arch);
		r_cons_printf ("bits %d\n", info->bits);
		r_cons_printf ("os %s\n", info->os);
		r_cons_printf ("endian %s\n", info->big_endian? "big": "little");
	} else if (IS_MODE_RAD (mode)) {
		if (info->type && !strcmp (info->type, "fs")) {
			r_cons_printf ("e file.type=fs\n");
			r_cons_printf ("m /root %s 0\n", info->arch);
		} else {
			r_cons_printf ("e cfg.bigendian=%s\n"
				"e asm.bits=%i\n"
				"e asm.dwarf=%s\n",
				r_str_bool (info->big_endian),
				info->bits,
				r_str_bool (R_BIN_DBG_STRIPPED &info->dbg_info));
			if (info->lang && *info->lang) {
				r_cons_printf ("e bin.lang=%s\n", info->lang);
			}
			if (info->rclass && *info->rclass) {
				r_cons_printf ("e file.type=%s\n",
					info->rclass);
			}
			if (info->os) {
				r_cons_printf ("e asm.os=%s\n", info->os);
			}
			if (info->arch) {
				r_cons_printf ("e asm.arch=%s\n", info->arch);
			}
		}
	} else {
		// XXX: if type is 'fs' show something different?
		if (IS_MODE_JSON (mode)) r_cons_printf ("{");
		pair_bool ("pic", info->has_pi, mode, false);
		pair_bool ("canary", info->has_canary, mode, false);
		pair_bool ("nx", info->has_nx, mode, false);
		pair_bool ("crypto", info->has_crypto, mode, false);
		pair_bool ("va", info->has_va, mode, false);
		pair_str ("bintype", info->rclass, mode, false);
		pair_str ("class", info->bclass, mode, false);
		pair_str ("lang", info->lang, mode, false);
		pair_str ("arch", info->arch, mode, false);
		pair_int ("bits", info->bits, mode, false);
		pair_str ("machine", info->machine, mode, false);
		pair_str ("os", info->os, mode, false);
		pair_str ("subsys", info->subsystem, mode, false);
		pair_str ("endian", info->big_endian ? "big" : "little", mode, false);
		pair_bool ("stripped", R_BIN_DBG_STRIPPED & info->dbg_info, mode, false);
		pair_bool ("static", r_bin_is_static (r->bin), mode, false);
		pair_bool ("linenum", R_BIN_DBG_LINENUMS & info->dbg_info, mode, false);
		pair_bool ("lsyms", R_BIN_DBG_SYMS & info->dbg_info, mode, false);
		pair_bool ("relocs", R_BIN_DBG_RELOCS & info->dbg_info, mode, false);
		pair_str ("rpath", info->rpath, mode, false);
		pair_str ("binsz", size_str, mode, false);
		pair_str ("compiled", compiled, mode, false);
		pair_str ("guid", info->guid, mode, false);
		pair_str ("dbg_file", info->debug_file_name, mode, true);

		for (i = 0; info->sum[i].type; i++) {
			int len;

			RBinHash *h = &info->sum[i];
			ut64 hash = r_hash_name_to_bits (h->type);
			RHash *rh = r_hash_new (true, hash);
			len = r_hash_calculate (rh, hash, (const ut8*)
					binfile->buf->buf+h->from, h->to);
			if (len < 1) eprintf ("Invaild wtf\n");
			r_hash_free (rh);

			r_cons_printf ("%s\t%d-%dc\t", h->type, h->from, h->to+h->from);
			for (j = 0; j < h->len; j++) {
				r_cons_printf ("%02x", h->buf[j]);
			}
			r_cons_newline ();
		}
		if (IS_MODE_JSON (mode)) r_cons_printf ("}");
	}
	return true;
}
Example #20
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;
}
Example #21
0
static int cmd_project(void *data, const char *input) {
	RCore *core = (RCore *)data;
	const char *file, *arg = input+1;
	const char *fileproject = r_config_get (core->config, "file.project");
	char *str = strdup (fileproject);
	if (*arg==' ') arg++;
	file = input[1]?arg:str;
	switch (input[0]) {
	case 'c':
		if (!input[1]) {
			eprintf ("TODO: Show project saving script to console\n");
		} else 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);
		} else {
			if (file && *file)
				r_cons_printf ("%s\n", file);
		}
		break;
	case 'l':
		r_core_project_list (core, input[1]);
		break;
	case 'd':
		r_core_project_delete (core, file);
		break;
	case 's':
		if (r_core_project_save (core, file)) {
			r_config_set (core->config, "file.project", file);
			r_cons_printf ("%s\n", file);
		}
		break;
	case 'n':
		if (!fileproject || !*fileproject) {
			eprintf ("No project\n");
		} else
		switch (input[1]) {
		case '-':
			/* remove lines containing specific words */
			{
			char *str = r_core_project_notes_file (core, fileproject);
			char *data = r_file_slurp (str, NULL);
			FILE *fd = r_sandbox_fopen (str, "w");
			if (!fd) {
				eprintf ("Cannot open %s\n", str);
			} else {
				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);
				}
				fclose (fd);
				free (str);
				if (del>0) {
					eprintf ("Deleted %d lines\n", del);
				}
			}
			}
			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_printf ("%s\n", res);
						free (res);
					}
					free (data);
					free (str);
				}
			} else if (input[2] == ' ') {
				/* set base64 string */
				ut8 *data = r_base64_decode_dyn (input+3, 0);
				if (data) {
					char *str = r_core_project_notes_file (core, fileproject);
					if (str) {
						r_file_dump (str, data, strlen ((const char*)data));
						free (str);
					}
					free (data);
				}
			} else {
				eprintf ("Usage: `Pnj` or `Pnj ...`\n");
			}
			break;
		case 0:
			{
			char *str = r_core_project_notes_file (core, fileproject);
			char *data = r_file_slurp (str, NULL);
			if (data) {
				r_cons_printf ("%s\n", 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",
					"Pnj", "", "show notes in base64",
					"Pnj", " [base64]", "set notes in base64",
					NULL};
				r_core_cmd_help (core, help_msg);
			}
			break;
		}
		break;
	case 'i':
//		if (r_file_is_regular (file))
		free (r_core_project_info (core, file));
		break;
	default: {
		const char* help_msg[] = {
		"Usage:", "P[?osi] [file]", "Project management",
		"Pc", "", "show what will be saved in the project script",
		"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",
		"NOTE:", "", "See 'e file.project'",
		"NOTE:", "", "project files are stored in ~/.config/radare2/projects",
		NULL};
		r_core_cmd_help (core, help_msg);
		}
		break;
	}
	free (str);
	return R_TRUE;
}
Example #22
0
File: rtr.c Project: 0xroot/radare2
- follow symlinks
#endif

R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
	RSocketHTTPRequest *rs;
	int oldsandbox = -1;
	int timeout = r_config_get_i (core->config, "http.timeout");
	int x = r_config_get_i (core->config, "scr.html");
	int y = r_config_get_i (core->config, "scr.color");
	int z = r_config_get_i (core->config, "asm.bytes");
	int u = r_config_get_i (core->config, "scr.interactive");
	int v = r_config_get_i (core->config, "asm.cmtright");
	const char *port = r_config_get (core->config, "http.port");
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return 1;
	}
	s = r_socket_new (R_FALSE);
	s->local = !r_config_get_i (core->config, "http.public");
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on http.port\n");
		return 1;
	}
	if (launch) {
		char cmd[128];
		const char *browser = r_config_get (core->config, "http.browser");
		snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s",
			browser, atoi (port), path?path:"");
		r_sys_cmd (cmd);
	}
	r_config_set (core->config, "asm.cmtright", "false");
	r_config_set (core->config, "scr.html", "true");
	r_config_set (core->config, "scr.color", "false");
	r_config_set (core->config, "asm.bytes", "false");
	r_config_set (core->config, "scr.interactive", "false");
	if (r_config_get_i (core->config, "http.sandbox")) {
		oldsandbox = r_config_get_i (core->config, "cfg.sandbox");
		r_config_set (core->config, "cfg.sandbox", "true");
	}
	eprintf ("Starting http server...\n");
	eprintf ("http://localhost:%d/\n", atoi (port));
	while (!r_cons_singleton ()->breaked) {
		r_cons_break (http_break, core);
		rs = r_socket_http_accept (s, timeout);
		if (!rs) {
			if (!s) break;
			r_sys_usleep (200);
			continue;
		}
		if (!rs->method || !rs->path) {
			r_socket_http_close (rs);
			continue;
		}
		if (!strcmp (rs->method, "GET")) {
			if (!memcmp (rs->path, "/up", 3)) {
				if (r_config_get_i (core->config, "http.upget")) {
					const char *uproot = r_config_get (core->config, "http.uproot");
					if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) {
						char *ptr = strdup ("<html><body>\n");
						const char *file;
						RListIter *iter;
						// list files
						RList *files = r_sys_dir (uproot);
						eprintf ("Listing directory %s\n", uproot);
						r_list_foreach (files, iter, file) {
							if (file[0] == '.') continue;
							ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n",
								file, file);
						}
						r_list_free (files);
						ptr = r_str_concat (ptr, "<html><body>\n");
						r_socket_http_response (rs, 200, ptr, 0, NULL);
					} else {
						char *path = r_file_root (uproot, rs->path + 4);
						if (r_file_exists (path)) {
							int sz = 0;
							char *f = r_file_slurp (path, &sz);
							if (f) {
								r_socket_http_response (rs, 200, f, sz, NULL);
								free (f);
							} else {
								r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
								eprintf ("http: Cannot open '%s'\n", path);
							}
						} else {
							eprintf ("File '%s' not found\n", path);
							r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
						}
						free (path);
					}
				} else {
					r_socket_http_response (rs, 403,
							"Permission denied\n", 0, NULL);
				}
			} else if (!memcmp (rs->path, "/cmd/", 5)) {
Example #23
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;
}
Example #24
0
static int asm_profile(RConfig *cfg, const char *profile) {
	// TODO: Do a cleanup on those configurations
	if (!strcmp (profile, "help") || *profile == '?') {
		r_cons_printf ("Available asm.profile:\n"
			" default, gas, smart, graph, debug, full, simple\n");
		return R_FALSE;
	} else if (!strcmp (profile, "default")) {
		r_config_set (cfg, "asm.bytes", "true");
		r_config_set (cfg, "asm.lines", "true");
		r_config_set (cfg, "asm.linesout", "false");
		r_config_set (cfg, "asm.lineswide", "false");
		r_config_set (cfg, "asm.offset", "true");
		r_config_set (cfg, "asm.comments", "true");
		r_config_set (cfg, "asm.flagsline", "false");
		r_config_set (cfg, "asm.section", "false");
		r_config_set (cfg, "asm.trace", "false");
		r_config_set (cfg, "anal.split", "true");
		r_config_set (cfg, "asm.flags", "true");
		r_config_set (cfg, "asm.size", "false");
		r_config_set (cfg, "asm.xrefs", "true");
		r_config_set (cfg, "asm.functions", "true");
		r_config_set (cfg, "scr.color", "true");
	} else if (!strcmp(profile, "compact")) {
		asm_profile (cfg, "simple");
		r_config_set (cfg, "asm.lines", "true");
		r_config_set (cfg, "asm.comments", "false");
		r_config_set (cfg, "scr.color", "false");
	} else if (!strcmp(profile, "gas")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.lines", "false");
		r_config_set (cfg, "asm.comments", "false");
		r_config_set (cfg, "asm.section", "false");
		r_config_set (cfg, "asm.trace", "false");
		r_config_set (cfg, "asm.bytes", "false");
		r_config_set (cfg, "asm.stackptr", "false");
		r_config_set (cfg, "asm.offset", "false");
		r_config_set (cfg, "asm.flags", "true");
		r_config_set (cfg, "asm.flagsline", "true");
		r_config_set (cfg, "asm.jmpflags", "true");
		r_config_set (cfg, "scr.color", "false");
	} else if (!strcmp(profile, "smart")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.section", "false");
		r_config_set (cfg, "asm.trace", "false");
		r_config_set (cfg, "asm.bytes", "false");
		r_config_set (cfg, "asm.stackptr", "false");
	} else if (!strcmp (profile, "graph")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.section", "false");
		r_config_set (cfg, "asm.bytes", "false");
		r_config_set (cfg, "asm.trace", "false");
		r_config_set (cfg, "scr.color", "false");
		r_config_set (cfg, "asm.lines", "false");
		r_config_set (cfg, "asm.stackptr", "false");
		if (r_config_get (cfg, "graph.offset"))
			r_config_set (cfg, "asm.offset", "true");
		else r_config_set (cfg, "asm.offset", "false");
	} else if (!strcmp (profile, "debug")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.trace", "true");
	} else if (!strcmp (profile, "full")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.bytes", "true");
		r_config_set (cfg, "asm.lines", "true");
		r_config_set (cfg, "asm.linesout", "true");
		r_config_set (cfg, "asm.lineswide", "true");
		r_config_set (cfg, "asm.section", "true");
		r_config_set (cfg, "asm.size", "true");
	} else if (!strcmp (profile, "simple")) {
		asm_profile (cfg, "default");
		r_config_set (cfg, "asm.bytes", "false");
		r_config_set (cfg, "asm.lines", "false");
		r_config_set (cfg, "asm.comments", "true");
		r_config_set (cfg, "anal.split", "false");
		r_config_set (cfg, "asm.flags", "false");
		r_config_set (cfg, "asm.flagsline", "true");
		r_config_set (cfg, "asm.xrefs", "false");
		r_config_set (cfg, "asm.stackptr", "false");
		r_config_set (cfg, "asm.section", "false");
	}
	return R_TRUE;
}
Example #25
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;
}
Example #26
0
static int cb(RDiff *d, void *user, RDiffOp *op) {
	int i; //, diffmode = (int)(size_t)user;
	char s[256];
	if (showcount) {
		count++;
		return 1;
	}
	switch (diffmode) {
	case 'U': // 'U' in theory never handled here
	case 'u':
		if (op->a_len > 0) {
			readstr (s, sizeof (s), op->a_buf, op->a_len);
			if (*s) {
				if (!quiet) printf (Color_RED);
				if (r_mem_is_printable ((const ut8*)s, R_MIN (strlen (s), 5))) {
					printf ("- %s\n", s);
				} else {
					printf ("-:");
					int len = op->a_len; //R_MIN (op->a_len, strlen (op->a_buf));
					for (i = 0; i < len; i++) {
						printf ("%02x", op->a_buf[i]);
					}
					printf (" \"%s\"\n", op->a_buf);
				}
				if (!quiet) printf (Color_RESET);
			}
		}
		if (op->b_len > 0) {
			readstr (s, sizeof (s), op->b_buf, op->b_len);
			if (*s) {
				if (!quiet) printf (Color_GREEN);
				if (r_mem_is_printable ((const ut8*)s, R_MIN (strlen (s), 5))) {
					printf ("+ %s\n", s);
				} else {
					printf ("+:");
					for (i = 0; i < op->b_len; i++) {
						printf ("%02x", op->b_buf[i]);
					}
					printf (" \"%s\"\n", op->b_buf);
				}
				if (!quiet) printf (Color_RESET);
			}
		}
		break;
	case 'r':
		if (disasm) {
			eprintf ("r2cmds (-r) + disasm (-D) not yet implemented\n");
		}
		if (op->a_len == op->b_len) {
			printf ("wx ");
			for (i = 0; i < op->b_len; i++) {
				printf ("%02x", op->b_buf[i]);
			}
			printf (" @ 0x%08"PFMT64x"\n", op->b_off);
		} else {
			if (op->a_len > 0) {
				printf ("r-%d @ 0x%08"PFMT64x"\n",
					op->a_len, op->a_off + delta);
			}
			if (op->b_len > 0) {
				printf ("r+%d @ 0x%08"PFMT64x"\n",
					op->b_len, op->b_off + delta);
				printf ("wx ");
				for (i = 0; i < op->b_len; i++) {
					printf ("%02x", op->b_buf[i]);
				}
				printf (" @ 0x%08"PFMT64x"\n", op->b_off+delta);
			}
			delta += (op->b_off - op->a_off);
		}
		return 1;
	case 'j':
		if (disasm) {
			eprintf ("JSON (-j) + disasm (-D) not yet implemented\n");
		}
		if (json_started) {
			printf (",\n");
		}
		json_started = 1;
		printf ("{\"offset\":%"PFMT64d",", op->a_off);
		printf("\"from\":\"");
		for (i = 0; i < op->a_len; i++) {
			printf ("%02x", op->a_buf[i]);
		}
		printf ("\", \"to\":\"");
		for (i = 0; i < op->b_len; i++) {
			printf ("%02x", op->b_buf[i]);
		}
		printf ("\"}"); //,\n");
		return 1;
	case 0:
	default:
		if (disasm) {
			printf ("--- 0x%08"PFMT64x"\n", op->a_off);
			if (!core) {
				core = opencore (file);
				if (arch) {
					r_config_set (core->config, "asm.arch", arch);
				}
				if (bits) {
					r_config_set_i (core->config, "asm.bits", bits);
				}
			}
			if (core) {
				RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->a_buf, op->a_len);
				printf ("%s\n", ac->buf_asm);
				//r_asm_code_free (ac);
			}
		} else {
			printf ("0x%08"PFMT64x" ", op->a_off);
			for (i = 0; i < op->a_len; i++) {
				printf ("%02x", op->a_buf[i]);
			}
		}
		if (disasm) {
			printf ("+++ 0x%08"PFMT64x"\n", op->b_off);
			if (!core) {
				core = opencore (NULL);
			}
			if (core) {
				RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->b_buf, op->b_len);
				printf ("%s\n", ac->buf_asm);
				//r_asm_code_free (ac);
			}
		} else {
			printf (" => ");
			for (i = 0; i < op->b_len; i++) {
				printf ("%02x", op->b_buf[i]);
			}
			printf (" 0x%08"PFMT64x"\n", op->b_off);
		}
		return 1;
	}
	return 0;
}
Example #27
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;
}