Пример #1
0
static char *getstr(const char *src) {
	int len;
	char *ret = NULL;

	switch (*src) {
	case '\'':
		ret = strdup (src+1);
		if (ret) {
			len = strlen (ret);
			if (len>0) {
				len--;
				if (ret[len]=='\'') {
					ret[len] = 0;
					return ret;
				} else eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '"':
		ret = strdup (src+1);
		if (ret) {
			len = strlen (ret);
			if (len>0) {
				len--;
				if (ret[len]=='"') {
					ret[len] = 0;
					r_str_unescape (ret);
					return ret;
				} else eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '@':
		// slurp file
		return r_file_slurp (src+1, NULL);
	case ':':
		// hexpairs
		ret = strdup (src);
		len = r_hex_str2bin (src+1, (ut8*)ret);
		if (len>0) {
			ret[len] = 0;
			return ret;
		} else {
			eprintf ("Invalid hexpair string\n");
			free (ret);
			return NULL;
		}
	}
	r_str_unescape ((ret = strdup (src)));
	return ret;
}
Пример #2
0
int main() {
	RSocket *s = r_socket_new (R_FALSE);
	if (!r_socket_listen (s, "8080", NULL)) {
		eprintf ("Cannot listen here\n");
		return 1;
	}
	for (;;) {
		RSocketHTTPRequest *rs = r_socket_http_accept (s, 0);
		if (!rs) continue;
		if (!strcmp (rs->method, "GET")) {
			r_socket_http_response (rs, 200,
			"<html><body><form method=post action=/>"
			"<input name=a /><input type=button></form></body>");
		} else 
		if (!strcmp (rs->method, "POST")) {
			char *buf = malloc (rs->data_length+ 50);
			strcpy (buf, "<html><body><h2>XSS test</h2>\n");
			r_str_unescape (rs->data);
			strcat (buf, rs->data);
			r_socket_http_response (rs, 200, buf);
			free (buf);
		} else {
			r_socket_http_response (rs, 404, "Invalid protocol");
		}
		r_socket_http_close (rs);
	}
}
Пример #3
0
static int cmd_meta_comment(RCore *core, const char *input) {
	ut64 addr = core->offset;
	switch (input[1]) {
	case '?': {
		const char* help_msg[] = {
			"Usage:", "CC[-+!*au] [base64:..|str] @ addr", "",
			"CC", "", "list all comments in human friednly form",
			"CC*", "", "list all comments in r2 commands",
			"CC.", "", "show comment at current offset",
			"CC", " or maybe not", "append comment at current address",
			"CC+", " same as above", "append comment at current address",
			"CC!", "", "edit comment using cfg.editor (vim, ..)",
			"CC-", " @ cmt_addr", "remove comment at given address",
			"CCu", " good boy @ addr", "add good boy comment at given address",
			"CCu", " base64:AA== @ addr", "add comment in base64",
			NULL};
		r_core_cmd_help (core, help_msg);
		} break;
	case '.':
		  {
			  char *comment = r_meta_get_string (
					  core->anal, R_META_TYPE_COMMENT, addr);
			  if (comment) {
				  r_cons_printf ("%s\n", comment);
				  free (comment);
			  }
		  }
		break;
	case 0:
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 0);
		break;
	case '!':
		{
			char *out, *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			out = r_core_editor (core, NULL, comment);
			if (out) {
				//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
				r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
				//r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL);
				r_meta_set_string (core->anal,
						R_META_TYPE_COMMENT, addr, out);
				free (out);
			}
			free (comment);
		}
		break;
	case '+':
	case ' ':
		{
		const char* newcomment = input+2;
		char *text, *nc;
		while (*newcomment==' ') newcomment++;
		char *comment = r_meta_get_string (
				core->anal, R_META_TYPE_COMMENT, addr);
		nc = strdup (newcomment);
		r_str_unescape (nc);
		if (comment) {
			text = malloc (strlen (comment)+strlen (newcomment)+2);
			strcpy (text, comment);
			strcat (text, "\n");
			strcat (text, nc);
			r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
					addr, text);
			free (text);
		} else {
			r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
					addr, nc);
		}
		free (nc);
		}
		break;
	case '*':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 1);
		break;
	case '-':
		r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL);
		break;
	case 'u':
		//
		{
		char *newcomment;
		const char *arg = input+2;
		while (*arg && *arg == ' ') arg++;
		if (!strncmp (arg, "base64:", 7)) {
			char *s = (char *)sdb_decode (arg+7, NULL);
			if (s) {
				newcomment = s;
			} else {
				newcomment = NULL;
			}
		} else {
			newcomment = strdup (arg);
		}
		if (newcomment) {
			char *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			if (!comment || (comment && !strstr (comment, newcomment))) {
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
						addr, newcomment);
			}
			free (comment);
			free (newcomment);
		}
		}
		break;
	case 'a':
		{
		char *s, *p;
		s = strchr (input, ' ');
		if (s) {
			s = strdup (s+1);
		} else {
			eprintf ("Usage\n");
			return R_FALSE;
		}
		p = strchr (s, ' ');
		if (p) *p++ = 0;
		ut64 addr;
		if (input[2]=='-') {
			if (input[3]) {
				addr = r_num_math (core->num, input+3);
				r_meta_del (core->anal,
						R_META_TYPE_COMMENT,
						addr, 1, NULL);
			} else eprintf ("Usage: CCa-[address]\n");
			free (s);
			return R_TRUE;
		}
		addr = r_num_math (core->num, s);
		// Comment at
		if (p) {
			if (input[2]=='+') {
				char *text = p;
				char *comment = r_meta_get_string (
						core->anal, R_META_TYPE_COMMENT,
						addr);
				if (comment) {
					text = malloc (strlen (comment) + strlen (p)+2);
					strcpy (text, comment);
					strcat (text, "\n");
					strcat (text, p);
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, text);
					free (text);
				} else {
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, p);
				}
			} else {
				r_meta_add (core->anal,
						R_META_TYPE_COMMENT,
						addr, addr+1, p);
			}
		} else eprintf ("Usage: CCa [address] [comment]\n");
		free (s);
		return R_TRUE;
		}
	}

	return R_TRUE;
}
Пример #4
0
int main(int argc, char **argv) {
	int i, ret, c, rad = 0, bsize = 0, numblocks = 0, ule = 0, b64mode = 0;
	const char *algo = "sha256"; /* default hashing algorithm */
	const char *seed = NULL;
	char *hashstr = NULL;
	int hashstr_len = 0;
	int hashstr_hex = 0;
	ut64 algobit;
	RHash *ctx;
	RIO *io;

	while ((c = getopt (argc, argv, "jdDrvea:i:S:s:x:b:nBhf:t:kLq")) != -1) {
		switch (c) {
		case 'q': quiet = 1; break;
		case 'i': iterations = atoi (optarg);
			if (iterations<0) {
				eprintf ("error: -i argument must be positive\n");
				return 1;
			}
			break;
		case 'j': rad = 'j'; break;
		case 'S': seed = optarg; break;
		case 'n': numblocks = 1; break;
		case 'd': b64mode = 1; break;
		case 'D': b64mode = 2; break;
		case 'L': algolist (); return 0;
		case 'e': ule = 1; break;
		case 'r': rad = 1; break;
		case 'k': rad = 2; break;
		case 'a': algo = optarg; break;
		case 'B': incremental = 0; break;
		case 'b': bsize = (int)r_num_math (NULL, optarg); break;
		case 'f': from = r_num_math (NULL, optarg); break;
		case 't': to = 1+r_num_math (NULL, optarg); break;
		case 'v': return blob_version ("rahash2");
		case 'h': return do_help (0);
		case 's': setHashString (optarg, 0); break;
		case 'x': setHashString (optarg, 1); break;
			break;
		default: eprintf ("rahash2: Unknown flag\n"); return 1;
		}
	}
	if ((st64)from>=0 && (st64)to<0) {
		to = 0; // end of file
	}
	if (from || to) {
		if (to && from>=to) {
			eprintf ("Invalid -f or -t offsets\n");
			return 1;
		}
	}
	do_hash_seed (seed);
	if (hashstr) {
#define INSIZE 32768
		if (!strcmp (hashstr, "-")) {
			int res = 0;
			hashstr = malloc (INSIZE);
			if (!hashstr)
				return 1;
			res = fread ((void*)hashstr, 1, INSIZE-1, stdin);
			if (res<1) res = 0;
			hashstr[res] = '\0';
			hashstr_len = res;
		}
		if (hashstr_hex) {
			ut8 *out = malloc ((strlen (hashstr)+1)*2);
			hashstr_len = r_hex_str2bin (hashstr, out);
			if (hashstr_len<1) {
				eprintf ("Invalid hex string\n");
				free (out);
			}
			hashstr = (char *)out;
			/* out memleaks here, hashstr can't be freed */
		} else {
			hashstr_len = strlen (hashstr);
		}
		if (from) {
			if (from>=hashstr_len) {
				eprintf ("Invalid -f.\n");
				return 1;
			}
		}
		if (to) {
			if (to>hashstr_len) {
				eprintf ("Invalid -t.\n");
				return 1;
			}
		} else {
			to = hashstr_len;
		}
		hashstr = hashstr+from;
		hashstr_len = to-from;
		hashstr[hashstr_len] = '\0';
		hashstr_len = r_str_unescape (hashstr);
		switch (b64mode) {
		case 1: // encode
			{
			char *out = malloc (((hashstr_len+1)*4)/3);
			if (out) {
				r_base64_encode (out, (const ut8*)hashstr, hashstr_len);
				printf ("%s\n", out);
				fflush (stdout);
				free (out);
			}
			}
			break;
		case 2: // decode
			{
			ut8 *out = malloc (INSIZE);
			if (out) {
				int outlen = r_base64_decode (out,
					(const char *)hashstr, hashstr_len);
				write (1, out, outlen);
				free (out);
			}
			}
		       break;
		default:
			{
			       char *str = (char *)hashstr;
			       int strsz = hashstr_len;
			       if (_s) {
				       // alloc/concat/resize
				       str = malloc (strsz + s.len);
				       if (s.prefix) {
					       memcpy (str, s.buf, s.len);
					       memcpy (str+s.len, hashstr, hashstr_len);
				       } else {
					       memcpy (str, hashstr, hashstr_len);
					       memcpy (str+strsz, s.buf, s.len);
				       }
				       strsz += s.len;
				       str[strsz] = 0;
			       }
			       algobit = r_hash_name_to_bits (algo);
			       for (i=1; i<0x800000; i<<=1) {
				       if (algobit & i) {
					       int hashbit = i & algobit;
					       ctx = r_hash_new (R_TRUE, hashbit);
					       from = 0;
					       to = strsz;
					       do_hash_internal (ctx, hashbit,
						       (const ut8*)str, strsz, rad, 1, ule);
					       r_hash_free (ctx);
				       }
			       }
			       if (_s) {
				       free (str);
				       free (s.buf);
			       }
			}
		}
		return 0;
	}
	if (optind>=argc)
		return do_help (1);
	if (numblocks) {
		bsize = -bsize;
	} else if (bsize<0) {
		eprintf ("rahash2: Invalid block size\n");
		return 1;
	}

	io = r_io_new ();
	for (ret=0, i=optind; i<argc; i++) {
		switch (b64mode) {
		case 1: // encode
			{
			int binlen;
			char *out;
			ut8 *bin = (ut8*)r_file_slurp (argv[i], &binlen);
			if (!bin) {
				eprintf ("Cannot open file\n");
				continue;
			}
			out = malloc (((binlen+1)*4)/3);
			if (out) {
				r_base64_encode (out, bin, binlen);
				printf ("%s\n", out);
				fflush (stdout);
				free (out);
			}
			free (bin);
			}
			break;
		case 2: // decode
			{
			int binlen, outlen;
			ut8 *out, *bin = (ut8*)r_file_slurp (argv[i], &binlen);
			if (!bin) {
				eprintf ("Cannot open file\n");
				continue;
			}
			out = malloc (binlen+1);
			if (out) {
				outlen = r_base64_decode (out, (const char*)bin, binlen);
				write (1, out, outlen);
				free (out);
			}
			free (bin);
			}
			break;
		default:
			if (r_file_is_directory (argv[i])) {
				eprintf ("rahash2: Cannot hash directories\n");
				return 1;
			}
			if (!r_io_open_nomap (io, argv[i], 0, 0)) {
				eprintf ("rahash2: Cannot open '%s'\n", argv[i]);
				return 1;
			}
			ret |= do_hash (argv[i], algo, io, bsize, rad, ule);
		}
	}
	free (hashstr);
	r_io_free (io);
	return ret;
}
Пример #5
0
static char *getstr(const char *src) {
	int len;
	char *ret = NULL;

	switch (*src) {
	case '\'':
		ret = strdup (src+1);
		if (ret) {
			len = strlen (ret);
			if (len>0) {
				len--;
				if (ret[len]=='\'') {
					ret[len] = 0;
					return ret;
				} else eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '"':
		ret = strdup (src+1);
		if (ret) {
			len = strlen (ret);
			if (len>0) {
				len--;
				if (ret[len]=='"') {
					ret[len] = 0;
					r_str_unescape (ret);
					return ret;
				} else eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '@':
		{
			char *pat = strchr (src+1, '@');
			if (pat) {
				*pat++ = 0;
				int i, rep = atoi (src+1);
				int len = strlen (pat);
				if (rep>0) {
					char *buf = malloc (rep);
					for(i=0;i<rep;i++) {
						buf[i] = pat[i%len];
					}
					return buf;
				}
			}
			// slurp file
			return r_file_slurp (src+1, NULL);
		}
	case '!':
		return r_str_trim_tail (r_sys_cmd_str (src+1, NULL, NULL));
	case ':':
		if (src[1]=='!') {
			ret = r_str_trim_tail (r_sys_cmd_str (src+1, NULL, NULL));
		} else {
			ret = strdup (src);
		}
		len = r_hex_str2bin (src+1, (ut8*)ret);
		if (len>0) {
			ret[len] = 0;
			return ret;
		} else {
			eprintf ("Invalid hexpair string\n");
			free (ret);
			return NULL;
		}
	}
	r_str_unescape ((ret = strdup (src)));
	return ret;
}
Пример #6
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len = strlen (input);
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename;
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa"," push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wA"," r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wF"," -|file","write contents of hexpairs file here",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo?"," hex","write in block with operation. 'wo?' fmi",
		"wp"," -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt"," file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx"," 9090","write two intel nops",
		"wv"," eip+34","write 32-64 bit value",
		NULL
	};

	if (!input)
		return 0;

	#define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y)
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup ((input&&*input)?input+1:"");
	_fn[0] = 0;

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

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

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

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

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

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


		if (cmd_suc == R_FALSE) {
			r_cons_printf ("|Usage: write extend\n"
			"wen <num>               insert num null bytes at current offset\n"
			"wex <hex_bytes>         insert bytes at current offset\n"
			"weN <addr> <len>        insert bytes at address\n"
			"weX <addr> <hex_bytes>  insert bytes at address\n"
			"wes <addr>  <dist> <block_size>   shift a blocksize left or write in the editor\n"
			);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				eprintf ("Usage: wp [-|r2patch-file]\n"
			         "TODO: rapatch format documentation here\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r':
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len>0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			r_cons_printf ("|Usage: wA [type] [value]\n"
			"|Types:\n"
			"| r   raw write value\n"
			"| v   set value (taking care of current address)\n"
			"| d   destination register\n"
			"| 0   1st src register\n"
			"| 1   2nd src register\n"
			"|Example: wA r 0 # e800000000\n");
			break;
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core, 0);
			break;
		case 'r':
			r_io_cache_reset (core->io, R_TRUE);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, R_TRUE);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, R_TRUE);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '?':
	{
                const char* help_msg[] = {
			"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
			"wc","","list all write changes",
			"wc-"," [from] [to]","remove write op at curseek or given addr",
			"wc+"," [addr]","commit change from cache to io",
			"wc*","","\"\" in radare commands",
			"wcr","","reset all write changes in cache",
			"wci","","commit write cache",
                        NULL
                        };
                        r_core_cmd_help(core, help_msg);
        }
			break;
		case '*':
			r_io_cache_list (core->io, R_TRUE);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, R_FALSE);
			break;
		}
		break;
	case ' ':
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core, 0);
		break;
	case 't': // "wt"
		if (*str == '?' || *str == '\0') {
			eprintf ("Usage: wt[a] file [size]   write 'size' bytes in current block to file\n");
			free (ostr);
			return 0;
		} else {
			int append = 0;
			st64 sz = core->blocksize;
			if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0]==' ') {
					filename = str+1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf(_fn, sizeof(_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else filename = str+1;
			tmp = strchr (str+1, ' ');
			if (tmp) {
				sz = (st64) r_num_math (core->num, tmp+1);
				if (!sz) {
					sz = core->blocksize;
				}
				*tmp = 0;
				if (sz<1) eprintf ("Invalid length\n");
				else r_core_dump (core, filename, core->offset, (ut64)sz, append);
			} else {
				if (!r_file_dump (filename, core->block, core->blocksize, append)) {
					sz = 0;
				} else sz = core->blocksize;
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_io_write_at (core->io, core->offset,
					(ut8*)out, strlen (out));
				free (out);
			}
		} else
		if ((buf = (ut8*) r_file_slurp (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'F':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			int len;
			ut8 *out;
			char *in = r_core_editor (core, NULL, NULL);
			if (in) {
				out = (ut8 *)strdup (in);
				if (out) {
					len = r_hex_str2bin (in, out);
					if (len>0)
						r_io_write_at (core->io, core->offset, out, len);
					free (out);
				}
				free (in);
			}
		} else
		if ((buf = r_file_slurp_hexpairs (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'w':
		str++;
		len = (len-1)<<1;
		if (len>0) tmp = malloc (len+1);
		else tmp = NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
			free (tmp);
		} else eprintf ("Cannot malloc %d\n", len);
		break;
	case 'x':
		{
		int b, len = strlen (input);
		ut8 *buf = malloc (len+1);
		len = r_hex_str2bin (input+1, buf);
		if (len != 0) {
			if (len<0) len = -len+1;
			if (len<core->blocksize) {
				b = core->block[len]&0xf;
				b |= (buf[len]&0xf0);
			} else b = buf[len];
			buf[len] = b;
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
		} else eprintf ("Error: invalid hexpair string\n");
		free (buf);
		}
		break;
	case 'a':
		switch (input[1]) {
		case 'o':
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					r_cons_printf ("wx %s\n", acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core, 0);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f':
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						r_cons_printf ("wx %s\n", acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core, 0);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			r_cons_printf ("|Usage: wa[of*] [arg]\n"
				"| wa nop           : write nopcode using asm.arch and asm.bits\n"
				"| wa* mov eax, 33  : show 'wx' op with hexpair bytes of assembled opcode\n"
				"| \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
				"| waf foo.asm      : assemble file and write bytes\n"
				"| wao nop          : convert current opcode into nops\n"
				"| wao?             : show help for assembler operation on current opcode (hack)\n");
			break;
		}
		break;
	case 'b':
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core, 0);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core, 0);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core, 0);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Пример #7
0
static char *getstr(const char *src) {
	int len;
	char *ret = NULL;

	switch (*src) {
	case '\'':
		ret = strdup (src+1);
		if (ret) {
			len = strlen (ret);
			if (len > 0) {
				len--;
				if (ret[len] == '\'') {
					ret[len] = 0;
					return ret;
				}
				eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '"':
		ret = strdup (src + 1);
		if (ret) {
			len = strlen (ret);
			if (len > 0) {
				len--;
				if (ret[len] == '"') {
					ret[len] = 0;
					r_str_unescape (ret);
					return ret;
				}
				eprintf ("Missing \"\n");
			}
			free (ret);
		}
		return NULL;
	case '@':
		{
			char *pat = strchr (src + 1, '@');
			if (pat) {
				int i, len, rep;
				*pat++ = 0;
				rep = atoi (src + 1);
				len = strlen (pat);
				if (rep > 0) {
					char *buf = malloc (rep);
					if (buf) {
						for (i = 0; i < rep; i++) {
							buf[i] = pat[i%len];
						}
					}
					return buf;
				}
			}
			// slurp file
			return r_file_slurp (src + 1, NULL);
		}
	case '`':
		{
		char *msg = strdup (src + 1);
		int msg_len = strlen (msg);
		if (msg_len > 0) {
			msg [msg_len - 1] = 0;
			char *ret = r_str_trim_tail (r_sys_cmd_str (msg, NULL, NULL));
			free (msg);
			return ret;
		}
		free (msg);
		return strdup ("");
		}
	case '!':
		return r_str_trim_tail (r_sys_cmd_str (src + 1, NULL, NULL));
	case ':':
		if (src[1] == '!') {
			ret = r_str_trim_tail (r_sys_cmd_str (src + 1, NULL, NULL));
		} else {
			ret = strdup (src);
		}
		len = r_hex_str2bin (src + 1, (ut8*)ret);
		if (len > 0) {
			ret[len] = 0;
			return ret;
		}
		eprintf ("Invalid hexpair string\n");
		free (ret);
		return NULL;
#if 0
	// what is this for??
	case '%':
		return (char *) strtoul (src + 1, NULL, 0);
#endif
	}
	r_str_unescape ((ret = strdup (src)));
	return ret;
}
Пример #8
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	ut64 off;
	ut8 *buf;
	const char *arg;
	int wseek, i, size, len = strlen (input);
	char *tmp, *str, *ostr;
	RCore *core = (RCore *)data;
	#define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y)
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup (input+1);

	switch (*input) {
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_printf ("%s\n", p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = R_FALSE;
		char *input_shadow = NULL, *p = NULL;

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

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

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

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


		if (cmd_suc == R_FALSE) {
			r_cons_printf ("|Usage: write extend\n"
			"wen <num>               insert num null bytes at current offset\n"
			"wex <hex_bytes>         insert bytes at current offset\n"
			"weN <addr> <len>        insert bytes at address\n"
			"weX <addr> <hex_bytes>  insert bytes at address\n"
			"wes <addr>  <dist> <block_size>   shift a blocksize left or write in the editor\n"
			);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' '&&input[2]=='-')) {
			const char *tmpfile = ".tmp";
			char *out = r_core_editor (core, NULL);
			if (out) {
				// XXX hacky .. patch should support str, not only file
				r_file_dump (tmpfile, (ut8*)out, strlen (out));
				r_core_patch (core, tmpfile);
				r_file_rm (tmpfile);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				r_core_patch (core, input+2);
			} else {
				eprintf ("Usage: wp [-|r2patch-file]\n"
			         "TODO: rapatch format documentation here\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r':
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len>0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			r_cons_printf ("|Usage: wA [type] [value]\n"
			"|Types:\n"
			"| r   raw write value\n"
			"| v   set value (taking care of current address)\n"
			"| d   destination register\n"
			"| 0   1st src register\n"
			"| 1   2nd src register\n"
			"|Example: wA r 0 # e800000000\n");
			break;
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io);
			r_core_block_read (core, 0);
			break;
		case 'r':
			r_io_cache_reset (core->io, R_TRUE);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, R_TRUE);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '?':
			r_cons_printf (
			"|Usage: wc[ir*?]\n"
			"| wc           list all write changes\n"
			"| wc- [a] [b]  remove write op at curseek or given addr\n"
			"| wc*          \"\" in radare commands\n"
			"| wcr          reset all write changes in cache\n"
			"| wci          commit write cache\n"
			"|NOTE: Requires 'e io.cache=true'\n");
			break;
		case '*':
			r_io_cache_list (core->io, R_TRUE);
			break;
		case '\0':
			if (!r_config_get_i (core->config, "io.cache"))
				eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, R_FALSE);
			break;
		}
		break;
	case ' ':
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core, 0);
		break;
	case 't':
		if (*str != ' ') {
			eprintf ("Usage: wt file [size]\n");
		} else {
			tmp = strchr (str+1, ' ');
			if (tmp) {
				st64 sz = (st64) r_num_math (core->num, tmp+1);
				*tmp = 0;
				if (sz<1) eprintf ("Invalid length\n");
				else r_core_dump (core, str+1, core->offset, (ut64)sz);
			} else r_file_dump (str+1, core->block, core->blocksize);
		}
		break;
	case 'T':
		eprintf ("TODO: wT // why?\n");
		break;
	case 'f':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			char *out = r_core_editor (core, NULL);
			if (out) {
				r_io_write_at (core->io, core->offset,
					(ut8*)out, strlen (out));
				free (out);
			}
		} else
		if ((buf = (ut8*) r_file_slurp (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'F':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			int len;
			ut8 *out;
			char *in = r_core_editor (core, NULL);
			if (in) {
				out = (ut8 *)strdup (in);
				if (out) {
					len = r_hex_str2bin (in, out);
					if (len>0)
						r_io_write_at (core->io, core->offset, out, len);
					free (out);
				}
				free (in);
			}
		} else
		if ((buf = r_file_slurp_hexpairs (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'w':
		str++;
		len = (len-1)<<1;
		if (len>0) tmp = malloc (len+1);
		else tmp = NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
			free (tmp);
		} else eprintf ("Cannot malloc %d\n", len);
		break;
	case 'x':
		{
		int b, len = strlen (input);
		ut8 *buf = malloc (len+1);
		len = r_hex_str2bin (input+1, buf);
		if (len != 0) {
			if (len<0) len = -len+1;
			if (len<core->blocksize) {
				b = core->block[len]&0xf;
				b |= (buf[len]&0xf0);
			} else b = buf[len];
			buf[len] = b;
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
		} else eprintf ("Error: invalid hexpair string\n");
		free (buf);
		}
		break;
	case 'a':
		switch (input[1]) {
		case 'o':
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					r_cons_printf ("wx %s\n", acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core, 0);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f':
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						r_cons_printf ("wx %s\n", acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core, 0);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			r_cons_printf ("|Usage: wa[of*] [arg]\n"
				"| wa nop           : write nopcode using asm.arch and asm.bits\n"
				"| wa* mov eax, 33  : show 'wx' op with hexpair bytes of sassembled opcode\n"
				"| \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
				"| waf foo.asm      : assemble file and write bytes\n"
				"| wao nop          : convert current opcode into nops\n"
				"| wao?             : show help for assembler operation on current opcode (hack)\n");
			break;
		}
		break;
	case 'b':
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core, 0);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		{
			int type = 0;
			ut8 addr1;
			ut16 addr2;
			ut32 addr4, addr4_;
			ut64 addr8;

			switch (input[1]) {
			case '?':
				r_cons_printf ("|Usage: wv[size] [value]    # write value of given size\n"
					"|  wv1 234      # write one byte with this value\n"
					"|  wv 0x834002  # write dword with this value\n"
					"|Supported sizes are: 1, 2, 4, 8\n");
				return 0;
			case '1': type = 1; break;
			case '2': type = 2; break;
			case '4': type = 4; break;
			case '8': type = 8; break;
			}
			off = r_num_math (core->num, input+2);
			r_io_use_desc (core->io, core->file->desc);
			r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
			if (type == 0)
				type = (off&UT64_32U)? 8: 4;
			switch (type) {
			case 1:
				addr1 = (ut8)off;
				r_io_write (core->io, (const ut8 *)&addr1, 1);
				WSEEK (core, 1);
				break;
			case 2:
				addr2 = (ut16)off;
				r_io_write (core->io, (const ut8 *)&addr2, 2);
				WSEEK (core, 2);
				break;
			case 4:
				addr4_ = (ut32)off;
				//drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
				//endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
				memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
				r_io_write (core->io, (const ut8 *)&addr4, 4);
				WSEEK (core, 4);
				break;
			case 8:
				/* 8 byte addr */
				memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
			//	endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
				r_io_write (core->io, (const ut8 *)&addr8, 8);
				WSEEK (core, 8);
				break;
			}
			r_core_block_read (core, 0);
		}
		break;
	case 'o':
		switch (input[1]) {
			case 'a':
			case 's':
			case 'e':
			case 'A':
			case 'x':
			case 'r':
			case 'l':
			case 'm':
			case 'd':
			case 'o':
			case 'w':
				if (input[2]!=' ') {
					if (input[1]=='e') r_cons_printf (
						"Usage: 'woe from-to step'\n");
					else r_cons_printf (
						"Usage: 'wo%c 00 11 22'\n", input[1]);
					free (ostr);
					return 0;
				}
			case '2':
			case '4':
				r_core_write_op (core, input+3, input[1]);
				r_core_block_read (core, 0);
				break;
			case 'R':
				r_core_cmd0 (core, "wr $b");
				break;
			case 'n':
				r_core_write_op (core, "ff", 'x');
				r_core_block_read (core, 0);
				break;
			case '\0':
			case '?':
			default:
				r_cons_printf (
					"|Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n"
					"|Example:\n"
					"|  wox 0x90   ; xor cur block with 0x90\n"
					"|  wox 90     ; xor cur block with 0x90\n"
					"|  wox 0x0203 ; xor cur block with 0203\n"
					"|  woa 02 03  ; add [0203][0203][...] to curblk\n"
					"|  woe 02 03  \n"
					"|Supported operations:\n"
					"|  wow  ==  write looped value (alias for 'wb')\n"
					"|  woa  +=  addition\n"
					"|  wos  -=  substraction\n"
					"|  wom  *=  multiply\n"
					"|  wod  /=  divide\n"
					"|  wox  ^=  xor\n"
					"|  woo  |=  or\n"
					"|  woA  &=  and\n"
					"|  woR  random bytes (alias for 'wr $b'\n"
					"|  wor  >>= shift right\n"
					"|  wol  <<= shift left\n"
					"|  wo2  2=  2 byte endian swap\n"
					"|  wo4  4=  4 byte endian swap\n"
						);
				break;
		}
		break;
	case 'd':
		if (input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		{
			ut8 ulen;
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core, 0);
			}
		}
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core, 0);
		} else r_cons_printf (
			"|Usage: w[x] [str] [<file] [<<EOF] [@addr]\n"
			"| w foobar     write string 'foobar'\n"
			"| wh r2        whereis/which shell command\n"
			"| wr 10        write 10 random bytes\n"
			"| ww foobar    write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n"
			"| wa push ebp  write opcode, separated by ';' (use '\"' around the command)\n"
			"| waf file     assemble file and write bytes\n"
			"| wA r 0       alter/modify opcode at current seek (see wA?)\n"
			"| wb 010203    fill current block with cyclic hexpairs\n"
			"| wc[ir*?]     write cache undo/commit/reset/list (io.cache)\n"
			"| wd [off] [n] duplicate N bytes from offset at current seek (memcpy) (see y?)\n"
			"| wx 9090      write two intel nops\n"
			"| wv eip+34    write 32-64 bit value\n"
			"| wo? hex      write in block with operation. 'wo?' fmi\n"
			"| wm f0ff      set binary mask hexpair to be used as cyclic write mask\n"
			"| ws pstring   write 1 byte for length and then the string\n"
			"| wf -|file    write contents of file at current offset\n"
			"| wF -|file    write contents of hexpairs file here\n"
			"| wp -|file    apply radare patch file. See wp? fmi\n"
			"| wt file [sz] write to file (from current seek, blocksize or sz bytes)\n"
			);
			//TODO: add support for offset+seek
			// " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n"
		break;
	}
Пример #9
0
static int cmd_meta_comment(RCore *core, const char *input) {
	ut64 addr = core->offset;
	switch (input[1]) {
	case '?': {
		const char* help_msg[] = {
			"Usage:", "CC[-+!*au] [base64:..|str] @ addr", "",
			"CC", "", "list all comments in human friendly form",
			"CC*", "", "list all comments in r2 commands",
			"CC.", "", "show comment at current offset",
			"CC,", " [file]", "show or set comment file",
			"CC", " [text]", "append comment at current address",
			"CCf", "", "list comments in function",
			"CC+", " [text]", "append comment at current address",
			"CC!", "", "edit comment using cfg.editor (vim, ..)",
			"CC-", " @ cmt_addr", "remove comment at given address",
			"CCu", " good boy @ addr", "add good boy comment at given address",
			"CCu", " base64:AA== @ addr", "add comment in base64",
			NULL};
		r_core_cmd_help (core, help_msg);
		} break;
	case ',': // "CC,"
		if (input[2]=='?') {
			eprintf ("Usage: CC, [file]\n");
		} else if (input[2]==' ') {
			const char *fn = input+2;
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			while (*fn== ' ')fn++;
			if (comment && *comment) {
				// append filename in current comment
				char *nc = r_str_newf ("%s ,(%s)", comment, fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
				free (nc);
			} else {
				char *comment = r_str_newf (",(%s)", fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment);
				free (comment);
			}
		} else {
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			if (comment && *comment) {
				char *cmtfile = r_str_between (comment, ",(", ")");
				if (cmtfile && *cmtfile) {
					char *getcommapath(RCore *core);
					char *cwd = getcommapath (core);
					r_cons_printf ("%s"R_SYS_DIR"%s\n", cwd, cmtfile);
					free (cwd);
				}
				free (cmtfile);
			}
			free (comment);
		}
		break;
	case '.':
		  {
			  char *comment = r_meta_get_string (
					  core->anal, R_META_TYPE_COMMENT, addr);
			  if (comment) {
				  r_cons_println (comment);
				  free (comment);
			  }
		  }
		break;
	case 0: // "CC"
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 0);
		break;
	case 'f': // "CCf"
		r_meta_list_at (core->anal, R_META_TYPE_COMMENT, 'f', core->offset);
		break;
	case 'j': // "CCj"
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 'j');
		break;
	case '!':
		{
			char *out, *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			out = r_core_editor (core, NULL, comment);
			if (out) {
				//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
				r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
				//r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL);
				r_meta_set_string (core->anal,
						R_META_TYPE_COMMENT, addr, out);
				free (out);
			}
			free (comment);
		}
		break;
	case '+':
	case ' ':
		{
		const char* newcomment = r_str_chop_ro (input + 2);
		char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
		char *nc = strdup (newcomment);
		r_str_unescape (nc);
		if (comment) {
			text = malloc (strlen (comment)+strlen (newcomment)+2);
			if (text) {
				strcpy (text, comment);
				strcat (text, "\n");
				strcat (text, nc);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text);
				free (text);
			} else {
				r_sys_perror ("malloc");
			}
		} else {
			r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
		}
		free (nc);
		}
		break;
	case '*':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 1);
		break;
	case '-': // "CC-"
		r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL);
		break;
	case 'u':
		//
		{
		char *newcomment;
		const char *arg = input + 2;
		while (*arg && *arg == ' ') arg++;
		if (!strncmp (arg, "base64:", 7)) {
			char *s = (char *)sdb_decode (arg+7, NULL);
			if (s) {
				newcomment = s;
			} else {
				newcomment = NULL;
			}
		} else {
			newcomment = strdup (arg);
		}
		if (newcomment) {
			char *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			if (!comment || (comment && !strstr (comment, newcomment))) {
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
						addr, newcomment);
			}
			free (comment);
			free (newcomment);
		}
		}
		break;
	case 'a':
		{
		char *s, *p;
		s = strchr (input, ' ');
		if (s) {
			s = strdup (s + 1);
		} else {
			eprintf ("Usage\n");
			return false;
		}
		p = strchr (s, ' ');
		if (p) {
			*p++ = 0;
		}
		ut64 addr;
		if (input[2]=='-') {
			if (input[3]) {
				addr = r_num_math (core->num, input+3);
				r_meta_del (core->anal,
						R_META_TYPE_COMMENT,
						addr, 1, NULL);
			} else eprintf ("Usage: CCa-[address]\n");
			free (s);
			return true;
		}
		addr = r_num_math (core->num, s);
		// Comment at
		if (p) {
			if (input[2]=='+') {
				char *comment = r_meta_get_string (
						core->anal, R_META_TYPE_COMMENT,
						addr);
				if (comment) {
					char* text = r_str_newf ("%s\n%s", comment, p);
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, text);
					free (text);
				} else {
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, p);
				}
			} else {
				r_meta_add (core->anal,
						R_META_TYPE_COMMENT,
						addr, addr + 1, p);
			}
		} else {
			eprintf ("Usage: CCa [address] [comment]\n");
		}
		free (s);
		return true;
		}
	}

	return true;
}