Exemple #1
0
static bool cmd_wff(RCore *core, const char *input) {
	ut8 *buf;
	int size;
	// XXX: file names cannot contain spaces
	const char *arg = input + ((input[1] == ' ') ? 2 : 1);
	int wseek = r_config_get_i (core->config, "cfg.wseek");
	char *p, *a = r_str_trim (strdup (arg));
	p = strchr (a, ' ');
	if (p) {
		*p++ = 0;
	}

	if (*arg =='?' || !*arg) {
		eprintf ("Usage: wf [file] ([size] ([offset]))\n");
	}
	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));
			r_core_block_read (core);
			free (out);
		}
	}
	if ((buf = (ut8*) r_file_slurp (a, &size))) {
		int u_size = size;
		int u_offset = 0;
		u_size = r_num_math (core->num, p);
		if (u_size < 1) u_size = size;
		if (p) {
			*p++ = 0;
			u_offset = r_num_math (core->num, p);
			if (u_offset > size) {
				eprintf ("Invalid offset\n");
				free (buf);
				return false;
			}
		}
		r_io_use_fd (core->io, core->file->fd);
		r_io_write_at (core->io, core->offset, buf + u_offset, u_size);
		WSEEK (core, size);
		free (buf);
		r_core_block_read (core);
	} else {
		eprintf ("Cannot open file '%s'\n", arg);
	}
	return true;
}
Exemple #2
0
R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
	core->offset = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	if (rb) {
		r_core_block_read (core);
	}
	return core->offset == addr;
}
Exemple #3
0
static bool cmd_wfs(RCore *core, const char *input) {
	char * args = r_str_trim (strdup (input + 1));
	char *arg = strchr (args, ' ');
	int len = core->blocksize;
	if (arg) {
		*arg = 0;
		len = r_num_math (core->num, arg + 1);
	}
	ut64 dst = core->offset;
	ut64 src = r_num_math (core->num, args);
	if (len > 0) {
		// cache dest, memcpy, write cache
		ut8 *buf = calloc (1, len);
		if (buf) {
			if (r_io_read_at (core->io, dst, buf, len)) {
				ioMemcpy (core, core->offset, src, len);
				if (r_io_write_at (core->io, src, buf, len)) {
					r_core_block_read (core);
				} else {
					eprintf ("Failed to write at 0x%08"PFMT64x"\n", src);
				}
			} else {
				eprintf ("cmd_wfs: failed to read at 0x%08"PFMT64x"\n", dst);
			}
			free (buf);
		}
	}
	free (args);
	return true;
}
Exemple #4
0
static bool cmd_wf(RCore *core, const char *input) {
	if (!core || !*input) {
		return false;
	}
	if (input[1] == '?') {
		eprintf ("Usage: wf [file] ([size] ([offset]))\n");
		r_core_cmd_help (core, help_msg_wf);
		return false;
	}
	if (input[1] == 's') { // "wfs"
		return cmd_wfs (core, input + 1);
	}
	if (input[1] == 'f') { // "wff"
		return cmd_wff (core, input + 1);
	}
	char *args = r_str_trim (strdup (input + 1));
	char *arg = strchr (args, ' ');
	int len = core->blocksize;
	if (arg) {
		*arg++ = 0;
		len = r_num_math (core->num, arg);
	}
	ut64 addr = r_num_math (core->num, args);
	ioMemcpy (core, core->offset, addr, len);
	free (args);
	r_core_block_read (core);
	return true;
}
Exemple #5
0
static int config_iova_callback(void *user, void *data) {
	RCore *core = (RCore *) user;
	RConfigNode *node = (RConfigNode *) data;
	if (node->i_value != core->io->va) {
		core->io->va = node->i_value;
		r_core_block_read (core, 0);
		// reload symbol information
		r_core_cmd0 (core, ".ia*");
	}
	return R_TRUE;
}
Exemple #6
0
R_API bool r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
	bool ret;
	if (!core) {
		return false;
	}
	ret = r_io_write_at (core->io, addr, buf, size);
	if (addr >= core->offset && addr <= core->offset + core->blocksize - 1) {
		r_core_block_read (core);
	}
	return ret;
}
Exemple #7
0
R_API int r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
	int ret;
	if (!core->io || !core->file || size<1)
		return R_FALSE;
	ret = r_io_set_fd (core->io, core->file->fd);
	if (ret != -1) {
		ret = r_io_write_at (core->io, addr, buf, size);
		if (addr >= core->offset && addr <= core->offset+core->blocksize)
			r_core_block_read (core, 0);
	}
	return (ret==-1)? R_FALSE: R_TRUE;
}
Exemple #8
0
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
	RIOSection *newsection;
	ut64 old = core->offset;
	ut64 ret;

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

	if (ret == UT64_MAX) {
		//eprintf ("RET =%d %llx\n", ret, addr);
		/*
		   XXX handle read errors correctly
		   if (core->ffio) {
		   core->offset = addr;
		   } else return R_FALSE;
		 */
		//core->offset = addr;
		if (!core->io->va)
			return R_FALSE;
		memset (core->block, 0xff, core->blocksize);
	} else core->offset = addr;
	if (rb) {
		ret = r_core_block_read (core, 0);
		if (core->ffio) {
			if (ret<1 || ret > core->blocksize)
				memset (core->block, 0xff, core->blocksize);
			else memset (core->block+ret, 0xff, core->blocksize-ret);
			ret = core->blocksize;
			core->offset = addr;
		} else {
			if (ret<1) {
				core->offset = old;
				//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
			}
		}
	}
	if (core->section != newsection) {//&& core->io->section->arch) {
		int bits = 0;// = core->io->section->bits;
		const char *arch = r_io_section_get_archbits (core->io, core->offset, &bits);
		if (arch && bits) {
			r_config_set (core->config, "asm.arch", arch);
			r_config_set_i (core->config, "asm.bits", bits);
		}
		core->section = core->io->section;
	}
	return (ret==-1)? R_FALSE: R_TRUE;
}
Exemple #9
0
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
	int ret;
	if (!core->io || !core->file || size<1)
		return R_FALSE;
#if 0
	r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
	ret = r_io_read_at (core->io, addr, buf, size);
	if (addr>=core->offset && addr<=core->offset+core->blocksize)
		r_core_block_read (core, 0);
#else
	r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
	//ret = r_io_read_at (core->io, addr, buf, size);
	r_io_seek (core->io, addr, R_IO_SEEK_SET);
	ret = r_io_read (core->io, buf, size);
	if (ret != size) {
		if (ret>=size || ret<0) ret = 0;
		memset (buf+ret, 0xff, size-ret);
	}
	if (addr>=core->offset && addr<=core->offset+core->blocksize)
		r_core_block_read (core, 0);
#endif
	return (ret==size); //UT64_MAX);
}
Exemple #10
0
R_API int r_core_extend_at(RCore *core, ut64 addr, int size) {
	int ret;
	if (!core->io || !core->file || size < 1) {
		return false;
	}
	ret = r_io_use_fd (core->io, core->file->fd);
	if (ret != -1) {
		ret = r_io_extend_at (core->io, addr, size);
		if (addr >= core->offset && addr <= core->offset+core->blocksize) {
			r_core_block_read (core);
		}
	}
	return (ret==-1)? false: true;
}
Exemple #11
0
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
	int ret;
	if (!core->io || !core->file || size<1)
		return R_FALSE;
	r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
	ret = r_io_read_at (core->io, addr, buf, size);
	if (ret != size) {
		if (ret<size && ret>0)
			memset (buf+ret, 0xff, size-ret);
		else	memset (buf, 0xff, size);
	}
	if (addr>=core->offset && addr<=core->offset+core->blocksize)
		r_core_block_read (core, 0);
	return (ret!=UT64_MAX);
}
Exemple #12
0
R_API int cmd_write_hexpair(RCore* core, const char* pairs) {
	ut8 *buf = malloc (strlen (pairs));
	int len = r_hex_str2bin (pairs, buf);
	if (len != 0) {
		if (len < 0)
			len = -len + 1;
		if (len<core->blocksize)
			buf[len] = (core->block[len] & 0xf) | (buf[len] & 0xf0);
		r_core_write_at (core, core->offset, buf, len);
		if (r_config_get_i (core->config, "cfg.wseek"))
			r_core_seek_delta (core, len);
		r_core_block_read (core, 0);
	} else
		eprintf ("Error: invalid hexpair string\n");
	free (buf);

	return !!!len;
}
Exemple #13
0
static bool ioMemcpy (RCore *core, ut64 dst, ut64 src, int len) {
	bool ret = false;
	if (len > 0) {
		ut8 * buf = calloc (1, len);
		if (buf) {
			if (r_io_read_at (core->io, src, buf, len)) {
				if (r_io_write_at (core->io, dst, buf, len)) {
					r_core_block_read (core);
					ret = true;
				} else {
					eprintf ("r_io_write_at failed at 0x%08"PFMT64x"\n", dst);
				}
			} else {
				eprintf ("r_io_read_at failed at 0x%08"PFMT64x"\n", src);
			}
			free (buf);
		}
	}
	return ret;
}
Exemple #14
0
R_API int cmd_write_hexpair(RCore* core, const char* pairs) {
	ut8 *buf = malloc (strlen (pairs) + 1);
	int len = r_hex_str2bin (pairs, buf);
	if (len != 0) {
		if (len < 0) {
			len = -len;
			if (len < core->blocksize) {
				buf[len-1] |= core->block[len-1] & 0xf;
			}
		}
		r_core_write_at (core, core->offset, buf, len);
		if (r_config_get_i (core->config, "cfg.wseek")) {
			r_core_seek_delta (core, len);
		}
		r_core_block_read (core);
	} else {
		eprintf ("Error: invalid hexpair string\n");
	}
	free (buf);
	return len;
}
Exemple #15
0
R_API int r_core_yank_to(RCore *core, const char *_arg) {
	ut64 src = core->offset;
	ut64 len = 0;
	ut64 pos = -1;
	char *str, *arg;
	ut8 *buf;

	while (*_arg==' ') _arg++;
	arg = strdup (_arg);
	str = strchr (arg, ' ');
	if (str) {
		str[0]='\0';
		len = r_num_math (core->num, arg);
		pos = r_num_math (core->num, str+1);
		str[0]=' ';
	}
	if ((str == NULL) || (pos == -1) || (len == 0)) {
		eprintf ("Usage: yt [len] [dst-addr]\n");
		free (arg);
		return 1;
	}
#if 0
	if (!config_get("file.write")) {
		eprintf("You are not in read-write mode.\n");
		return 1;
	}
#endif
	buf = (ut8*)malloc (len);
	r_core_read_at (core, src, buf, len);
	r_core_write_at (core, pos, buf, len);
	free (buf);

	core->offset = src;
	r_core_block_read (core, 0);
	free (arg);
	return 0;
}
Exemple #16
0
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
	ut64 old = core->offset;
	ut64 ret;

	/* XXX unnecesary call */
	//r_io_set_fd (core->io, core->file->fd);
	ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	if (ret == UT64_MAX) {
//eprintf ("RET =%d %llx\n", ret, addr);
/*
	XXX handle read errors correctly
		if (core->ffio) {
			core->offset = addr;
		} else return R_FALSE;
*/
		//core->offset = addr;
		if (!core->io->va)
			return R_FALSE;
		memset (core->block, 0xff, core->blocksize);
	} else core->offset = addr;
	if (rb) {
		ret = r_core_block_read (core, 0);
		if (core->ffio) {
			if (ret<1 || ret > core->blocksize)
				memset (core->block, 0xff, core->blocksize);
			else memset (core->block+ret, 0xff, core->blocksize-ret);
			ret = core->blocksize;
			core->offset = addr;
		} else {
			if (ret<1) {
				core->offset = old;
				//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
			}
		}
	}
	return (ret==-1)?R_FALSE:R_TRUE;
}
Exemple #17
0
static void cmd_write_value (RCore *core, const char *input) {
	int type = 0;
	ut64 off = 0LL;
	ut8 buf[sizeof(ut64)];
	int wseek = r_config_get_i (core->config, "cfg.wseek");
	bool be = r_config_get_i (core->config, "cfg.bigendian");

	if (!input)
		return;

	if (input[0])
	switch (input[1]) {
	case '?':
		r_core_cmd_help (core, help_msg_wv);
		return;
	case '1': type = 1; break;
	case '2': type = 2; break;
	case '4': type = 4; break;
	case '8': type = 8; break;
	}
	if (input && input[0] && input[1] && input[2]) {
		off = r_num_math (core->num, input+2);
	}
	if (core->file) {
		r_io_use_fd (core->io, core->file->fd);
	}
	ut64 res = r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
	if (res == UT64_MAX) return;
	if (type == 0)
		type = (off&UT64_32U)? 8: 4;
	switch (type) {
	case 1:
		r_write_ble8 (buf, (ut8)(off & UT8_MAX));
		if (!r_io_write (core->io, buf, 1)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 1);
		}
		break;
	case 2:
		r_write_ble16 (buf, (ut16)(off & UT16_MAX), be);
		if (!r_io_write (core->io, buf, 2)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 2);
		}
		break;
	case 4:
		r_write_ble32 (buf, (ut32)(off & UT32_MAX), be);
		if (!r_io_write (core->io, buf, 4)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 4);
		}
		break;
	case 8:
		r_write_ble64 (buf, off, be);
		if (!r_io_write (core->io, buf, 8)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 8);
		}
		break;
	}
	r_core_block_read (core);
}
Exemple #18
0
static void cmd_write_op (RCore *core, const char *input) {
	ut8 *buf;
	int len;
	int value;
	if (!input[0])
		return;
	switch (input[1]) {
	case 'e':
		if (input[2]!=' ') {
			r_cons_printf ("Usage: 'woe from-to step'\n");
			return;
		}
		/* fallthru */
	case 'a':
	case 's':
	case 'A':
	case 'x':
	case 'r':
	case 'l':
	case 'm':
	case 'd':
	case 'o':
	case 'w':
	case '2':
	case '4':
		if (input[2]) {  // parse val from arg
			r_core_write_op (core, input+3, input[1]);
			r_core_block_read (core);
		} else {  // use clipboard instead of val
			r_core_write_op (core, NULL, input[1]);
			r_core_block_read (core);
		}
		break;
	case 'R':
		r_core_cmd0 (core, "wr $b");
		break;
	case 'n':
		r_core_write_op (core, "ff", 'x');
		r_core_block_read (core);
		break;
	case 'E': // "woE" encrypt
	case 'D': // "woD" decrypt
		{
			int direction = (input[1] == 'E') ? 0 : 1;
			const char *algo = NULL;
			const char *key = NULL;
			const char *iv = NULL;
			char *space, *args = strdup (r_str_trim_ro (input+2));
			space = strchr (args, ' ');
			if (space) {
				*space++ = 0;
				key = space;
				space = strchr (key, ' ');
				if (space) {
					*space++ = 0;
					iv = space;
				}
			}
			algo = args;
			if (algo && *algo && key) {
				encrypt_or_decrypt_block (core, algo, key, direction, iv);
			} else {
				eprintf ("Usage: wo%c [algo] [key] [IV]\n", ((!direction)?'E':'D'));
				eprintf ("Currently supported hashes:\n");
				ut64 bits;
				int i;
				for (i = 0; ; i++) {
					bits = ((ut64)1) << i;
					const char *name = r_hash_name (bits);
					if (!name || !*name) break;
					printf ("  %s\n", name);
				}
				eprintf ("Available Encoders/Decoders: \n");
				// TODO: do not hardcode
				eprintf ("  base64\n");
				eprintf ("  base91\n");
				eprintf ("  punycode\n");
				eprintf ("Currently supported crypto algos:\n");
				for (i = 0; ; i++) {
					bits = ((ut64)1) << i;
					const char *name = r_crypto_name (bits);
					if (!name || !*name) break;
					printf ("  %s\n", name);
				}
			}
			free (args);
		}
		break;
	case 'p': // debrujin patterns
		switch (input[2]) {
		case 'D': // "wopD"
			len = (int)(input[3]==' ')
				? r_num_math (core->num, input + 3)
				: core->blocksize;
			if (len > 0) {
				/* XXX This seems to fail at generating long patterns (wopD 512K) */
				buf = (ut8*)r_debruijn_pattern (len, 0, NULL); //debruijn_charset);
				if (buf) {
					const ut8 *ptr = buf;
					ut64 addr = core->offset;
					if (input[3] == '*') {
						int i;
						r_cons_printf ("wx ");
						for (i = 0; i < len; i++) {
							r_cons_printf ("%02x", buf[i]);
						}
						r_cons_newline ();
					} else {
						while (true) {
							int res = r_core_write_at (core, addr, ptr, len);
							if (res < 1 || len == res) {
								break;
							}
							if (res < len) {
								ptr += res;
								len -= res;
								addr += res;
							}
						} 
					}
					free (buf);
				} else {
					eprintf ("Couldn't generate pattern of length %d\n", len);
				}
			}
			break;
		case 'O': // "wopO"
			if (strlen (input) > 4 && strncmp (input + 4, "0x", 2)) {
				eprintf ("Need hex value with `0x' prefix e.g. 0x41414142\n");
			} else if (input[3] == ' ') {
				value = r_num_get (core->num, input + 4);
				core->num->value = r_debruijn_offset (value, r_config_get_i (core->config, "cfg.bigendian"));
				r_cons_printf ("%"PFMT64d"\n", core->num->value);
			}
			break;
		case '\0':
		case '?':
		default:
			r_core_cmd_help (core, help_msg_wop);
			break;
		}
		break;
	case '\0':
	case '?':
	default:
		r_core_cmd_help (core, help_msg_wo);
		break;
	}
}
Exemple #19
0
static int cmd_seek(void *data, const char *input) {
	RCore *core = (RCore *) data;
	char *cmd, *p;
	ut64 off;

	if (!*input) {
		r_cons_printf ("0x%"PFMT64x "\n", core->offset);
		return 0;
	}
	char *ptr;
	if ((ptr = strstr (input, "+.")) != NULL) {
		char *dup = strdup (input);
		dup[ptr - input] = '\x00';
		off = r_num_math (core->num, dup + 1);
		core->offset = off;
		free (dup);
	}
	const char *inputnum = strchr (input, ' ');
	{
		const char *u_num = inputnum? inputnum + 1: input + 1;
		off = r_num_math (core->num, u_num);
		if (*u_num == '-') {
			off = -off;
		}
	}
	int sign = 1;
	if (input[0] == ' ') {
		switch (input[1]) {
		case '-':
			sign = -1;
			/* pass thru */
		case '+':
			input++;
			break;
		}
	}
	bool silent = false;
	if (*input == 's') {
		silent = true;
		input++;
		if (*input == '?') {
			const char *help_message[] = {
				"Usage: ss", "", " # Seek silently (not recorded in the seek history)",
				"s?", "", "Works with all s subcommands",
				NULL
			};
			r_core_cmd_help (core, help_message);
			return 0;
		}
	}

	switch (*input) {
	case 'r':
		if (input[1] && input[2]) {
			seek_to_register (core, input + 2, silent);
		} else {
			eprintf ("|Usage| 'sr PC' seek to program counter register\n");
		}
		break;
	case 'C':
		if (input[1] == '*') {
			r_core_cmd0 (core, "C*~^\"CC");
		} else if (input[1] == ' ') {
			typedef struct {
				ut64 addr;
				char *str;
			} MetaCallback;
			int count = 0;
			MetaCallback cb = {
				0, NULL
			};
			ut64 addr;
			char key[128];
			const char *val, *comma;
			char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
			char *str, *next, *cur = list;
			if (list) {
				for (;;) {
					cur = sdb_anext (cur, &next);
					addr = sdb_atoi (cur);
					snprintf (key, sizeof (key) - 1, "meta.C.0x%"PFMT64x, addr);
					val = sdb_const_get (core->anal->sdb_meta, key, 0);
					if (val) {
						comma = strchr (val, ',');
						if (comma) {
							str = (char *) sdb_decode (comma + 1, 0);
							if (strstr (str, input + 2)) {
								r_cons_printf ("0x%08"PFMT64x "  %s\n", addr, str);
								count++;
								cb.addr = addr;
								free (cb.str);
								cb.str = str;
							} else {
								free (str);
							}
						}
					} else {
						eprintf ("sdb_const_get key not found '%s'\n", key);
					}
					if (!next) {
						break;
					}
					cur = next;
				}
			}

			switch (count) {
			case 0:
				eprintf ("No matching comments\n");
				break;
			case 1:
				off = cb.addr;
				if (!silent) {
					r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				}
				r_core_seek (core, off, 1);
				r_core_block_read (core);
				break;
			default:
				eprintf ("Too many results\n");
				break;
			}
			free (cb.str);
		} else {
			const char *help_msg[] = {
				"Usage:", "sC", "Comment grep",
				"sC", "*", "List all comments",
				"sC", " str", "Seek to the first comment matching 'str'",
				NULL
			};
			r_core_cmd_help (core, help_msg);
		}
		break;
	case ' ':
		if (!silent) {
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
		}
		r_core_seek (core, off * sign, 1);
		r_core_block_read (core);
		break;
	case '/':
	{
		const char *pfx = r_config_get (core->config, "search.prefix");
		ut64 from = r_config_get_i (core->config, "search.from");
// kwidx cfg var is ignored
		int kwidx = core->search->n_kws; // (int)r_config_get_i (core->config, "search.kwidx")-1;
		if (kwidx < 0) {
			kwidx = 0;
		}
		switch (input[1]) {
		case ' ':
		case 'v':
		case 'V':
		case 'w':
		case 'W':
		case 'z':
		case 'm':
		case 'c':
		case 'A':
		case 'e':
		case 'E':
		case 'i':
		case 'R':
		case 'r':
		case '/':
		case 'x':
			r_config_set_i (core->config, "search.from", core->offset + 1);
			r_config_set_i (core->config, "search.count", 1);
			r_core_cmdf (core, "s+1; %s; s-1; s %s%d_0; f-%s%d_0",
				input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
			r_config_set_i (core->config, "search.from", from);
			r_config_set_i (core->config, "search.count", 0);
			break;
		case '?':
			eprintf ("Usage: s/.. arg.\n");
			r_cons_printf ("/?\n");
			break;
		default:
			eprintf ("unknown search method\n");
			break;
		}
	}
	break;
	case '.':
		for (input++; *input == '.'; input++) {
			;
		}
		r_core_seek_base (core, input);
		break;
	case 'j':  // sj
		{
			RList /*<ut64 *>*/ *addrs = r_list_newf (free);
			RList /*<char *>*/ *names = r_list_newf (free);
			RList *list = r_io_sundo_list (core->io, '!');
			ut64 lsz = 0;
			ut64 i;
			RListIter *iter;
			RIOUndos *undo;
			if (list) {
				r_list_foreach (list, iter, undo) {
					char *name = NULL;

					core->flags->space_strict = true;
					RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
					core->flags->space_strict = false;
					if (f) {
						if (f->offset != undo->off) {
							name = r_str_newf ("%s + %d\n", f->name,
									(int)(undo->off- f->offset));
						} else {
							name = strdup (f->name);
						}
					}
					if (!name) {
						name = strdup ("");
					}
					ut64 *val = malloc (sizeof (ut64));
					if (!val) {
						free (name);
						break;
					}
					*val = undo->off;
					r_list_append (addrs, val);
					r_list_append (names, strdup (name));
					lsz++;
					free (name);
				}
				r_list_free (list);
			}
			r_cons_printf ("[");
			for (i = 0; i < lsz; ++i) {
				ut64 *addr = r_list_get_n (addrs, i);
				const char *name = r_list_get_n (names, i);
				// XXX(should the "name" field be optional? That might make
				// a bit more sense.
				r_cons_printf ("{\"offset\":%"PFMT64d",\"symbol\":\"%s\"}", *addr, name);
				if (i != lsz - 1) {
					r_cons_printf (",");
				}
			}
			r_cons_printf ("]\n");
			r_list_free (addrs);
			r_list_free (names);
		}
		break;
	case '*':
	case '=':
	case '!':
		{
			RList *list = r_io_sundo_list (core->io, input[0]);
			RListIter *iter;
			RIOUndos *undo;
			if (list) {
				r_list_foreach (list, iter, undo) {
					char *name = NULL;

					core->flags->space_strict = true;
					RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
					core->flags->space_strict = false;
					if (f) {
						if (f->offset != undo->off) {
							name = r_str_newf ("%s + %d\n", f->name,
									(int)(undo->off- f->offset));
						} else {
							name = strdup (f->name);
						}
					}
					if (!name) {
						name = strdup ("");
					}
					r_cons_printf ("0x%"PFMT64x" %s\n", undo->off, name);
					free (name);
				}
				r_list_free (list);
			}
		}
Exemple #20
0
static int cmd_seek(void *data, const char *input) {
	RCore *core = (RCore *)data;
	char *cmd, *p;
	ut64 off;

	if (*input=='r') {
		if (input[1] && input[2]) {
			if (core->io->debug) {
				off = r_debug_reg_get (core->dbg, input+2);
				r_io_sundo_push (core->io, core->offset);
				r_core_seek (core, off, 1);
			} else {
				RReg *orig = core->dbg->reg;
				core->dbg->reg = core->anal->reg;
				off = r_debug_reg_get (core->dbg, input+2);
				core->dbg->reg = orig;
				r_core_seek (core, off, 1);
			}
		} else eprintf ("|Usage| 'sr pc' seek to program counter register\n");
	} else
	if (*input) {
		const char *inputnum = strchr (input+1, ' ');
		int sign = 1;
		inputnum = inputnum? inputnum+1: input+1;
		off = r_num_math (core->num, inputnum);
		if (*inputnum== '-') off = -off;
#if 0
		if (input[0]!='/' && inputnum && isalpha (inputnum[0]) && off == 0) {
			if (!r_flag_get (core->flags, inputnum)) {
				eprintf ("Cannot find address for '%s'\n", inputnum);
				return R_FALSE;
			}
		}
#endif
		if (input[0]==' ') {
			switch (input[1]) {
			case '-': sign=-1;
			case '+': input++; break;
			}
		}

		switch (*input) {
		case 'C':
			if (input[1]=='*') {
				r_core_cmd0 (core, "C*~^\"CC");
			} else
			if (input[1]==' ') {
				typedef struct {
					ut64 addr;
					char *str;
				} MetaCallback;
				int count = 0;
				MetaCallback cb = { 0, NULL };
				ut64 addr;
				char key[128];
				const char *val, *comma;
				char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
				char *str, *next, *cur = list;
				if (list) {
					for (;;) {
						cur = sdb_anext (cur, &next);
						addr = sdb_atoi (cur);
						snprintf (key, sizeof (key)-1, "meta.C.0x%"PFMT64x, addr);
						val = sdb_const_get (core->anal->sdb_meta, key, 0);
						if (val) {
							comma = strchr (val, ',');
							if (comma) {
								str = (char *)sdb_decode (comma+1, 0);
								if (strstr (str, input+2)) {
									r_cons_printf ("0x%08"PFMT64x"  %s\n", addr, str);
									count++;
									cb.addr = addr;
									free (cb.str);
									cb.str = str;
								} else free (str);
							}
						} else eprintf ("sdb_const_get key not found '%s'\n", key);
						if (!next)
							break;
						cur = next;
					}
				}

				switch (count) {
				case 0:
					eprintf ("No matching comments\n");
					break;
				case 1:
					off = cb.addr;
					r_io_sundo_push (core->io, core->offset);
					r_core_seek (core, off, 1);
					r_core_block_read (core, 0);
					break;
				default:
					eprintf ("Too many results\n");
					break;
				}
				free (cb.str);
			} else eprintf ("Usage: sC[?*] comment-grep\n"
				"sC*        list all comments\n"
				"sC const   seek to comment matching 'const'\n");
			break;
		case ' ':
			r_io_sundo_push (core->io, core->offset);
			r_core_seek (core, off*sign, 1);
			r_core_block_read (core, 0);
			break;
		case '/':
			{
			const char *pfx = r_config_get (core->config, "search.prefix");
//kwidx cfg var is ignored
			int kwidx = core->search->n_kws; //(int)r_config_get_i (core->config, "search.kwidx")-1;
			if (kwidx<0) kwidx = 0;
			switch (input[1]) {
			case ' ':
			case 'x':
				r_config_set_i (core->config, "search.count", 1);
				r_core_cmdf (core, "s+1; p8 ; .%s;s-1;s %s%d_0;f-%s%d_0",
					input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
				r_config_set_i (core->config, "search.count", 0);
				break;
			default:
				eprintf ("unknown search method\n");
				break;
			}
			}
			break;
		case '.':
			for (input++;*input=='.';input++);
			r_core_seek_base (core, input);
			break;
		case '*':
			r_io_sundo_list (core->io);
			break;
		case '+':
			if (input[1]!='\0') {
				int delta = (input[1]=='+')? core->blocksize: off;
				r_io_sundo_push (core->io, core->offset);
				r_core_seek_delta (core, delta);
			} else {
				off = r_io_sundo_redo (core->io);
				if (off != UT64_MAX)
					r_core_seek (core, off, 0);
			}
			break;
		case '-':
			if (input[1]!='\0') {
				int delta = (input[1]=='-') ? -core->blocksize: -off;
				r_io_sundo_push (core->io, core->offset);
				r_core_seek_delta (core, delta);
			} else {
				off = r_io_sundo (core->io, core->offset);
				if (off != UT64_MAX)
					r_core_seek (core, off, 0);
			}
			break;
		case 'n':
			r_io_sundo_push (core->io, core->offset);
			r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
			break;
		case 'p':
			r_io_sundo_push (core->io, core->offset);
			r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
			break;
		case 'a':
			off = core->blocksize;
			if (input[1]&&input[2]) {
				cmd = strdup (input);
				p = strchr (cmd+2, ' ');
				if (p) {
					off = r_num_math (core->num, p+1);;
					*p = '\0';
				}
				cmd[0] = 's';
				// perform real seek if provided
				r_cmd_call (core->rcmd, cmd);
				free (cmd);
			}
			r_io_sundo_push (core->io, core->offset);
			r_core_seek_align (core, off, 0);
			break;
		case 'b':
			if (off == 0)
				off = core->offset;
			r_io_sundo_push (core->io, core->offset);
			r_core_anal_bb_seek (core, off);
			break;
		case 'f':
			if (strlen(input) > 2 && input[1]==' ') {
				RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input+2);
				if (fcn) {
					r_core_seek (core, fcn->addr, 1);
				}
				break;
			}
			RAnalFunction *fcn = r_anal_fcn_find (core->anal, core->offset, 0);
			if (fcn) {
				r_core_seek (core, fcn->addr+fcn->size, 1);
			}
			break;
		case 'o':
			{
			RAnalOp op;
			int val=0, ret, i, n = r_num_math (core->num, input+1);
			if (n==0) n = 1;
			if (n<0) {
				int ret = prevopsz (core, n);
				ret = r_anal_op (core->anal, &op,
						core->offset, core->block, core->blocksize);
				val += ret;
			} else
			for (val=i=0; i<n; i++) {
				ret = r_anal_op (core->anal, &op,
						core->offset, core->block, core->blocksize);
				if (ret<1)
					break;
				r_core_seek_delta (core, ret);
				val += ret;
			}
			core->num->value = val;
			}
			break;
		case 'g':
			{
			RIOSection *s = r_io_section_vget (core->io, core->offset);
			if (s) r_core_seek (core, s->vaddr, 1);
			else r_core_seek (core, 0, 1);
			}
			break;
		case 'G':
			{
			RIOSection *s = r_io_section_vget (core->io, core->offset);
			// XXX: this +2 is a hack. must fix gap between sections
			if (s) r_core_seek (core, s->vaddr+s->size+2, 1);
			else r_core_seek (core, core->file->size, 1);
			}
			break;
		case '?': {
			const char * help_message[] = {
			"Usage: s", "", " # Seek commands",
			"s", "", "Print current address",
			"s", " addr", "Seek to address",
			"s-", "", "Undo seek",
			"s-", " n", "Seek n bytes backward",
			"s--", "", "Seek blocksize bytes backward",
			"s+", "", "Redo seek",
			"s+", " n", "Seek n bytes forward",
			"s++", "", "Seek blocksize bytes forward",
			"s*", "", "List undo seek history",
			"s/", " DATA", "Search for next occurrence of 'DATA'",
			"s/x", " 9091", "Search for next occurrence of \\x90\\x91",
			"s.", "hexoff", "Seek honoring a base from core->offset",
			"sa", " [[+-]a] [asz]", "Seek asz (or bsize) aligned to addr",
			"sb", "", "Seek aligned to bb start",
			"sC", " string", "Seek to comment matching given string",
			"sf", "", "Seek to next function (f->addr+f->size)",
			"sf", " function", "Seek to address of specified function",
			"sg/sG", "", "Seek begin (sg) or end (sG) of section or file",
			"sn/sp", "", "Seek next/prev scr.nkey",
			"so", " [N]", "Seek to N next opcode(s)",
			"sr", " pc", "Seek to register",
			//"sp [page]  seek page N (page = block)",
			NULL
			};
			r_core_cmd_help(core, help_message);
		}
			break;
		}
	} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
	return 0;
}
Exemple #21
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 'p':
        if (input[1]==' ' && input[2]) {
            r_core_patch (core, input+2);
        } else {
            eprintf ("Usage: wp [rapatch-file]\n"
                     "TODO: rapatch format documentation here\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':
            r_io_cache_list (core->io, R_FALSE);
            break;
        }
        break;
    case ' ':
        /* write string */
        len = r_str_escape (str);
        r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
        r_io_set_fd (core->io, core->file->fd);
        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 ((buf = (ut8*) r_file_slurp (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            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 ((buf = r_file_slurp_hexpairs (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            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_set_fd (core->io, core->file->fd);
            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;
            b = core->block[len]&0xf;
            b |= (buf[len]&0xf0);
            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+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);
            }
        }
        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:
            eprintf ("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");
        } 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_set_fd (core->io, core->file->fd);
                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_set_fd (core->io, core->file->fd);
        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 'A':
        case 'x':
        case 'r':
        case 'l':
        case 'm':
        case 'd':
        case 'o':
        case 'w':
            if (input[2]!=' ') {
                r_cons_printf ("Usage: 'wo%c 00 11 22'\n", input[1]);
                return 0;
            }
        case '2':
        case '4':
            r_core_write_op (core, input+3, input[1]);
            r_core_block_read (core, 0);
            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"
                "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  >>= shift right\n"
                "  wol  <<= shift left\n"
                "  wo2  2=  2 byte endian swap\n"
                "  wo4  4=  4 byte endian swap\n"
            );
            break;
        }
        break;
    default:
    case '?':
        if (core->oobi) {
            eprintf ("Writing oobi buffer!\n");
            r_io_set_fd (core->io, core->file->fd);
            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"
                " 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 commit/reset/list\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"
                " wf file      write contents of file at current offset\n"
                " wF file      write contents of hexpairs file here\n"
                " wt file [sz] write to file (from current seek, blocksize or sz bytes)\n"
                " wp file      apply radare patch file. See wp? fmi\n");
        //TODO: add support for offset+seek
        // " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n"
        break;
    }
Exemple #22
0
static int perform_mapped_file_yank(RCore *core, ut64 offset, ut64 len, const char *filename) {
	// grab the current file descriptor, so we can reset core and io state
	// after our io op is done
	RIODesc *yankdesc = NULL;
	ut64 fd = core->file? core->file->fd: -1, yank_file_sz = 0,
	     loadaddr = 0, addr = offset;
	int res = false;

	if (filename && *filename) {
		ut64 load_align = r_config_get_i (core->config, "file.loadalign");
		RIOMap *map = NULL;
		yankdesc = r_io_open_nomap (core->io, filename, R_PERM_R, 0644);
		// map the file in for IO operations.
		if (yankdesc && load_align) {
			yank_file_sz = r_io_size (core->io);
			map = r_io_map_add_next_available (core->io, yankdesc->fd, R_PERM_R, 0, 0, yank_file_sz, load_align);
			loadaddr = map? map->itv.addr: -1;
			if (yankdesc && map && loadaddr != -1) {
				// ***NOTE*** this is important, we need to
				// address the file at its physical address!
				addr += loadaddr;
			} else if (yankdesc) {
				eprintf ("Unable to map the opened file: %s", filename);
				r_io_desc_close (yankdesc);
				yankdesc = NULL;
			} else {
				eprintf ("Unable to open the file: %s", filename);
			}
		}
	}

	// if len is -1 then we yank in everything
	if (len == -1) {
		len = yank_file_sz;
	}

	// this wont happen if the file failed to open or the file failed to
	// map into the IO layer
	if (yankdesc) {
		ut64 res = r_io_seek (core->io, addr, R_IO_SEEK_SET);
		ut64 actual_len = len <= yank_file_sz? len: 0;
		ut8 *buf = NULL;
		if (actual_len > 0 && res == addr) {
			buf = malloc (actual_len);
			if (!r_io_read_at (core->io, addr, buf, actual_len)) {
				actual_len = 0;
			}
			r_core_yank_set (core, R_CORE_FOREIGN_ADDR, buf, len);
			res = true;
		} else if (res != addr) {
			eprintf (
				"ERROR: Unable to yank data from file: (loadaddr (0x%"
				PFMT64x ") (addr (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", res, addr,
				yank_file_sz );
		} else if (actual_len == 0) {
			eprintf (
				"ERROR: Unable to yank from file: addr+len (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", addr + len,
				yank_file_sz );
		}
		r_io_desc_close (yankdesc);
		free (buf);
	}
	if (fd != -1) {
		r_io_use_fd (core->io, fd);
		core->switch_file_view = 1;
		r_core_block_read (core);
	}
	return res;
}
Exemple #23
0
static void cmd_write_op (RCore *core, const char *input) {
	ut8 *buf;
  char *sequence_err = NULL;
	int len;
	const char* help_msg[] = {
		"Usage:","wo[asmdxoArl24]"," [hexpairs] @ addr[!bsize]",
		"wow"," [val]", "==  write looped value (alias for 'wb')",
		"woa"," [val]", "+=  addition (f.ex: woa 0102)",
		"wos"," [val]", "-=  substraction",
		"wom"," [val]", "*=  multiply",
		"wod"," [val]", "/=  divide",
		"woe"," [from-to] [step]","..  create sequence",
		"wox"," [val]","^=  xor  (f.ex: wox 0x90)",
		"woo"," [val]","|=  or",
		"woA"," [val]","&=  and",
		"woR","","random bytes (alias for 'wr $b')",
		"wor"," [val]", ">>= shift right",
		"wol"," [val]","<<= shift left",
		"wo2"," [val]","2=  2 byte endian swap",
		"wo4"," [val]", "4=  4 byte endian swap",
		"woD"," [len]","De Bruijn Pattern (syntax woD length @ addr)",
		"woO"," [len]", "De Bruijn Pattern Offset (syntax: woO value)",
		NULL
	};
	if (!input[0])
		return;
	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]);
			return;
		}
	case '2':
	case '4':
		if (input[2]){
			r_core_write_op (core, input+3, input[1]);
			r_core_block_read (core, 0);
		} else eprintf ("Missing argument\n");
		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 'D':
        len = strtoul (input+2, &sequence_err, 0);
        if (*sequence_err) {
          printf ("Invalid length: %s\n", sequence_err);
          break;
        }
        if (len > 0) {
          buf = (ut8*)r_debruijn_pattern (len, 0, NULL); //debruijn_charset);
          if (buf) {
              r_core_write_at (core, core->offset, buf, len);
              free (buf);
          } else {
            eprintf ("Couldn't generate pattern of length %d\n", len);
          }
        }
        break;
	case 'O':
        len = strtoul (input+2, &sequence_err, 16);
        if (*sequence_err) {
          eprintf ("Invalid sequence: %s\n", sequence_err);
          break;
        }
		core->num->value = r_debruijn_offset (len, !core->assembler->big_endian);
		r_cons_printf ("%d\n", core->num->value);
		break;
	case '\0':
	case '?':
	default:
		r_core_cmd_help (core, help_msg);
		break;
	}
}
Exemple #24
0
static void cmd_write_op (RCore *core, const char *input) {
	ut8 *buf;
	int len;
	const char* help_msg[] = {
		"Usage:","wo[asmdxoArl24]"," [hexpairs] @ addr[!bsize]",
		"wo[aAdlmorwx24]","", "without hexpair values, clipboard is used",
		"woa"," [val]", "+=  addition (f.ex: woa 0102)",
		"woA"," [val]","&=  and",
		"wod"," [val]", "/=  divide",
		"woD","[algo] [key]","decrypt current block with given algo and key",
		"woe"," [from to] [step] [wsz=1]","..  create sequence",
		"woE"," [algo] [key]", "encrypt current block with given algo and key",
		"wol"," [val]","<<= shift left",
		"wom"," [val]", "*=  multiply",
		"woo"," [val]","|=  or",
		"wopD"," [len]","De Bruijn Pattern (syntax wopD length @ addr)",
		"wopO"," [len]", "De Bruijn Pattern Offset (syntax: wopO value)",
		"wor"," [val]", ">>= shift right",
		"woR","","random bytes (alias for 'wr $b')",
		"wos"," [val]", "-=  substraction",
		"wow"," [val]", "==  write looped value (alias for 'wb')",
		"wox"," [val]","^=  xor  (f.ex: wox 0x90)",
		"wo2"," [val]","2=  2 byte endian swap",
		"wo4"," [val]", "4=  4 byte endian swap",
		NULL
	};
	if (!input[0])
		return;
	switch (input[1]) {
	case 'e':
		if (input[2]!=' ') {
			r_cons_printf ("Usage: 'woe from-to step'\n");
			return;
		}
		/* fallthru */
	case 'a':
	case 's':
	case 'A':
	case 'x':
	case 'r':
	case 'l':
	case 'm':
	case 'd':
	case 'o':
	case 'w':
	case '2':
	case '4':
		if (input[2]) {  // parse val from arg
			r_core_write_op (core, input+3, input[1]);
			r_core_block_read (core, 0);
		} else {  // use clipboard instead of val
			r_core_write_op (core, NULL, 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 'E': // encrypt
	case 'D': // decrypt
		{
			int direction = (input[1] == 'E') ? 0 : 1;
			const char *algo = NULL;
			const char *key = NULL;
			char *space, *args = strdup (r_str_chop_ro (input+2));
			space = strchr (args, ' ');
			if (space) {
				*space++ = 0;
				key = space;
			}
			algo = args;
			if (algo && *algo) {
				encrypt_or_decrypt_block (core, algo, key, direction);
			} else {
				eprintf ("Usage: wo%c [algo] [key]\n", ((!direction)?'E':'D'));
				eprintf ("TODO: list currently supported crypto algorithms\n");
				eprintf ("  rc2, rc4, xor, blowfish, aes, rot, ror, rol\n");
			}
			free (args);
		}
		break;
	case 'p': // debrujin patterns
		switch (input[2]) {
		case 'D':
			len = (int)(input[3]==' ')?
				r_num_math (core->num, input + 3): core->blocksize;
			if (len > 0) {
				buf = (ut8*)r_debruijn_pattern (len, 0, NULL); //debruijn_charset);
				if (buf) {
					r_core_write_at (core, core->offset, buf, len);
					free (buf);
				} else {
					eprintf ("Couldn't generate pattern of length %d\n", len);
				}
			}
			break;
		case 'O':
			len = (int)(input[3]==' ')?
				r_num_math (core->num, input + 3): core->blocksize;
			core->num->value = r_debruijn_offset (len, !core->assembler->big_endian);
			r_cons_printf ("%"PFMT64d"\n", core->num->value);
			break;
		default:
			eprintf ("Invalid arguments for wop\n");
			break;
		}
		break;
	case '\0':
	case '?':
	default:
		r_core_cmd_help (core, help_msg);
		break;
	}
}
Exemple #25
0
R_API int r_core_visual_cmd(RCore *core, int ch) {
    RAsmOp op;
    ut64 offset = core->offset;
    char buf[4096];
    int i, ret, offscreen, cols = core->print->cols, delta = 0;
    ch = r_cons_arrow_to_hjkl (ch);
    ch = visual_nkey (core, ch);
    if (ch<2) return 1;

    // do we need hotkeys for data references? not only calls?
    if (ch>='0'&& ch<='9') {
        ut64 off = core->asmqjmps[ch-'0'];
        if (off != UT64_MAX) {
            int delta = R_ABS ((st64)off-(st64)offset);
            r_io_sundo_push (core->io, offset);
            if (curset && delta<100) {
                cursor = delta;
            } else {
                r_core_visual_seek_animation (core, off);
                //r_core_seek (core, off, 1);
            }
            r_core_block_read (core, 1);
        }
    } else
        switch (ch) {
        case 0x0d:
        {
            r_cons_enable_mouse (R_TRUE);
            RAnalOp *op = r_core_anal_op (core, core->offset+cursor);
            if (op) {
                if (op->type == R_ANAL_OP_TYPE_JMP	||
                        op->type == R_ANAL_OP_TYPE_CJMP ||
                        op->type == R_ANAL_OP_TYPE_CALL) {
                    r_io_sundo_push (core->io, offset);
                    r_core_visual_seek_animation(core, op->jump);
                }
            }
            r_anal_op_free (op);
        }
        break;
        case 90: // shift+tab
            if (!strcmp (printfmt[0], "x"))
                printfmt[0] = "pxa";
            else printfmt[0] = "x";
            break;
        case 9: // tab
        {   // XXX: unify diff mode detection
            ut64 f = r_config_get_i (core->config, "diff.from");
            ut64 t = r_config_get_i (core->config, "diff.to");
            if (f == t && f == 0) {
                core->print->col = core->print->col==1? 2: 1;
            } else {
                ut64 delta = offset - f;
                r_core_seek (core, t+delta, 1);
                r_config_set_i (core->config, "diff.from", t);
                r_config_set_i (core->config, "diff.to", f);
            }
        }
        break;
        case 'a':
            if (core->file && !(core->file->rwx & 2)) {
                r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
                r_cons_any_key ();
                return R_TRUE;
            }
            r_cons_printf ("Enter assembler opcodes separated with ';':\n");
            showcursor (core, R_TRUE);
            r_cons_flush ();
            r_cons_set_raw (R_FALSE);
            strcpy (buf, "wa ");
            r_line_set_prompt (":> ");
            if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0';
            if (*buf) {
                if (curset) r_core_seek (core, core->offset + cursor, 0);
                r_core_cmd (core, buf, R_TRUE);
                if (curset) r_core_seek (core, core->offset - cursor, 1);
            }
            showcursor (core, R_FALSE);
            r_cons_set_raw (R_TRUE);
            break;
        case '!':
            r_cons_2048();
            break;
        case 'o':
            visual_offset (core);
            break;
        case 'A':
        {   int oc = curset;
            ut64 off = curset? core->offset+cursor : core->offset;
            curset = 0;
            r_core_visual_asm (core, off);
            curset = oc;
        }
        break;
        case 'c':
            setcursor (core, curset?0:1);
            break;
        case 'C':
            color = color? 0: 1;
            r_config_set_i (core->config, "scr.color", color);
            break;
        case 'd':
            r_core_visual_define (core);
            break;
        case 'D':
            setdiff (core);
            break;
        case 'f':
        {
            int range, min, max;
            char name[256], *n;
            r_line_set_prompt ("flag name: ");
            showcursor (core, R_TRUE);
            if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) {
                n = r_str_chop (name);
                if (*name=='-') {
                    if (*n) r_flag_unset (core->flags, n+1, NULL);
                } else {
                    if (ocursor != -1) {
                        min = R_MIN (cursor, ocursor);
                        max = R_MAX (cursor, ocursor);
                    } else {
                        min = max = cursor;
                    }
                    range = max-min+1;
                    if (range<1) range = 1;
                    if (*n) r_flag_set (core->flags, n,
                                            core->offset + min, range, 1);
                }
            }
        }
        showcursor (core, R_FALSE);
        break;
        case 'F':
            r_flag_unset_i (core->flags, core->offset + cursor, NULL);
            break;
        case 'n':
            r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
            break;
        case 'N':
            r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
            break;
        case 'i':
        case 'I':
            if (core->file && !(core->file->rwx & 2)) {
                r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
                r_cons_any_key ();
                return R_TRUE;
            }
            showcursor (core, R_TRUE);
            r_cons_flush ();
            r_cons_set_raw (0);
            if (ch=='I') {
                strcpy (buf, "wow ");
                r_line_set_prompt ("insert hexpair block: ");
                if (r_cons_fgets (buf+4, sizeof (buf)-5, 0, NULL) <0)
                    buf[0]='\0';
                char *p = strdup (buf);
                int cur = core->print->cur;
                if (cur>=core->blocksize)
                    cur = core->print->cur-1;
                snprintf (buf, sizeof (buf), "%s @ $$0!%i", p,
                          core->blocksize-cursor);
                r_core_cmd (core, buf, 0);
                free (p);
                break;
            }
            delta = (ocursor!=-1)? R_MIN (cursor, ocursor): cursor;
            if (core->print->col==2) {
                strcpy (buf, "\"w ");
                r_line_set_prompt ("insert string: ");
                if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0)
                    buf[0]='\0';
                strcat (buf, "\"");
            } else {
                r_line_set_prompt ("insert hex: ");
                if (ocursor != -1) {
                    int bs = R_ABS (cursor-ocursor)+1;
                    core->blocksize = bs;
                    strcpy (buf, "wow ");
                } else {
                    strcpy (buf, "wx ");
                }
                if (r_cons_fgets (buf+strlen (buf), sizeof (buf)-strlen (buf), 0, NULL) <0)
                    buf[0]='\0';
            }
            if (curset) r_core_seek (core, core->offset + delta, 0);
            r_core_cmd (core, buf, 1);
            if (curset) r_core_seek (core, offset, 1);
            r_cons_set_raw (1);
            showcursor (core, R_FALSE);
            break;
        case 'R':
            r_core_cmd0 (core, "ecr");
            break;
        case 'e':
            r_core_visual_config (core);
            break;
        case 'E':
            r_core_visual_colors (core);
            break;
        case 'M':
            r_core_visual_mounts (core);
            break;
        case 't':
            r_core_visual_trackflags (core);
            break;
        case 'x':
        {
            int count = 0;
            RList *xrefs = NULL;
            RAnalRef *refi;
            RListIter *iter;
            RAnalFunction *fun;

            if ((xrefs = r_anal_xref_get (core->anal, core->offset))) {
                r_cons_gotoxy (1, 1);
                r_cons_printf ("[GOTO XREF]> \n");
                if (r_list_empty (xrefs)) {
                    r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset);
                    r_cons_any_key ();
                    r_cons_clear00 ();
                } else {
                    r_list_foreach (xrefs, iter, refi) {
                        fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL);
                        r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s)                      \n", count,
                                       refi->at,
                                       refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
                                       refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
                                       fun?fun->name:"unk");
                        if (++count > 9) break;
                    }
                }
            } else xrefs = NULL;
Exemple #26
0
R_API int r_core_visual_cmd(RCore *core, int ch) {
	RAsmOp op;
	char buf[4096];
	int i, ret, offscreen, cols = core->print->cols;
	ch = r_cons_arrow_to_hjkl (ch);
	ch = visual_nkey (core, ch);
	if (ch<2) return 1;

	// do we need hotkeys for data references? not only calls?
	if (ch>='0'&& ch<='9') {
		r_io_sundo_push (core->io, core->offset);
		r_core_seek (core, core->asmqjmps[ch-'0'], 1);
		r_core_block_read (core, 1);
	} else
	switch (ch) {
	case 9: // tab
		{ // XXX: unify diff mode detection
		ut64 f = r_config_get_i (core->config, "diff.from");
		ut64 t = r_config_get_i (core->config, "diff.to");
		if (f == t && f == 0) {
			core->print->col = core->print->col==1? 2: 1;
		} else {
			ut64 delta = core->offset - f;
			r_core_seek (core, t+delta, 1);
			r_config_set_i (core->config, "diff.from", t);
			r_config_set_i (core->config, "diff.to", f);
		}
		}
		break;
	case 'c':
		// XXX dupped flag imho
		setcursor (core, curset ^ 1);
		break;
	case 'd':
		r_core_visual_define (core);
		break;
	case 'D':
		setdiff (core);
		break;
	case 'C':
		color ^= 1;
		if (color) flags |= R_PRINT_FLAGS_COLOR;
		else flags &= ~(flags&R_PRINT_FLAGS_COLOR);
		r_config_set_i (core->config, "scr.color", color);
		r_print_set_flags (core->print, flags);
		break;
	case 'f':
		{
		int range;
		char name[256], *n;
		r_line_set_prompt ("flag name: ");
		if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) {
			n = r_str_chop (name);
			if (*name=='-') {
				if (*n) r_flag_unset (core->flags, n+1, NULL);
			} else {
				range = curset? (R_ABS (cursor-ocursor)+1): 1;
				if (range<1) range = 1;
				if (*n) r_flag_set (core->flags, n,
					core->offset + cursor, range, 1);
			}
		} }
		break;
	case 'F':
		r_flag_unset_i (core->flags, core->offset + cursor, NULL);
		break;
	case 'n':
		r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
		break;
	case 'N':
		r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
		break;
	case 'A':
		{ int oc = curset;
		ut64 off = curset? core->offset+cursor : core->offset;
		curset = 0;
		r_core_visual_asm (core, off);
		curset = oc;
		}
		break;
	case 'a':
		if (core->file && !(core->file->rwx & 2)) {
			r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
			r_cons_any_key ();
			return R_TRUE;
		}
		r_cons_printf ("Enter assembler opcodes separated with ';':\n");
		r_cons_show_cursor (R_TRUE);
		r_cons_flush ();
		r_cons_set_raw (R_FALSE);
		strcpy (buf, "wa ");
		r_line_set_prompt (":> ");
		if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0';
		if (*buf) {
			if (curset) r_core_seek (core, core->offset + cursor, 0);
			r_core_cmd (core, buf, R_TRUE);
			if (curset) r_core_seek (core, core->offset - cursor, 1);
		}
		r_cons_show_cursor (R_FALSE);
		r_cons_set_raw (R_TRUE);
		break;
	case 'i':
	case 'I':
		if (core->file && !(core->file->rwx & 2)) {
			r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
			r_cons_any_key ();
			return R_TRUE;
		}
		r_cons_show_cursor (R_TRUE);
		r_cons_flush ();
		r_cons_set_raw (0);
		if (ch=='I') {
			strcpy (buf, "wow ");
			r_line_set_prompt ("insert hexpair block: ");
			if (r_cons_fgets (buf+4, sizeof (buf)-3, 0, NULL) <0)
				buf[0]='\0';
			char *p = strdup (buf);
			int cur = core->print->cur;
			if (cur>=core->blocksize)
				cur = core->print->cur-1;
			snprintf (buf, sizeof (buf), "%s @ $$0!%i", p,
				core->blocksize-cursor);
			r_core_cmd (core, buf, 0);
			free (p);
			break;
		}
		if (core->print->col==2) {
			strcpy (buf, "w ");
			r_line_set_prompt ("insert string: ");
			if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) <0)
				buf[0]='\0';
		} else {
			strcpy (buf, "wx ");
			r_line_set_prompt ("insert hex: ");
			if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0)
				buf[0]='\0';
		}
		if (curset) r_core_seek (core, core->offset + cursor, 0);
		r_core_cmd (core, buf, 1);
		if (curset) r_core_seek (core, core->offset - cursor, 1);
		r_cons_set_raw (1);
		r_cons_show_cursor (R_FALSE);
		break;
	case 'e':
		r_core_visual_config (core);
		break;
	case 'M':
		r_core_visual_mounts (core);
		break;
	case 't':
		r_core_visual_trackflags (core);
		break;
	case 'x':
		{
		int count = 0;
		RList *xrefs = NULL;
		RAnalRef *refi;
		RListIter *iter;
		RAnalFunction *fun;

		if ((xrefs = r_anal_xref_get (core->anal, core->offset))) {
			r_cons_printf ("XREFS:\n");
			if (r_list_empty (xrefs)) {
				r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset);
				r_cons_any_key ();
				r_cons_clear00 ();
			} else {
				r_list_foreach (xrefs, iter, refi) {
					fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL);
					r_cons_printf ("\t[%i] %s XREF 0x%08"PFMT64x" (%s)\n", count,
							refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
							refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
							fun?fun->name:"unk");
					if (++count > 9) break;
				}
			}
		} else xrefs = NULL;
Exemple #27
0
R_API int r_core_file_reopen(RCore *core, const char *args, int perm, int loadbin) {
	int isdebug = r_config_get_i (core->config, "cfg.debug");
	char *path;
	ut64 laddr = r_config_get_i (core->config, "bin.laddr");
	RCoreFile *file = NULL;
	RCoreFile *ofile = core->file;
	RBinFile *bf = ofile ? r_bin_file_find_by_fd (core->bin, ofile->fd)
		: NULL;
	RIODesc *odesc = (core->io && ofile) ? r_io_desc_get (core->io, ofile->fd) : NULL;
	char *ofilepath = NULL, *obinfilepath = (bf && bf->file)? strdup (bf->file): NULL;
	int ret = false;
	ut64 origoff = core->offset;
	if (odesc) {
		if (odesc->referer) {
			ofilepath = odesc->referer;
		} else if (odesc->uri) {
			ofilepath = odesc->uri;
		}
	}

	if (r_sandbox_enable (0)) {
		eprintf ("Cannot reopen in sandbox\n");
		free (obinfilepath);
		return false;
	}
	if (!core->file) {
		eprintf ("No file opened to reopen\n");
		free (ofilepath);
		free (obinfilepath);
		return false;
	}
	int newpid = odesc? odesc->fd: -1;

	if (isdebug) {
		r_debug_kill (core->dbg, core->dbg->pid, core->dbg->tid, 9); // KILL
		perm = 7;
	} else {
		if (!perm) {
			perm = 4; //R_IO_READ;
		}
	}
	if (!ofilepath) {
		eprintf ("Unknown file path");
		free (obinfilepath);
		return false;
	}

	// HACK: move last mapped address to higher place
	// XXX - why does this hack work?
	// when the new memory maps are created.
	path = strdup (ofilepath);
	free (obinfilepath);
	obinfilepath = strdup (ofilepath);

	// r_str_trim (path);
	file = r_core_file_open (core, path, perm, laddr);
	if (file) {
		bool had_rbin_info = false;

		if (ofile) {
			if (r_bin_file_delete (core->bin, ofile->fd)) {
				had_rbin_info = true;
			}
		}
		r_core_file_close (core, ofile);
		r_core_file_set_by_file (core, file);
		ofile = NULL;
		odesc = NULL;
		//	core->file = file;
		eprintf ("File %s reopened in %s mode\n", path,
			(perm & R_IO_WRITE)? "read-write": "read-only");

		if (loadbin && (loadbin == 2 || had_rbin_info)) {
			ut64 baddr = r_config_get_i (core->config, "bin.baddr");
			ret = r_core_bin_load (core, obinfilepath, baddr);
			r_core_bin_update_arch_bits (core);
			if (!ret) {
				eprintf ("Error: Failed to reload rbin for: %s", path);
			}
		}

		if (core->bin->cur && core->io && r_io_desc_get (core->io, file->fd) && !loadbin) {
			//force here NULL because is causing uaf look this better in future XXX @alvarofe
			core->bin->cur = NULL;
		}
		// close old file
	} else if (ofile) {
		eprintf ("r_core_file_reopen: Cannot reopen file: %s with perms 0x%04x,"
			" attempting to open read-only.\n", path, perm);
		// lower it down back
		//ofile = r_core_file_open (core, path, R_IO_READ, addr);
		r_core_file_set_by_file (core, ofile);
	} else {
		eprintf ("Cannot reopen\n");
	}
	if (isdebug) {
		int newtid = newpid;
		// XXX - select the right backend
		if (core->file) {
			newpid = r_io_fd_get_pid (core->io, core->file->fd);
			newtid = r_io_fd_get_tid (core->io, core->file->fd);
#if __linux__
			core->dbg->main_pid = newpid;
			newtid = newpid;
#endif
#pragma message ("fix debugger-concept in core")
#if __WINDOWS__
			r_debug_select (core->dbg, newpid, newtid);
			core->dbg->reason.type = R_DEBUG_REASON_NONE;
#endif
		}
		//reopen and attach
		r_core_setup_debugger (core, "native", true);
		r_debug_select (core->dbg, newpid, newtid);
	}
	if (core->file) {
		r_io_use_fd (core->io, core->file->fd);
		core->switch_file_view = 1;
		r_core_block_read (core);
#if 0
		else {
Exemple #28
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;
	}
Exemple #29
0
static int perform_mapped_file_yank (RCore *core, ut64 offset, ut64 len, const char *filename) {
	// grab the current file descriptor, so we can reset core and io state
	// after our io op is done
	RIODesc *yankfd = NULL;
	ut64 fd = core->file ? core->file->desc->fd : -1, yank_file_sz = 0,
		 loadaddr = 0, addr = offset;
	int res = R_FALSE;

	if (filename && *filename) {
		ut64 load_align = r_config_get_i (core->config,
			"file.loadalign");
		RIOMap * map = NULL;
		yankfd = r_io_open (core->io, filename, R_IO_READ, 0644);
		// map the file in for IO operations.
		if (yankfd && load_align) {
			yank_file_sz = r_io_size (core->io);
			map = r_io_map_add_next_available (core->io,
				yankfd->fd,
				R_IO_READ, 0, 0,
				yank_file_sz,
				load_align);
			loadaddr = map ? map->from : -1;
			if (yankfd && map && loadaddr != -1) {
				// ***NOTE*** this is important, we need to
				// address the file at its physical address!
				addr += loadaddr;
			} else if (yankfd) {
				eprintf ("Unable to map the opened file: %s", filename);
				r_io_close (core->io, yankfd);
				yankfd = NULL;
			} else {
				eprintf ("Unable to open the file: %s", filename);
			}
		}
	}

	// if len is -1 then we yank in everything
	if (len == -1) len = yank_file_sz;

	IFDBG eprintf ("yankfd: %p, yank->fd = %d, fd=%d\n", yankfd,
		       (int)(yankfd ? yankfd->fd : -1), (int)fd);
	// this wont happen if the file failed to open or the file failed to
	// map into the IO layer
	if (yankfd) {
		ut64 res = r_io_seek (core->io, addr, R_IO_SEEK_SET),
		     actual_len = len <= yank_file_sz ? len : 0;
		ut8 *buf = NULL;
		IFDBG eprintf (
			"Addr (%"PFMT64d
			") file_sz (%"PFMT64d
			") actual_len (%"PFMT64d
			") len (%"PFMT64d
			") bytes from file: %s\n", addr, yank_file_sz,
			actual_len, len, filename);
		if (actual_len > 0 && res == addr) {
			IFDBG eprintf (
				"Creating buffer and reading %"PFMT64d
				" bytes from file: %s\n", actual_len, filename);
			buf = malloc (actual_len);
			actual_len = r_io_read_at (core->io, addr, buf,
				actual_len);
			IFDBG eprintf (
				"Reading %"PFMT64d " bytes from file: %s\n",
				actual_len, filename);
			/*IFDBG {
				int i = 0;
				eprintf ("Read these bytes from file: \n");
				for (i = 0; i < actual_len; i++)
					eprintf ("%02x", buf[i]);
				eprintf ("\n");
			}*/
			r_core_yank_set (core, R_CORE_FOREIGN_ADDR, buf, len);
			res = R_TRUE;
		} else if (res != addr) {
			eprintf (
				"ERROR: Unable to yank data from file: (loadaddr (0x%"
				PFMT64x ") (addr (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", res, addr,
				yank_file_sz );
		} else if (actual_len == 0) {
			eprintf (
				"ERROR: Unable to yank from file: addr+len (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", addr+len,
				yank_file_sz );
		}
		r_io_close (core->io, yankfd);
		free (buf);
	}
	if (fd != -1) {
		r_io_raise (core->io, fd);
		core->switch_file_view = 1;
		r_core_block_read (core, 0);
	}
	return res;
}
Exemple #30
0
static void cmd_write_value (RCore *core, const char *input) {
	int type = 0;
	ut8 addr1;
	ut16 addr2;
	ut32 addr4, addr4_;
	ut64 addr8, off = 0LL;
	int wseek = r_config_get_i (core->config, "cfg.wseek");

	if (!input)
		return;

	if (input[0])
	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;
	case '1': type = 1; break;
	case '2': type = 2; break;
	case '4': type = 4; break;
	case '8': type = 8; break;
	}
	if (input && input[0] && input[1] && input[2]) {
		off = r_num_math (core->num, input+2);
	}
	if (core->file) {
		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);
}