Exemplo n.º 1
0
static int r_cmd_yara_scan(const RCore* core) {
    RListIter* rules_it;
    YR_RULES* rules;
    void* to_scan;
    int result;
    const unsigned int to_scan_size = r_io_size (core->io);

    if (to_scan_size < 1) {
        eprintf ("Invalid file size\n");
        return R_FALSE;
    }

    to_scan = malloc (to_scan_size);
    if (!to_scan) {
        eprintf ("Something went wrong during memory allocation\n");
        return R_FALSE;
    }

    result = r_io_read_at (core->io, 0L, to_scan, to_scan_size);
    if (!result) {
        eprintf ("Something went wrong during r_io_read_at\n");
        free (to_scan);
        return R_FALSE;
    }

    r_list_foreach (rules_list, rules_it, rules) {
        yr_rules_scan_mem (rules, to_scan, to_scan_size, 0, callback, NULL, 0);
    }
Exemplo n.º 2
0
static ut8 *slurp(RCore **c, const char *file, int *sz) {
	RIODesc *d;
	RIO *io;
	if (c && file && strstr (file, "://")) {
		ut8 *data = NULL;
		ut64 size;
		if (!*c) {
			*c = opencore (NULL);
		}
		io = (*c)->io;
		d = r_io_open (io, file, 0, 0);
		if (!d) {
			return NULL;
		}
		size = r_io_size (io);
		if (size > 0 || size < ST32_MAX) {
			data = calloc (1, size);
			if (r_io_read_at (io, 0, data, size) == size) {
				if (sz) {
					*sz = size;
				}
			} else {
				eprintf ("slurp: read error\n");
				R_FREE (data);
			}
		} else {
			eprintf ("slurp: File is too big\n");
		}
		r_io_close (io, d);
		return data;
	}
	return (ut8*)r_file_slurp (file, sz);
}
Exemplo n.º 3
0
R_API ut64 r_io_desc_size(RIO *io, RIODesc *desc){
	RIODesc *old = NULL;
	ut64 sz = -1;
	if (desc && io->desc != desc){
		old = io->desc;
		r_io_use_desc (io, desc);
	}
	if (desc) sz = r_io_size(io);
	if (old) r_io_use_desc (io, old);
	return sz;
}
Exemplo n.º 4
0
static bool flagbar_foreach(RFlagItem *fi, void *user) {
	struct flagbar_t *u = (struct flagbar_t *)user;
	ut64 min = 0, max = r_io_size (u->core->io);
	RIOMap *m = r_io_map_get (u->core->io, fi->offset);
	if (m) {
		min = m->itv.addr;
		max = m->itv.addr + m->itv.size;
	}
	r_cons_printf ("0x%08"PFMT64x" ", fi->offset);
	r_print_rangebar (u->core->print, fi->offset, fi->offset + fi->size, min, max, u->cols);
	r_cons_printf ("  %s\n", fi->name);
	return true;
}
Exemplo n.º 5
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);
	}
	core->file->size = r_io_size (core->io);
	return (ret==-1)? R_FALSE: R_TRUE;
}
Exemplo n.º 6
0
R_API ut64 r_io_desc_size(RIO *io, RIODesc *desc){
	RIODesc *old = NULL;
    	ut64 sz = -1;
	
	if (desc && io->fd != desc){
		old = io->fd;
		r_io_set_fd(io, desc);
	}
        
	if (desc) sz = r_io_size(io);
	
	if(old){
		r_io_set_fd(io, old);
	}
	return sz;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static int do_hash(const char *file, const char *algo, RIO *io, int bsize, int rad, int ule) {
	ut64 j, fsize, algobit = r_hash_name_to_bits (algo);
	RHash *ctx;
	ut8 *buf;
	int i, first = 1;
	if (algobit == R_HASH_NONE) {
		eprintf ("rahash2: Invalid hashing algorithm specified\n");
		return 1;
	}
	fsize = r_io_size (io);
	if (fsize <1) {
		eprintf ("rahash2: Invalid file size\n");
		return 1;
	}
	if (bsize<0) bsize = fsize / -bsize;
	if (bsize == 0 || bsize > fsize) bsize = fsize;
	if (to == 0LL) to = fsize;
	if (from>to) {
		eprintf ("rahash2: Invalid -f -t range\n");
		return 1;
	}
	if (fsize == -1LL) {
		eprintf ("rahash2: Unknown file size\n");
		return 1;
	}
	buf = malloc (bsize+1);
	if (!buf)
		return 1;
	ctx = r_hash_new (R_TRUE, algobit);

	if (rad == 'j')
		printf ("[");
	if (incremental) {
		for (i=1; i<0x800000; i<<=1) {
			if (algobit & i) {
				int hashbit = i & algobit;
				int dlen = r_hash_size (hashbit);
				r_hash_do_begin (ctx, i);
				if (rad == 'j') {
					if (first) {
						first = 0;
					} else {
						printf (",");
					}
				}
				if (s.buf && s.prefix) {
					do_hash_internal (ctx,
						hashbit, s.buf, s.len, rad, 0, ule);
				}
				for (j=from; j<to; j+=bsize) {
					int len = ((j+bsize)>to)? (to-j): bsize;
					r_io_pread (io, j, buf, len);
					do_hash_internal (ctx, hashbit, buf,
						len, rad, 0, ule);
				}
				if (s.buf && !s.prefix) {
					do_hash_internal (ctx, hashbit, s.buf,
						s.len, rad, 0, ule);
				}
				r_hash_do_end (ctx, i);
				if (iterations>0)
					r_hash_do_spice (ctx, i, iterations, _s);
				if (!*r_hash_name (i))
					continue;
				if (!quiet && rad != 'j')
					printf ("%s: ", file);
				do_hash_print (ctx, i, dlen, rad, ule);
			}
		}
		if (_s)
			free (_s->buf);
	} else {
		/* iterate over all algorithm bits */
		if (s.buf)
			eprintf ("Warning: Seed ignored on per-block hashing.\n");
		for (i=1; i<0x800000; i<<=1) {
			ut64 f, t, ofrom, oto;
			if (algobit & i) {
				int hashbit = i & algobit;
				ofrom = from;
				oto = to;
				f = from;
				t = to;
				for (j=f; j<t; j+=bsize) {
					int nsize = (j+bsize<fsize)? bsize: (fsize-j);
					r_io_pread (io, j, buf, bsize);
					from = j;
					to = j+bsize;
					if (to>fsize)
						to = fsize;
					do_hash_internal (ctx, hashbit, buf, nsize, rad, 1, ule);
				}
				from = ofrom;
				to = oto;
			}
		}
	}
	if (rad == 'j')
		printf ("]\n");
	r_hash_free (ctx);
	free (buf);
	return 0;
}
Exemplo n.º 9
0
static int do_hash(const char *algo, RIO *io, int bsize, int rad) {
	ut8 *buf;
	RHash *ctx;
	ut64 j, fsize;
	int i;
	ut64 algobit = r_hash_name_to_bits (algo);
	if (algobit == R_HASH_NONE) {
		eprintf ("Invalid hashing algorithm specified\n");
		return 1;
	}
	fsize = r_io_size (io);
	if (bsize == 0 || bsize > fsize)
		bsize = fsize;
	if (to == 0LL)
		to = fsize;
	if (from>to) {
		eprintf ("Invalid -f -t range\n");
		return 1;
	}
	if (fsize == -1LL) {
		eprintf ("Unknown file size\n");
		return 1;
	}
	buf = malloc (bsize+1);
	ctx = r_hash_new (R_TRUE, algobit);

	if (incremental) {
		for (i=1; i<0x800000; i<<=1) {
			if (algobit & i) {
				int hashbit = i & algobit;
				int dlen = r_hash_size (hashbit);
				r_hash_do_begin (ctx, i);
				for (j=from; j<to; j+=bsize) {
					r_io_read_at (io, j, buf, bsize);
					do_hash_internal (ctx,
						hashbit, buf, ((j+bsize)<fsize)?
						bsize: (fsize-j), rad, 0);
				}
				r_hash_do_end (ctx, i);
				do_hash_print (ctx, i, dlen, rad);
			}
		}
	} else {
		/* iterate over all algorithm bits */
		for (i=1; i<0x800000; i<<=1) {
			ut64 f, t, ofrom, oto;
			if (algobit & i) {
				int hashbit = i & algobit;
				ofrom = from;
				oto = to;
				f = from;
				t = to;
				for (j=f; j<t; j+=bsize) {
					int nsize = (j+bsize<fsize)? bsize: (fsize-j);
					r_io_read_at (io, j, buf, bsize);
					from = j;
					to = j+bsize;
					do_hash_internal (ctx, hashbit, buf, nsize, rad, 1);
				}
				from = ofrom;
				to = oto;
			}
		}
	}
	r_hash_free (ctx);
	free (buf);
	return 0;
}
Exemplo n.º 10
0
Arquivo: yank.c Projeto: csarn/radare2
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;
}
Exemplo n.º 11
0
static int rafind_open_file(char *file) {
	const char *kw;
	RListIter *iter;
	bool last = false;
	int ret;

	if (!quiet) {
		printf ("File: %s\n", file);
	}

	if (identify) {
		char *cmd = r_str_newf ("r2 -e search.show=false -e search.maxhits=1 -nqcpm '%s'", file);
		r_sandbox_system (cmd, 1);
		free (cmd);
		return 0;
	}

	io = r_io_new ();
	fd = r_io_open_nomap (io, file, R_PERM_R, 0);
	if (!fd) {
		eprintf ("Cannot open file '%s'\n", file);
		return 1;
	}

	r_cons_new ();
	rs = r_search_new (mode);
	if (!rs) {
		return 1;
	}
	buf = calloc (1, bsize);
	if (!buf) {
		eprintf ("Cannot allocate %"PFMT64d" bytes\n", bsize);
		return 1;
	}
	rs->align = align;
	r_search_set_callback (rs, &hit, buf);
	if (to == -1) {
		to = r_io_size(io);
	}
	if (mode == R_SEARCH_STRING) {
		/* TODO: implement using api */
		r_sys_cmdf ("rabin2 -qzzz '%s'", file);
		return 0;
	}
	if (mode == R_SEARCH_MAGIC) {
		char *tostr = (to && to != UT64_MAX)?
			r_str_newf ("-e search.to=%"PFMT64d, to): strdup ("");
		char *cmd = r_str_newf ("r2"
			" -e search.in=range"
			" -e search.align=%d"
			" -e search.from=%"PFMT64d
			" %s -qnc/m '%s'",
			align, from, tostr, file);
		r_sandbox_system (cmd, 1);
		free (cmd);
		free (tostr);
		return 0;
	}
	if (mode == R_SEARCH_ESIL) {
		char *cmd;
		r_list_foreach (keywords, iter, kw) {
			cmd = r_str_newf ("r2 -qc \"/E %s\" %s", kw, file);
			r_sandbox_system (cmd, 1);
			free (cmd);
		}
Exemplo n.º 12
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len;
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename = "";
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa","[?] push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wao"," [?] op","modify opcode (change conditional of jump. nop, etc)",
		"wA"," [?] r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[?][ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[?] [nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo","[?] hex","write in block with operation. 'wo?' fmi",
		"wp"," [?] -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt[f]"," [?] file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"wts"," host:port [sz]", "send data to remote host:port via tcp://",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx","[?][fs] 9090","write two intel nops (from wxfile or wxseek)",
		"wv","[?] eip+34","write 32-64 bit value",
		"wz"," string","write zero terminated string (like w + \\x00)",
		NULL
	};

	if (!input) {
		return 0;
	}

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

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

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

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

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

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

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

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


		if (cmd_suc == false) {
			const char* help_msg[] = {
			"Usage", "", "write extend",
			"wen", " <num>", "insert num null bytes at current offset",
			"wex", " <hex_bytes>", "insert bytes at current offset",
			"weN", " <addr> <len>", "insert bytes at address",
			"weX", " <addr> <hex_bytes>", "insert bytes at address",
			"wes", " <addr>  <dist> <block_size>", "shift a blocksize left or write in the editor",
			NULL};
			r_core_cmd_help (core, help_msg);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				r_cons_printf ("Usage: wp [-|r2patch-file]\n"
					" ^# -> comments\n"
					" . -> execute command\n"
					" ! -> execute command\n"
					" OFFSET { code block }\n"
					" OFFSET \"string\"\n"
					" OFFSET 01020304\n"
					" OFFSET : assembly\n"
					" + {code}|\"str\"|0210|: asm\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r': //wr
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len > 0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			{
			const char* help_msg[] = {
				"Usage:", " wA", "[type] [value]",
				"Types", "", "",
				"r", "", "raw write value",
				"v", "", "set value (taking care of current address)",
				"d", "", "destination register",
				"0", "", "1st src register",
				"1", "", "2nd src register",
				"Example:",  "wA r 0", "# e800000000",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core);
			break;
		case 'r':
			r_io_cache_reset (core->io, true);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, true);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				from = r_num_math (core->num, input+3);
				if (p) {
					*p = 0;
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, true);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '?':
			{
				const char* help_msg[] = {
					"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
					"wc","","list all write changes",
					"wc-"," [from] [to]","remove write op at curseek or given addr",
					"wc+"," [addr]","commit change from cache to io",
					"wc*","","\"\" in radare commands",
					"wcr","","reset all write changes in cache",
					"wci","","commit write cache",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
		case '*':
			r_io_cache_list (core->io, 1);
			break;
		case 'j':
			r_io_cache_list (core->io, 2);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, 0);
			break;
		}
		break;
	case ' ': // "w"
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core);
		break;
	case 'z': // "wz"
		/* write zero-terminated string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str + 1, len);
		if (len > 0) {
			core->num->value = len;
		} else {
			core->num->value = 0;
		}
#if 0
		r_io_use_desc (core->io, core->file->desc);
#endif
		WSEEK (core, len + 1);
		r_core_block_read (core);
		break;
	case 't': // "wt"
		if (*str == 's') { // "wts"
			if (str[1] == ' ') {
				eprintf ("Write to server\n");
				st64 sz = r_io_size (core->io);
				if (sz > 0) {
					ut64 addr = 0;
					char *host = str + 2;
					char *port = strchr (host, ':');
					if (port) {
						*port ++= 0;
						char *space = strchr (port, ' ');
						if (space) {
							*space++ = 0;
							sz = r_num_math (core->num, space);
							addr = core->offset;
						}
						ut8 *buf = calloc (1, sz);
						r_io_read_at (core->io, addr, buf, sz);
						RSocket *s = r_socket_new (false);
						if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, 0)) {
							int done = 0;
							eprintf ("Transfering file to the end-point...\n");
							while (done < sz) {
								int rc = r_socket_write (s, buf + done, sz - done);
								if (rc <1) {
									eprintf ("oops\n");
									break;
								}
								done += rc;
							}
						} else {
							eprintf ("Cannot connect\n");
						}
						r_socket_free (s);
						free (buf);
					} else {
						eprintf ("Usage wts host:port [sz]\n");
					}
				} else {
					eprintf ("Unknown file size\n");
				}
			} else {
				eprintf ("Usage wts host:port [sz]\n");
			}
		} else if (*str == '?' || *str == '\0') {
			const char* help_msg[] = {
				"Usage:", "wt[a] file [size]", " Write 'size' bytes in current blok to 'file'",
				"wta", " [filename]", "append to 'filename'",
				"wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')",
				"wtf!", " [filename]", "write to file from current addresss to eof",
				NULL};
			r_core_cmd_help (core, help_msg);
			free (ostr);
			return 0;
		} else {
			bool append = false;
			bool toend = false;
			st64 sz = core->blocksize;
			if (*str == 'f') { // "wtf"
				str++;
				if (*str == '!') {
					toend = true;
					str++;
				}
				if (*str) {
					filename = str + ((*str == ' ')? 1: 0);
				} else {
					filename = "";
				}
			} else if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0] == ' ') {
					filename = str + 1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else {
				filename = str + 1;
			}
			tmp = strchr (str + 1, ' ');
			if (!filename || !*filename) {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			}
			if (tmp) {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
				} else {
					sz = (st64) r_num_math (core->num, tmp + 1);
					if (!sz) {
						sz = core->blocksize;
					}
					*tmp = 0;
				}
				if (sz < 1) {
					eprintf ("Invalid length\n");
				} else {
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				}
			} else {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				} else {
					if (!r_file_dump (filename, core->block, core->blocksize, append)) {
						sz = 0;
					} else {
						sz = core->blocksize;
					}
				}
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		cmd_wf (core, input);
		break;
	case 'w':
		str++;
		len = (len - 1) << 1;
		tmp = (len > 0) ? malloc (len + 1) : NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (tmp);
		} else {
			eprintf ("Cannot malloc %d\n", len);
		}
		break;
	case 'x': // "wx"
		switch (input[1]) {
		case 'f': // "wxf"
			arg = (const char *)(input + ((input[2]==' ')? 3: 2));
			if (!strcmp (arg, "-")) {
				int len;
				ut8 *out;
				char *in = r_core_editor (core, NULL, NULL);
				if (in) {
					out = (ut8 *)strdup (in);
					if (out) {
						len = r_hex_str2bin (in, out);
						if (len > 0) {
							r_io_write_at (core->io, core->offset, out, len);
							core->num->value = len;
						} else {
							core->num->value = 0;
						}
						free (out);
					}
					free (in);
				}
			} else if (r_file_exists (arg)) {
				if ((buf = r_file_slurp_hexpairs (arg, &size))) {
					r_io_use_desc (core->io, core->file->desc);
					if (r_io_write_at (core->io, core->offset, buf, size) > 0) {
						core->num->value = size;
						WSEEK (core, size);
					}
					free (buf);
					r_core_block_read (core);
				} else {
					eprintf ("This file doesnt contains hexpairs\n");
				}
			} else {
				eprintf ("Cannot open file '%s'\n", arg);
			}
			break;
		case 's': // "wxs"
			{
				int len = cmd_write_hexpair (core, input + 2);
				if (len > 0) {
					r_core_seek_delta (core, len);
					core->num->value = len;
				} else {
					core->num->value = 0;
				}
			}
			break;
		case ' ': // "wx ..."
			cmd_write_hexpair (core, input + 1);
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wx[f] [arg]", "",
				"wx", " 9090", "write two intel nops",
				"wxf", " -|file", "write contents of hexpairs file here",
				"wxs", " 9090", "write hexpairs and seek at the end",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'a': // "wa"
		switch (input[1]) {
		case 'o': // "wao"
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					cmd_write_hexpair(core, acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f': // "wof"
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						cmd_write_hexpair(core, acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wa[of*] [arg]", "",
				"wa", " nop", "write nopcode using asm.arch and asm.bits",
				"wa*", " mov eax, 33", "show 'wx' op with hexpair bytes of assembled opcode",
				"\"wa nop;nop\"", "" , "assemble more than one instruction (note the quotes)",
				"waf", "foo.asm" , "assemble file and write bytes",
				"wao?", "", "show help for assembler operation on current opcode (hack)",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'b': // "wb"
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Exemplo n.º 13
0
Arquivo: cio.c Projeto: f0829/radare2
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist) {
	// bstart - block start, fstart file start
	ut64 fend = 0, fstart = 0, bstart = 0, file_sz = 0;
	ut8 * shift_buf = NULL;
	int res = false;

	if (!core->io || !core->file) {
		return false;
	}

	if (b_size == 0 || b_size == (ut64) -1) {
		r_io_use_fd (core->io, core->file->fd);
		file_sz = r_io_size (core->io);
		if (file_sz == UT64_MAX) {
			file_sz = 0;
		}
#if 0
		bstart = r_io_seek (core->io, addr, R_IO_SEEK_SET);
		fend = r_io_seek (core->io, 0, R_IO_SEEK_END);
		if (fend < 1) {
			fend = 0;
		}
#else
		bstart = 0;
		fend = file_sz;
#endif
		fstart = file_sz - fend;
		b_size = fend > bstart ? fend - bstart: 0;
	}

	if ((st64)b_size < 1) {
		return false;
	}
	shift_buf = calloc (b_size, 1);
	if (!shift_buf) {
		eprintf ("Cannot allocated %d byte(s)\n", (int)b_size);
		return false;
	}

	// cases
	// addr + b_size + dist > file_end
	//if ( (addr+b_size) + dist > file_end ) {
	//	res = false;
	//}
	// addr + b_size + dist < file_start (should work since dist is signed)
	//else if ( (addr+b_size) + dist < 0 ) {
	//	res = false;
	//}
	// addr + dist < file_start
	if (addr + dist < fstart) {
		res = false;
	// addr + dist > file_end
	} else if ( (addr) + dist > fend) {
		res = false;
	} else {
		r_io_use_fd (core->io, core->file->fd);
		r_io_read_at (core->io, addr, shift_buf, b_size);
		r_io_write_at (core->io, addr + dist, shift_buf, b_size);
		res = true;
	}
	r_core_seek (core, addr, 1);
	free (shift_buf);
	return res;
}