Exemple #1
0
static int parse(RParse *p, const char *data, char *str) {
	char w0[256], w1[256], w2[256];
	int i, len = strlen(data);
	char *buf, *ptr, *optr;
	ADDR_TYPE atype;

	if (len >= sizeof(w0)) {
		return false;
	}
	// malloc can be slow here :?
	if ((buf = malloc(len + 1)) == NULL) {
		return false;
	}
	memcpy(buf, data, len + 1);

	if (*buf) {
		atype = addr_type(buf);
		r_str_replace_char(buf, '(', ' ');
		r_str_replace_char(buf, ')', ' ');
		*w0 = *w1 = *w2 = '\0';
		ptr = strchr(buf, ' ');
		if (ptr == NULL) {
			ptr = strchr(buf, '\t');
		}
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr == ' '; ptr++)
				;
			strncpy(w0, buf, sizeof(w0) - 1);
			strncpy(w1, ptr, sizeof(w1) - 1);
			optr = ptr;
			ptr = strchr(ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr == ' '; ptr++)
					;
				strncpy(w1, optr, sizeof(w1) - 1);
				strncpy(w2, ptr, sizeof(w2) - 1);
			}
		} else {
			strncpy(w0, buf, sizeof(w0) - 1);
		}

		const char *wa[] = {w0, w1, w2};
		int nw = 0;
		for (i = 0; i < 3; i++) {
			if (wa[i][0]) {
				nw++;
			}
		}
		replace(nw, wa, str, atype);
	}

	free(buf);

	return true;
}
Exemple #2
0
R_API int r_num_conditional(RNum *num, const char *str) {
	char *lgt, *t, *p, *s = strdup (str);
	int res = 0;
	ut64 n, a, b;
	p = s;
	do {
		t = strchr (p, ',');
		if (t) *t = 0;
		lgt = strchr (p, '<');
		if (lgt) {
			*lgt = 0;
			a = r_num_math (num, p);
			if (lgt[1]=='=') {
				b = r_num_math (num, lgt+2);
				if (a>b) goto fail;
			} else {
				b = r_num_math (num, lgt+1);
				if (a>=b) goto fail;
			}
		} else {
			lgt = strchr (p, '>');
			if (lgt) {
				*lgt = 0;
				a = r_num_math (num, p);
				if (lgt[1]=='=') {
					b = r_num_math (num, lgt+2);
					if (a<b) goto fail;
				} else {
					b = r_num_math (num, lgt+1);
					if (a<=b) goto fail;
				}
			} else {
				lgt = strchr (p, '=');
				if (lgt && lgt > p) {
					lgt--;
					if (*lgt=='!') {
						r_str_replace_char (p, '!', ' ');
						r_str_replace_char (p, '=', '-');
						n = r_num_math (num, p);
						if (!n) goto fail;
					}
				}
				lgt = strstr (p, "==");
				if (lgt) *lgt = ' ';
				r_str_replace_char (p, '=', '-');
				n = r_num_math (num, p);
				if (n) goto fail;
			}
		}
		p = t+1;
	} while (t);
	res = 1;
fail:
	free (s);
	return res;
}
bool test_r_str_replace_char(void) {
	char* str = strdup ("hello world");
	(void) r_str_replace_char (str, 'l', 'x');
	mu_assert_streq (str, "hexxo worxd", "error, replace char multi failed");
	free (str);
	mu_end;
}
Exemple #4
0
R_API void r_cons_pal_list(int rad, const char *arg) {
	char *name, **color;
	const char *hasnext;
	int i;
	if (rad == 'j') {
		r_cons_print ("{");
	}
	for (i = 0; keys[i].name; i++) {
		RColor *rcolor = RCOLOR_AT (i);
		color = COLOR_AT (i);
		switch (rad) {
		case 'j':
			hasnext = (keys[i + 1].name) ? "," : "";
			r_cons_printf ("\"%s\":[%d,%d,%d]%s",
				keys[i].name, rcolor->r, rcolor->g, rcolor->b, hasnext);
			break;
		case 'c': {
			const char *prefix = r_str_trim_ro (arg);
			if (!prefix) {
				prefix = "";
			}
			hasnext = (keys[i + 1].name) ? "\n" : "";
			// TODO Need to replace the '.' char because this is not valid CSS
			char *name = strdup (keys[i].name);
			int j, len = strlen (name);
			for (j = 0; j < len; j++) {
				if (name[j] == '.') {
					name[j] = '_';
				}
			}
			r_cons_printf (".%s%s { color: rgb(%d, %d, %d); }%s",
				prefix, name, rcolor->r, rcolor->g, rcolor->b, hasnext);
			free (name);
			}
			break;
		case 'h':
			name = strdup (keys[i].name);
			r_str_replace_char (name, '.', '_');
			r_cons_printf (".%s { color:#%02x%02x%02x }\n",
				name, rcolor->r, rcolor->g, rcolor->b);
			free (name);
			break;
		case '*':
		case 'r':
		case 1:
			r_cons_printf ("ec %s rgb:%02x%02x%02x\n",
				keys[i].name, rcolor->r, rcolor->g, rcolor->b);
			break;
		default:
			r_cons_printf (" %s##"Color_RESET"  %s\n", *color,
				keys[i].name);
		}
	}
	if (rad == 'j') {
		r_cons_print ("}\n");
	}
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	cs_insn* insn;
	int mode, n, ret = -1;
	mode = CS_MODE_BIG_ENDIAN;
	if (!op) {
		return 0;
	}
	// mode |= (a->bits == 64)? CS_MODE_64: CS_MODE_32;
	memset (op, 0, sizeof (RAsmOp));
	op->size = 4;
	if (cd != 0) {
		cs_close (&cd);
	}
	ret = cs_open (CS_ARCH_TMS320C64X, mode, &cd);
	if (ret) {
		goto fin;
	}
	if (a->syntax == R_ASM_SYNTAX_REGNUM) {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
	} else {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
	}
	cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	n = cs_disasm (cd, (ut8*)buf, len, a->pc, 1, &insn);
	if (n < 1) {
		strcpy (op->buf_asm, "invalid");
		op->size = 4;
		goto beach;
	} else {
		ret = 4;
	}
	if (insn->size < 1) {
		goto beach;
	}
	op->size = insn->size;
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
		insn->mnemonic, insn->op_str[0]? " ": "",
		insn->op_str);
	// r_str_replace_in (op->buf_asm, sizeof (op->buf_asm), "*+", "", 1);
	// nasty, the disasm output comes with tabs and uppercase :(
	r_str_replace_char (op->buf_asm, '\t', 0);
	// r_str_replace_in (op->buf_asm, sizeof (op->buf_asm), "\t", "", 1);
	r_str_case (op->buf_asm, false);
	cs_free (insn, n);
beach:
	// cs_close (&cd);
fin:
	return op->size;
}
Exemple #6
0
R_API bool r_run_parse(RRunProfile *pf, const char *profile) {
	if (!pf || !profile) {
		return false;
	}
	char *p, *o, *str = strdup (profile);
	if (!str) {
		return false;
	}
	r_str_replace_char (str, '\r',0);
	for (p = str; (o = strchr (p, '\n')); p = o) {
		*o++ = 0;
		r_run_parseline (pf, p);
	}
	free (str);
	return true;
}
Exemple #7
0
static int typelist (void *p, const char *k, const char *v) {
	r_cons_printf ("tk %s = %s\n", k, v);
#if 0
	if (!strcmp (v, "func")) {
		const char *rv = sdb_const_get (DB,
						sdb_fmt (0, "func.%s.ret", k), 0);
		r_cons_printf ("# %s %s(", rv, k);
		for (i = 0; i < 16; i++) {
			char *av = sdb_get (DB,
					sdb_fmt (0, "func.%s.arg.%d", k, i), 0);
			if (!av) break;
			r_str_replace_char (av, ',', ' ');
			r_cons_printf ("%s%s", i? ", ": "", av);
			free (av);
		}
		r_cons_printf (");\n");
		// signature in pf for asf
		r_cons_printf ("asf %s=", k);
		// formats
		for (i = 0; i < 16; i++) {
			const char *fmt;
			char *comma, *av = sdb_get (DB,
						sdb_fmt (0, "func.%s.arg.%d", k, i), 0);
			if (!av) break;
			comma = strchr (av, ',');
			if (comma) *comma = 0;
			fmt = sdb_const_get (DB, sdb_fmt (0, "type.%s", av), 0);
			r_cons_printf ("%s", fmt);
			if (comma) *comma = ',';
			free (av);
		}
		// names
		for (i = 0; i < 16; i++) {
			char *comma, *av = sdb_get (DB,
						sdb_fmt (0, "func.%s.arg.%d", k, i), 0);
			if (!av) break;
			comma = strchr (av, ',');
			if (comma) *comma++ = 0;
			r_cons_printf (" %s", comma);
			free (av);
		}
		r_cons_newline ();
	}
#endif
	return 1;
}
Exemple #8
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	csh handle;
	cs_insn* insn;
	int mode, n, ret = -1;
	mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;
	if (a->cpu && *a->cpu) {
		if (!strcmp (a->cpu, "gp64")) {
			mode |= CS_MODE_MIPSGP64;
		} else if (!strcmp (a->cpu, "micro")) {
			mode |= CS_MODE_MICRO;
		} else if (!strcmp (a->cpu, "r6")) {
			mode |= CS_MODE_MIPS32R6;
		} else if (!strcmp (a->cpu, "v3")) {
			mode |= CS_MODE_MIPS3;
		}
	}
	mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32;
	memset (op, 0, sizeof (RAsmOp));
	op->size = 4;
	ret = cs_open (CS_ARCH_MIPS, mode, &handle);
	if (ret) goto fin;
	if (a->syntax == R_ASM_SYNTAX_REGNUM) {
		cs_option (handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
	} else cs_option (handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_OFF);
	n = cs_disasm (handle, (ut8*)buf, len, a->pc, 1, &insn);
	if (n<1) {
		strcpy (op->buf_asm, "invalid");
		op->size = 4;
		ret = -1;
		goto beach;
	} else ret = 4;
	if (insn->size<1)
		goto beach;
	op->size = insn->size;
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
		insn->mnemonic, insn->op_str[0]? " ": "",
		insn->op_str);
	// remove the '$'<registername> in the string
	r_str_replace_char (op->buf_asm, '$', 0);
	cs_free (insn, n);
	beach:
	cs_close (&handle);
	fin:
	return op->size;
}
Exemple #9
0
static int tms320c64x_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	cs_insn* insn;
	int n = -1, ret = -1;
	int mode = 0;
	if (op) {
		memset (op, 0, sizeof (RAsmOp));
		op->size = 4;
	}
	if (cd != 0) {
		cs_close (&cd);
	}
	ret = cs_open (CS_ARCH_TMS320C64X, mode, &cd);
	if (ret) {
		goto fin;
	}
	cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	if (!op) {
		return 0;
	}
	n = cs_disasm (cd, buf, len, a->pc, 1, &insn);
	if (n < 1) {
		r_asm_op_set_asm (op, "invalid");
		op->size = 4;
		ret = -1;
		goto beach;
	} else {
		ret = 4;
	}
	if (insn->size < 1) {
		goto beach;
	}
	op->size = insn->size;
	char *buf_asm = sdb_fmt ("%s%s%s", insn->mnemonic, insn->op_str[0]? " ": "", insn->op_str);
	r_str_replace_char (buf_asm, '%', 0);
	r_str_case (buf_asm, false);
	r_asm_op_set_asm (op, buf_asm);
	cs_free (insn, n);
	beach:
	// cs_close (&cd);
	fin:
	return ret;
}
Exemple #10
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;
}
Exemple #11
0
R_API void r_cons_pal_list (int rad, const char *arg) {
	RConsPalette *pal = & (r_cons_singleton ()->pal);
	ut8 r, g, b, *p = (ut8*)pal;
	char *name, **color, rgbstr[32];
	const char *hasnext;
	int i;
	if (rad == 'j') r_cons_print ("{");
	for (i = 0; keys[i].name; i++) {
		color = (char**) (p + keys[i].off);
		switch (rad) {
		case 'j':
			r = g = b = 0;
			r_cons_rgb_parse (*color, &r, &g, &b, NULL);
			hasnext = (keys[i + 1].name) ? "," : "";
			r_cons_printf ("\"%s\":[%d,%d,%d]%s",
				keys[i].name, r, g, b, hasnext);
			break;
		case 'c': {
			const char *prefix = r_str_chop_ro (arg);
			if (!prefix) {
				prefix = "";
			}
			r = g = b = 0;
			r_cons_rgb_parse (*color, &r, &g, &b, NULL);
			hasnext = (keys[i + 1].name) ? "\n" : "";
			//Need to replace the '.' char because this is not
			//valid CSS
			char *name = strdup (keys[i].name);
			int j, len = strlen (name);
			for (j = 0; j < len; j++) {
				if (name[j] == '.') {
					name[j] = '_';
				}
			}
			r_cons_printf (".%s%s { color: rgb(%d, %d, %d); }%s",
				prefix, name, r, g, b, hasnext);
			free (name);
			}
			break;
		case 'h':
			r = g = b = 0;
			r_cons_rgb_parse (*color, &r, &g, &b, NULL);
			rgbstr[0] = 0;
			name = strdup (keys[i].name);
			r_str_replace_char (name, '.', '_');
			r_cons_printf (".%s { color:#%02x%02x%02x }\n",
				name, r, g, b);
			free (name);
			break;
		case '*':
		case 'r':
		case 1:
			r = g = b = 0;
			r_cons_rgb_parse (*color, &r, &g, &b, NULL);
			rgbstr[0] = 0;
			r_cons_rgb_str (rgbstr, r, g, b, 0);
			r_cons_printf ("ec %s rgb:%02x%02x%02x\n",
				keys[i].name, r, g, b);
			break;
		default:
			r_cons_printf (" %s##"Color_RESET"  %s\n", *color,
				keys[i].name);
		}
	}
	if (rad == 'j') r_cons_print ("}\n");
}
Exemple #12
0
static int parse(RParse *p, const char *data, char *str) {
	int i, len = strlen (data);
	char w0[WSZ];
	char w1[WSZ];
	char w2[WSZ];
	char w3[WSZ];
	char w4[WSZ];
	char *buf, *ptr, *optr;

	if (!strcmp (data, "jr ra")) {
		strcpy (str, "ret");
		return true;
	}

	// malloc can be slow here :?
	if (!(buf = malloc (len + 1))) {
		return false;
	}
	memcpy (buf, data, len+1);

	r_str_replace_char (buf, '(', ',');
	r_str_replace_char (buf, ')', ' ');
	r_str_trim (buf);

	if (*buf) {
		w0[0]='\0';
		w1[0]='\0';
		w2[0]='\0';
		w3[0]='\0';
		w4[0]='\0';
		ptr = strchr (buf, ' ');
		if (!ptr) {
			ptr = strchr (buf, '\t');
		}
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr == ' '; ptr++) {
				;
			}
			strncpy (w0, buf, WSZ - 1);
			strncpy (w1, ptr, WSZ - 1);

			optr=ptr;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr == ' '; ptr++) {
					;
				}
				strncpy (w1, optr, WSZ - 1);
				strncpy (w2, ptr, WSZ - 1);
				optr=ptr;
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr == ' '; ptr++) {
						;
					}
					strncpy (w2, optr, WSZ - 1);
					strncpy (w3, ptr, WSZ - 1);
					optr=ptr;
// bonus
					ptr = strchr (ptr, ',');
					if (ptr) {
						*ptr = '\0';
						for (++ptr; *ptr == ' '; ptr++) {
							;
						}
						strncpy (w3, optr, WSZ - 1);
						strncpy (w4, ptr, WSZ - 1);
					}
				}
			}
		} else {
			strncpy (w0, buf, WSZ - 1);
		}
		{
			const char *wa[] = { w0, w1, w2, w3, w4 };
			int nw = 0;
			for (i=0; i<4; i++) {
				if (wa[i][0] != '\0') {
					nw++;
				}
			}
			replace (nw, wa, str);
{
	char *p = strdup (str);
	p = r_str_replace (p, "+ -", "- ", 0);
	p = r_str_replace (p, " + ]", " + 0]", 0);

	p = r_str_replace (p, "zero", "0", 1);
	if (!strncmp (p, "0 = ", 4)) {
		*p = 0; // nop
	}
	if (!strcmp (w1, w2)) {
		char a[32], b[32];
#define REPLACE(x,y) do { \
		int snprintf_len1_ = snprintf (a, 32, x, w1, w1); \
		int snprintf_len2_ = snprintf (b, 32, y, w1);	\
		if (snprintf_len1_ < 32 && snprintf_len2_ < 32) { \
			p = r_str_replace (p, a, b, 0); \
		} \
	} while (0)

		// TODO: optimize
		REPLACE ("%s = %s +", "%s +=");
		REPLACE ("%s = %s -", "%s -=");
		REPLACE ("%s = %s &", "%s &=");
		REPLACE ("%s = %s |", "%s |=");
		REPLACE ("%s = %s ^", "%s ^=");
		REPLACE ("%s = %s >>", "%s >>=");
		REPLACE ("%s = %s <<", "%s <<=");
	}
	p = r_str_replace (p, ":", "0000", 0);
	strcpy (str, p);
	free (p);
}
		}
	}
	free (buf);
	return true;
}
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 (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 #14
0
static int replace(int argc, const char *argv[], char *newstr) {
	int i,j,k;
	struct {
		int narg;
		char *op;
		char *str;
	} ops[] = {
		{ 0, "abs",  "1 = abs(1)"},
		{ 0, "adc",  "1 = 2 + 3"},
		{ 3, "add",  "1 = 2 + 3"},
		{ 2, "add",  "1 += 2"},
		{ 2, "adds",  "1 += 2"},
		{ 3, "adds",  "1 = 2 + 3"},
		{ 3, "addw",  "1 = 2 + 3"},
		{ 3, "add.w",  "1 = 2 + 3"},
		{ 0, "adf",  "1 = 2 + 3"},
		{ 0, "adrp",  "1 = 2"},
		{ 0, "and",  "1 = 2 & 3"},
		{ 0, "ands",  "1 &= 2"},
		{ 0, "asls",  "1 = 2 << 3"},
		{ 0, "asl",  "1 = 2 << 3"},
		{ 0, "asrs",  "1 = 2 >> 3"},
		{ 0, "asr",  "1 = 2 >> 3"},
		{ 0, "b",  "jmp 1"},
		{ 0, "cbz",  "if !1 jmp 2"},
		{ 0, "cbnz",  "if 1 jmp 2"},
		{ 0, "b.w",  "jmp 1"},
		{ 0, "b.gt",  "jmp ifgt 1"},
		{ 0, "b.le",  "jmp ifle 1"},
		{ 0, "beq lr",  "ifeq ret"},
		{ 0, "beq",  "je 1"},
		{ 0, "call",  "1()"},
		{ 0, "bl",  "1()"},
		{ 0, "blx",  "1()"},
		{ 0, "bx lr",  "ret"},
		{ 0, "bxeq",  "je 1"},
		{ 0, "cmf",  "if (1 == 2)"},
		{ 0, "cmp",  "if (1 == 2)"},
		{ 0, "tst",  "if (1 == 2)"},
		{ 0, "dvf",  "1 = 2 / 3"},
		{ 0, "eor",  "1 = 2 ^ 3"},
		{ 0, "fdv",  "1 = 2 / 3"},
		{ 0, "fml",  "1 = 2 * 3"},
		{ 2, "ldr",  "1 = 2"},
		{ 2, "ldrb",  "1 = (byte) 2"},
		{ 2, "ldrsb",  "1 = (byte) 2"},
		{ 2, "ldr.w",  "1 = 2"},
		{ 2, "ldrsw",  "1 = 2"},
		{ 3, "ldr",  "1 = 2 + 3"},
		{ 3, "ldrb",  "1 = (byte) 2 + 3"},
		{ 3, "ldrsb",  "1 = (byte) 2 + 3"},
		{ 3, "ldr.w",  "1 = 2 + 3"},
		{ 3, "ldrsw",  "1 = 2 + 3"},
		{ 0, "lsl",  "1 = 2 << 3"},
		{ 0, "lsr",  "1 = 2 >> 3"},
		{ 0, "mov",  "1 = 2"},
		{ 0, "mvn",  "1 = ~2"},
		{ 0, "movz",  "1 = 2"},
		{ 0, "movk",  "1 = 2"},
		{ 0, "movn",  "1 = 2"},
		{ 0, "vmov.i32",  "1 = 2"},
		{ 0, "muf",  "1 = 2 * 3"},
		{ 0, "mul",  "1 = 2 * 3"},
		{ 0, "muls",  "1 = 2 * 3"},
		{ 0, "orr",  "1 = 2 | 3"},
		{ 0, "rmf",  "1 = 2 % 3"},
		{ 0, "bge",  "(>=) goto 1"},
		{ 0, "sbc",  "1 = 2 - 3"},
		{ 0, "sqt",  "1 = sqrt(2)"},
		{ 0, "lsrs",  "1 = 2 >> 3"},
		{ 0, "lsls",  "1 = 2 << 3"},
		{ 0, "lsr",  "1 = 2 >> 3"},
		{ 0, "lsl",  "1 = 2 << 3"},
		{ 2, "str",  "2 = 1"},
		{ 2, "strb",  "2 = (byte) 1"},
		{ 2, "strh",  "2 = (half) 1"},
		{ 2, "strh.w",  "2 = (half) 1"},
		{ 3, "str",  "2 + 3 = 1"},
		{ 3, "strb",  "2 + 3 = (byte) 1"},
		{ 3, "strh",  "2 + 3 = (half) 1"},
		{ 3, "strh.w",  "2 + 3 = (half) 1"},
		{ 3, "sub",  "1 = 2 - 3"},
		{ 3, "subs",  "1 = 2 - 3"},
		{ 2, "sub",  "1 -= 2"}, // THUMB
		{ 2, "subs",  "1 -= 2"}, // THUMB
		{ 0, "swp",  "swap(1, 2)"},
		/* arm thumb */
		{ 0, "movs",  "1 = 2"},
		{ 0, "movw",  "1 = 2"},
		{ 0, "movt",  "1 |= 2 << 16"},
		{ 0, "vmov",  "1 = (float) 2 . 3"},
		{ 0, "vdiv.f64", "1 = (float) 2 / 3" },
		{ 0, "addw",  "1 = 2 + 3"},
		{ 0, "sub.w",  "1 = 2 - 3"},
		{ 0, "tst.w", "if (1 == 2)"},
		{ 0, "lsr.w", "1 = 2 >> 3"},
		{ 0, "lsl.w", "1 = 2 << 3"},
		{ 0, "pop.w",  "pop 1"},
		{ 0, "vpop",  "pop 1"},
		{ 0, "vpush",  "push 1"},
		{ 0, "push.w",  "push 1"},
		{ 0, NULL }
	};
	if (!newstr) {
		return false;
	}

	for (i = 0; ops[i].op != NULL; i++) {
		if (ops[i].narg) {
			if (argc-1 != ops[i].narg) {
				continue;
			}
		}
		if (!strcmp (ops[i].op, argv[0])) {
			for (j = k = 0; ops[i].str[j] != '\0'; j++, k++) {
				if (IS_DIGIT(ops[i].str[j])) {
					int idx = ops[i].str[j]-'0';
					if (idx < argc) {
						const char *w = argv[idx];
						if (w) {
							strcpy (newstr + k, w);
							k += strlen (w) - 1;
						}
					}
				} else {
					newstr[k] = ops[i].str[j];
				}
			}
			newstr[k] = '\0';
			r_str_replace_char (newstr, '{', '(');
			r_str_replace_char (newstr, '}', ')');
			return true;
		}
	}

	/* TODO: this is slow */
	newstr[0] = '\0';
	for (i = 0; i < argc; i++) {
		strcat (newstr, argv[i]);
		strcat (newstr, (!i || i == argc - 1)? " " : ",");
	}
	r_str_replace_char (newstr, '{', '(');
	r_str_replace_char (newstr, '}', ')');
	return false;
}
Exemple #15
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	if (*str=='[') {
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = strchr (str+5, ':');
		ut64 n;
		// TODO: honor endian
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			char *o = strdup (str+1);
			const char *q = r_num_calc_index (core->num, NULL);
			r_str_replace_char (o, ']', 0);
			n = r_num_math (core->num, o);
			r_num_calc_index (core->num, q);
			free (o);
		}
		// pop state
		switch (refsz) {
		case 8: {
			ut64 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 4: {
			ut32 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 2: {
			ut16 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		case 1: {
			ut8 num = 0;
			r_io_read_at (core->io, n, (ut8*)&num, sizeof (num));
			return num; }
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			break;
		}
	} else
	if (str[0]=='$') {
		if (ok) *ok = 1;
		// TODO: group analop-dependant vars after a char, so i can filter
		r_anal_op (core->anal, &op, core->offset,
			core->block, core->blocksize);
		switch (str[1]) {
		case '.': // can use pc, sp, a0, a1, ...
			return r_debug_reg_get (core->dbg, str+2);
		case '{':
			bptr = strdup (str+2);
			ptr = strchr (bptr, '}');
			if (ptr != NULL) {
				ut64 ret;
				ptr[0] = '\0';
				ret = r_config_get_i (core->config, bptr);
				free (bptr);
				return ret;
			}
			break;
		case 'h': {
			int rows;
			r_cons_get_size (&rows);
			return rows;
			}
		case 'e': return op.eob;
		case 'j': return op.jump;
		case 'f': return op.fail;
		case 'r': return op.ref;
		case 'l': return op.length;
		case 'b': return core->blocksize;
		case 's': return core->file->size;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_get (core->io, 
				r_io_section_vaddr_to_offset (core->io,
				core->offset));
			return s? (str[2]=='S'? s->size: s->offset): 0;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return core->io->off;
		case 'C': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CALL);
		case 'J': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CODE);
		case 'D': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_DATA);
		case 'X': return getref (core, atoi (str+2), 'x',
				R_ANAL_REF_TYPE_CALL);
		case 'I':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
	} else
	if (*str>'A') {
		if ((flag = r_flag_get (core->flags, str))) {
			ret = flag->offset;
			if (ok) *ok = R_TRUE;
		}
	}
	return ret;
}
Exemple #16
0
static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) {
	RList *regs, *bpargs, *spargs;
	RAnalVar *reg, *bparg, *sparg;
	RListIter *regiter, *bpargiter, *spiter;
	char oldstr[64], newstr[64];
	char *tstr = strdup (data);
	if (!tstr) {
		return false;
	}

	bool att = strchr (data, '%');

	if (p->relsub) {
		if (att) {
			char *rip = (char *) r_str_casestr (tstr, "(%rip)");
			if (rip) {
				*rip = 0;
				char *pre = tstr;
				char *pos = rip + 6;
				char *word = strchr (tstr, ' ');
				if (word) {
					*word++ = 0;
					*rip = 0;
					st64 n = r_num_math (NULL, word);
					ut64 repl_num = oplen + addr + n;
					char *tstr_new = r_str_newf ("%s 0x%08"PFMT64x"%s", pre, repl_num, pos);
					*rip = '(';
					free (tstr);
					tstr = tstr_new;
				}
			}
		} else {
			char *rip = (char *) r_str_casestr (tstr, "[rip");
			if (rip) {
				char *ripend = strchr (rip + 3, ']');
				const char *plus = strchr (rip, '+');
				const char *neg = strchr (rip, '-');
				char *tstr_new;
				ut64 repl_num = oplen + addr;

				if (!ripend) {
					ripend = "]";
				}
				if (plus) {
					repl_num += r_num_get (NULL, plus + 1);
				}
				if (neg) {
					repl_num -= r_num_get (NULL, neg + 1);
				}

				rip[1] = '\0';
				tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend);
				free (tstr);
				tstr = tstr_new;
				if (!strncasecmp (tstr, "lea", 3)) {
					r_str_replace_char (tstr, '[', 0);
					r_str_replace_char (tstr, ']', 0);
				}
			}
		}
	}

	if (!p->varlist) {
                free (tstr);
		return false;
        }
	regs = p->varlist (p->anal, f, 'r');
	bpargs = p->varlist (p->anal, f, 'b');
	spargs = p->varlist (p->anal, f, 's');
	/*iterate over stack pointer arguments/variables*/
	bool ucase = *tstr >= 'A' && *tstr <= 'Z';
	if (ucase && tstr[1]) {
		ucase = tstr[1] >= 'A' && tstr[1] <= 'Z';
	}
	r_list_foreach (spargs, spiter, sparg) {
		// assuming delta always positive?
		mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, oldstr, sizeof (oldstr));

		if (ucase) {
			r_str_case (oldstr, true);
		}
		parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', att);
		if (ucase) {
			char *plus = strchr (newstr, '+');
			if (plus) {
				*plus = 0;
				r_str_case (newstr, true);
				*plus = '+';
			} else {
				r_str_case (newstr, true);
			}
		}
		char *ptr = strstr(tstr, oldstr);
		if (ptr && (!att || *(ptr - 1) == ' ')) {
			tstr = r_str_replace (tstr, oldstr, newstr, 1);
			break;
		} else {
			r_str_case (oldstr, false);
			ptr = strstr(tstr, oldstr);
			if (ptr && (!att || *(ptr - 1) == ' ')) {
				tstr = r_str_replace (tstr, oldstr, newstr, 1);
				break;
			}
		}
	}
Exemple #17
0
static int parse(RParse *p, const char *data, char *str) {
	int i, n;
	char w0[32];
	char w1[32];
	char w2[32];
	char w3[32];
	char *buf, *ptr, *optr, *num;

	// malloc can be slow here :?
	buf = strdup (data);
	r_str_trim_head (buf);

	ptr = strchr (buf, '#');
	if (ptr) {
		*ptr = 0;
		r_str_chop (buf);
	}
	if (*buf == '.' || buf[strlen(buf)-1] == ':') {
		free (buf);
		strcpy (str, data);
		return R_TRUE;
	}
	r_str_replace_char (buf, '$', 0);
	r_str_replace_char (buf, '%', 0);
	r_str_replace_char (buf, '\t', ' ');
	r_str_replace_char (buf, '(', '[');
	r_str_replace_char (buf, ')', ']');
	ptr = strchr (buf, '[');
	if (ptr) {
		*ptr = 0;
		num = (char*)r_str_lchr (buf, ' ');
		if (!num)
			num = (char*)r_str_lchr (buf, ',');
		if (num) {
			n = atoi (num+1);
			*ptr = '[';
			memmove (num+1, ptr, strlen (ptr)+1);
			ptr = (char*)r_str_lchr (buf, ']');
			if (n && ptr) {
				char *rest = strdup (ptr+1);
				if(n>0) sprintf (ptr, "+%d]%s", n, rest);
				else sprintf (ptr, "%d]%s", n, rest);
				free (rest);
			}
		} else *ptr = '[';
	}

	if (*buf) {
		*w0 = *w1 = *w2 = *w3 = 0;
		ptr = strchr (buf, ' ');
		if (ptr == NULL)
			ptr = strchr (buf, '\t');
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr==' '; ptr++);
			strncpy (w0, buf, sizeof(w0) - 1);
			strncpy (w1, ptr, sizeof(w1) - 1);

			optr = ptr;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr==' '; ptr++);
				strncpy (w1, optr, sizeof(w1)-1);
				strncpy (w2, ptr, sizeof(w2)-1);
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr==' '; ptr++);
					strncpy (w2, optr, sizeof(w2)-1);
					strncpy (w3, ptr, sizeof(w3)-1);
				}
			}
		}
		{
			const char *wa[] = { w0, w1, w2, w3 };
			int nw = 0;
			for (i=0; i<4; i++) {
				if (wa[i][0] != '\0')
				nw++;
			}
			replace (nw, wa, str);
		}
	}
	free (buf);
	return R_TRUE;
}
static int parse(RParse *p, const char *data, char *str) {
	int i, len = strlen (data);
	char w0[WSZ];
	char w1[WSZ];
	char w2[WSZ];
	char w3[WSZ];
	char w4[WSZ];
	char *buf, *ptr, *optr;

	if (!strcmp (data, "jr ra")) {
		strcpy (str, "ret");
		return R_TRUE;
	}

	// malloc can be slow here :?
	if ((buf = malloc (len+1)) == NULL)
		return R_FALSE;
	memcpy (buf, data, len+1);

	r_str_replace_char (buf, '(', ',');
	r_str_replace_char (buf, ')', ' ');
	r_str_chop (buf);

	if (*buf) {
		w0[0]='\0';
		w1[0]='\0';
		w2[0]='\0';
		w3[0]='\0';
		w4[0]='\0';
		ptr = strchr (buf, ' ');
		if (ptr == NULL)
			ptr = strchr (buf, '\t');
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr==' '; ptr++);
			strncpy (w0, buf, WSZ - 1);
			strncpy (w1, ptr, WSZ - 1);

			optr=ptr;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr==' '; ptr++);
				strncpy (w1, optr, WSZ - 1);
				strncpy (w2, ptr, WSZ - 1);
				optr=ptr;
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr==' '; ptr++);
					strncpy (w2, optr, WSZ - 1);
					strncpy (w3, ptr, WSZ - 1);
					optr=ptr;
// bonus
					ptr = strchr (ptr, ',');
					if (ptr) {
						*ptr = '\0';
						for (++ptr; *ptr==' '; ptr++);
						strncpy (w3, optr, WSZ - 1);
						strncpy (w4, ptr, WSZ - 1);
					}
				}
			}
		}
		{
			const char *wa[] = { w0, w1, w2, w3, w4 };
			int nw = 0;
			for (i=0; i<4; i++) {
				if (wa[i][0] != '\0')
				nw++;
			}
			replace (nw, wa, str);
{
	char *p = strdup (str);
	p = r_str_replace (p, "+ -", "- ", 0);
#if EXPERIMENTAL_ZERO
	p = r_str_replace (p, "zero", "0", 0);
	if (!memcmp (p, "0 = ", 4)) *p = 0; // nop
#endif
	if (!strcmp (w1, w2)) {
		char a[32], b[32];
#define REPLACE(x,y) \
		sprintf (a, x, w1, w1); \
		sprintf (b, y, w1); \
		p = r_str_replace (p, a, b, 0);

// TODO: optimize
		REPLACE ("%s = %s +", "%s +=");
		REPLACE ("%s = %s -", "%s -=");
		REPLACE ("%s = %s &", "%s &=");
		REPLACE ("%s = %s |", "%s |=");
		REPLACE ("%s = %s ^", "%s ^=");
		REPLACE ("%s = %s >>", "%s >>=");
		REPLACE ("%s = %s <<", "%s <<=");
	}
	p = r_str_replace (p, ":", "0000", 0);
	strcpy (str, p);
	free (p);
}
		}
	}
	free (buf);
	return R_TRUE;
}
Exemple #19
0
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr, *out;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

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

	if (p->relsub) {
		char *rip = strstr (tstr, "[rip");
		if (rip) {
			char *ripend = strchr (rip + 3, ']');
			const char *plus = strchr (rip, '+');
			const char *neg = strchr (rip, '-');
			char *tstr_new;
			ut64 repl_num = oplen + addr;

			if (!ripend) ripend = "]";
			if (plus) repl_num += r_num_get (NULL, plus + 1);
			if (neg) repl_num -= r_num_get (NULL, neg + 1);

			rip[1] = '\0';
			tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend);
			free (tstr);
			tstr = tstr_new;
			if (!strncmp (tstr, "lea", 3)) {
				r_str_replace_char (tstr, '[', 0);
				r_str_replace_char (tstr, ']', 0);
			}
		}
	}

	if (!p->varlist) {
                free (tstr);
		return false;
        }
	regs = p->varlist (p->anal, f, 'v');
	bpargs = p->varlist (p->anal, f, 'a');
	spargs = p->varlist (p->anal, f, 'e');
	/*iterate over stack pointer arguments/variables*/
	r_list_foreach (spargs, spiter,sparg) {
		if (sparg->delta < 10) {
			snprintf (oldstr, sizeof (oldstr)-1, "[%s + %d]",
				p->anal->reg->name[R_REG_NAME_SP], sparg->delta);
		} else {
			snprintf (oldstr, sizeof (oldstr)-1, "[%s + 0x%x]",
				p->anal->reg->name[R_REG_NAME_SP], sparg->delta);
		}
		snprintf (newstr, sizeof (newstr)-1, "[%s + %s]",
			p->anal->reg->name[R_REG_NAME_SP],
			sparg->name);
		if (strstr (tstr, oldstr)) {
			tstr = r_str_replace (tstr, oldstr, newstr, 1);
			break;
		} else {
			r_str_case (oldstr, false);
			if (strstr (tstr, oldstr)) {
				tstr = r_str_replace (tstr, oldstr, newstr, 1);
				break;
			}
		}
	}
	/* iterate over base pointer args/vars */
	r_list_foreach (bpargs, bpargiter, bparg) {
		char sign = '+';
		if (bparg->delta < 0) {
			sign = '-';
			bparg->delta = -bparg->delta;
		}
		if (bparg->delta < 10) snprintf (oldstr, sizeof (oldstr)-1,
			"[%s %c %d]",
			p->anal->reg->name[R_REG_NAME_BP],
			sign, bparg->delta);
		else snprintf (oldstr, sizeof (oldstr)-1,
			"[%s %c 0x%x]",
			p->anal->reg->name[R_REG_NAME_BP],
			sign, bparg->delta);
		snprintf (newstr, sizeof (newstr)-1, "[%s %c %s]",
			p->anal->reg->name[R_REG_NAME_BP], sign,
			bparg->name);
		if (strstr (tstr, oldstr) != NULL) {
			tstr = r_str_replace (tstr, oldstr, newstr, 1);
			break;
		} else {
			r_str_case (oldstr, false);
			if (strstr (tstr, oldstr) != NULL) {
				tstr = r_str_replace (tstr, oldstr, newstr, 1);
				break;
			}
		}
		// Try with no spaces
		snprintf (oldstr, sizeof (oldstr)-1, "[%s%c0x%x]",
			p->anal->reg->name[R_REG_NAME_BP], sign,
			bparg->delta);
		if (strstr (tstr, oldstr) != NULL) {
			tstr = r_str_replace (tstr, oldstr, newstr, 1);
			break;
		}
	}