This commit is contained in:
condret 2017-04-24 19:45:33 +00:00
parent 6db6c6c72f
commit 1ab91415e6
7 changed files with 33 additions and 392 deletions

View File

@ -1187,13 +1187,6 @@ static int cb_ioautofd(void *user, void *data) {
return true;
}
static int cb_iovio(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->vio = node->i_value;
return true;
}
static int cb_pager(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
@ -2284,7 +2277,6 @@ R_API int r_core_config_init(RCore *core) {
SETCB("io.va", "true", &cb_iova, "Use virtual address layout");
SETCB("io.pava", "false", &cb_iopava, "Use EXPERIMENTAL paddr -> vaddr address mode");
SETCB("io.autofd", "true", &cb_ioautofd, "Change fd when opening a new file");
SETCB("io.vio", "false", &cb_iovio, "Enable the new vio (reading only) (WIP)");
/* file */
SETPREF("file.desc", "", "User defined file description (used by projects)");

View File

@ -29,7 +29,6 @@ struct search_parameters {
bool crypto_search;
bool bckwrds;
bool do_bckwrd_srch;
bool use_mread;
bool aes_search;
bool rsa_search;
};
@ -1924,14 +1923,9 @@ static void do_string_search(RCore *core, struct search_parameters *param) {
if ((at + bufsz) > param->to) {
bufsz = param->to - at;
}
if (param->use_mread) {
// what about a config var to choose which io api to use?
ret = r_io_mread (core->io, fd, at, buf, bufsz);
} else {
// if seek fails we shouldnt read at all
(void) r_io_seek (core->io, at, R_IO_SEEK_SET);
ret = r_io_read (core->io, buf, bufsz);
}
// if seek fails we shouldnt read at all
(void) r_io_seek (core->io, at, R_IO_SEEK_SET);
ret = r_io_read (core->io, buf, bufsz);
if (ret < 1) {
break;
}
@ -2228,7 +2222,6 @@ static int cmd_search(void *data, const char *input) {
param.do_bckwrd_srch = false;
param.aes_search = false;
param.rsa_search = false;
param.use_mread = false;
param.do_bckwrd_srch = false;
c = 0;
@ -2243,7 +2236,6 @@ static int cmd_search(void *data, const char *input) {
param.mode = r_config_get (core->config, "search.in");
param.boundaries = r_core_get_boundaries (core, param.mode,
&param.from, &param.to);
param.use_mread = (!strcmp (param.mode, "maps"))? 1: 0;
if (__from != UT64_MAX) {
param.from = __from;

View File

@ -950,11 +950,7 @@ static int cmd_write(void *data, const char *input) {
addr = core->offset;
}
ut8 *buf = calloc (1, sz);
if (space) {
(void)r_io_vread (core->io, addr, buf, sz);
} else {
(void)r_io_pread (core->io, addr, buf, 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;

View File

@ -124,7 +124,6 @@ typedef struct r_io_t {
int raised;
int va;
bool pava;
int vio; // remove that when vio replaces the old stuff
int sectonly;
char *referer;
char *redirect;
@ -318,16 +317,13 @@ R_API RIODesc *r_io_use_fd(RIO *io, int fd);
R_API int r_io_use_desc(RIO *io, RIODesc *fd);
R_API RBuffer *r_io_read_buf(RIO *io, ut64 addr, int len);
R_API int r_io_vread(RIO *io, ut64 vaddr, ut8 *buf, int len);
R_API int r_io_read_internal(RIO *io, ut8 *buf, int len);
R_API int r_io_mread(RIO *io, int fd, ut64 maddr, ut8 *buf, int len);
R_API int r_io_pread(RIO *io, ut64 paddr, ut8 *buf, int len);
R_API int r_io_read(RIO *io, ut8 *buf, int len);
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len);
R_API ut64 r_io_read_i(RIO *io, ut64 addr, int sz);
R_API int r_io_write(RIO *io, const ut8 *buf, int len);
R_API int r_io_write_at(RIO *io, ut64 addr, const ut8 *buf, int len);
R_API int r_io_mwrite(RIO *io, int fd, ut64 maddr, ut8 *buf, int len);
R_API int r_io_pwrite(RIO *io, ut64 paddr, const ut8 *buf, int len);
R_API ut64 r_io_seek(RIO *io, ut64 offset, int whence);
R_API int r_io_system(RIO *io, const char *cmd);

View File

@ -7,8 +7,6 @@ STATIC_OBJS=$(subst ..,p/..,$(subst io_,p/io_,$(STATIC_OBJ)))
OBJS=${STATIC_OBJS}
OBJS+=io.o plugin.o map.o section.o desc.o cache.o undo.o buffer.o
OBJS+=vio.o
CFLAGS+=-Wall -DCORELIB
include ../socket/deps.mk

View File

@ -351,29 +351,24 @@ R_API int r_io_read(RIO *io, ut8 *buf, int len) {
return ret;
}
int r_io_read_cr (RIO *io, ut64 addr, ut8 *buf, int len) {
RList *maps;
RListIter *iter;
RIOMap *map;
if (!io)
R_API int r_io_pread (RIO *io, ut64 paddr, ut8 *buf, int len) {
if (!io || !buf) {
return R_FAIL;
if (io->ff)
memset (buf, io->Oxff, len);
if (io->va) {
r_io_vread (io, addr, buf, len); //must check return-stat
if (io->cached)
r_io_cache_read (io, addr, buf, len);
return len;
}
maps = r_io_map_get_maps_in_range (io, addr, addr + len);
r_list_foreach (maps, iter, map) {
r_io_mread (io, map->fd, addr, buf, len); //must check return-stat
if (paddr == UT64_MAX) {
if (io->ff) {
memset (buf, 0xff, len);
return len;
}
return R_FAIL;
}
r_io_mread (io, io->desc->fd, addr, buf, len); //must check return-stat
if (io->cached)
r_io_cache_read (io, addr, buf, len);
r_list_free (maps);
return len;
if (io->buffer_enabled) {
return r_io_buffer_read (io, paddr, buf, len);
} else if (!io->desc || !io->desc->plugin || !io->desc->plugin->read) {
return 0;
}
r_io_seek (io, paddr, R_IO_SEEK_SET);
return io->desc->plugin->read (io, io->desc, buf, len);
}
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
@ -383,9 +378,6 @@ R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
if (!io || !buf || len < 0) {
return 0;
}
if (io->vio) {
return r_io_read_cr (io, addr, buf, len);
}
if (io->sectonly && !r_list_empty (io->sections)) {
if (!r_io_section_exists_for_vaddr (io, addr, 0)) {
// find next sec
@ -773,6 +765,20 @@ cleanup:
return ret;
}
R_API int r_io_pwrite (RIO *io, ut64 paddr, const ut8 *buf, int len) {
if (!io || !buf) {
return R_FAIL;
}
if (paddr == UT64_MAX) {
return R_FAIL;
}
if (!io->desc || !io->desc->plugin || !io->desc->plugin->write) {
return 0;
}
r_io_seek (io, paddr, R_IO_SEEK_SET);
return io->desc->plugin->write (io, io->desc, buf, len);
}
R_API int r_io_write_at(RIO *io, ut64 addr, const ut8 *buf, int len) {
if (io->cached) {
return r_io_cache_write (io, addr, buf, len);

View File

@ -1,339 +0,0 @@
/* radare - LGPL - Copyright 2014-2016 - pancake, condret */
#include <r_io.h>
#define VIO_DEBUG 0
/*
| io.va | | io.ff |
.------------------.
| |
| VADDR ---> MADDR | ---> PADDR ---> PLUGINS
| | maddr->paddr+fd
`------------------'
virtual addresses are used when io.va is enabled
and it checks for sections in order to find an address
inside a mapped range.
If a virtual address is not found in any section,
then it looks into the map addresses.
mapped addresses are used to map an RIODesc at a
specific physical address. A file can be opened, but
not mapped, in this case it will not be visible.
cache: where should it
undo api: works at vaddr level too
TODO:
- How to share data pointers?
- Load RBuffer as file?
maddr -> vaddr
it is possible to get a list of virtual addresses that
point to a given physical address from a virtual one.
*/
/* Virtual Addressing API */
#define isInMapRange(m,x) ((m->from <= x) && (x <= m->to))
/* Idea: At first, get all sections in vrange, meanwhile record all unsectioned area and store it via RIORange in a list,
read all sections via mread, resolve maps for unsectioned areas and fill the gaps. last point must always prefere using io->desc*/
R_API int r_io_vread (RIO *io, ut64 vaddr, ut8 *buf, int len) {
int tmp_len = len;
ut8 *tmp_buf = buf;
ut64 vendaddr, maddr, tmp_vaddr = vaddr;
RIOMap *map;
RIOSection *section;
RIORange *range;
RList *sections, *ranges = NULL, *maps;
RListIter *iter, *ator;
if (!io->desc) {
eprintf ("r_io_vread: desc is NULL, WTF!\n");
return R_ERROR;
}
if (len < 0) {
eprintf ("r_io_vread: wrong usage; len is smaller than 0. len: %i\n", len);
return R_FAIL;
}
sections = r_io_section_get_in_vaddr_range (io, vaddr, vaddr+len);
if (!r_list_empty (sections)) { //check if there is any section
ranges = r_list_newf (free);
if (!ranges) {
r_list_free (sections);
return false;
}
r_list_foreach (sections, iter, section) {
if (!section->vaddr) continue;
if (section->vaddr > tmp_vaddr) {
range = r_io_range_new (); //create a new range
if (!range) {
r_list_free (ranges);
r_list_free (sections);
return false;
}
range->from = tmp_vaddr; //record unsectioned area
range->to = section->vaddr;
r_list_append (ranges, range); //store the range
tmp_vaddr = section->vaddr; //prepare for resolving the maddr
tmp_len -= (tmp_vaddr - vaddr);
tmp_buf += (tmp_vaddr - vaddr); //adjust buffer
}
vendaddr = tmp_vaddr + tmp_len; //calculate the virtual end address
if (vendaddr > (section->vaddr + section->vsize)) //check if the virtual end address is in the section too
vendaddr = section->vaddr + section->vsize; //if not, size it down
maddr = tmp_vaddr - section->vaddr + section->paddr; //calculate the map address (address inside the map)
if (maddr > (section->paddr + section->size)) { //check if the maddr is inside the physical section, if not, skip some things
} else {
if ((vendaddr - section->vaddr + section->paddr) > (section->paddr + section->size)) { //check if the virtual part of the section fits into the physical part
r_io_mread (io, section->fd, maddr, tmp_buf, (section->paddr + section->size) - maddr);//if not, read as far as possible
} else {
r_io_mread (io, section->fd, maddr, tmp_buf, vendaddr - tmp_vaddr); //read from the sections fd
}
}
tmp_buf += (vendaddr - tmp_vaddr); //adjust buffer
tmp_len -= (vendaddr - tmp_vaddr); //adjust length
tmp_vaddr = vendaddr; //adjust address
}
}
r_list_free (sections);
if (ranges) { //this is all might be too slow
r_list_foreach (ranges, iter, range) {
maps = r_io_map_get_maps_in_range (io, range->from, range->to - range->from); //get all maps in the range
tmp_vaddr = range->from;
tmp_len = range->to - range->from; //adjust length
tmp_buf = buf + (tmp_vaddr - vaddr); //adjust pointer
r_list_foreach (maps, ator, map) { //start filling the gaps
r_io_mread (io, map->fd, tmp_vaddr, tmp_buf, tmp_len); //read from maps, the ranges will adjusted in mread
}
r_list_free (maps); //free the list for the next iteration
r_io_mread (io, io->desc->fd, tmp_vaddr, tmp_buf, tmp_len); //ensure that io->desc is always on the top
}
r_list_free (ranges);
} else {
maps = r_io_map_get_maps_in_range (io, vaddr, vaddr + len); //get all maps
r_list_foreach (maps, iter, map) {
r_io_mread (io, map->fd, vaddr, buf, len); //read from the maps, the ranges will be adjusted in mread
}
r_list_free (maps); //free the list
r_io_mread (io, io->desc->fd, vaddr, buf, len); //ensure that io->desc is always on the top
}
return true;
}
/*you can throw any fd on this beast, it's important that len is equal or smaller than the size of buf*/
R_API int r_io_mread (RIO *io, int fd, ut64 maddr, ut8 *buf, int len) {
int read_bytes = len;
ut64 endaddr, paddr, d;
RIODesc *desc; //desc for tmp use
RIOMap *map; //map
if (len < 0) { //len must be bigger then -1
eprintf ("r_io_mread: wrong usage; len is smaller than 0. len: %i\n", len);
return R_FAIL;
}
if ((UT64_MAX - len) < maddr) { //say no to integer-overflows
eprintf ("r_io_mread: sorry, but I won't let you overflow this ut64\n");
read_bytes = UT64_MAX - maddr; //shrink len/read_bytes
}
endaddr = maddr + read_bytes; //get endaddr
map = r_io_map_resolve_in_range (io, maddr, endaddr, fd); //resolve map for fd in range
if (!map)
map = r_io_map_resolve (io, fd); //try to resolve map if it is not in range
if (!map) { //check if map exists
eprintf ("r_io_mread: cannot resolve map for fd %i\n", fd);
return R_ERROR;
}
if (endaddr > map->to) { //check if endaddr is in the map
if (maddr > map->to) //check segfault
return R_FAIL;
endaddr = map->to; //adjust endaddr
read_bytes = endaddr - maddr; //adjust read_bytes
}
if (maddr < map->from) { //adjusting things here will make vread very easy, because you can just get a list of fds in the range and the throw every fd on this function
if (endaddr < map->from) //check segfaults
return R_FAIL;
d = map->from - maddr; //get difference between maddr and start of the map
if (read_bytes < d) //check if adjusting would cause segfaults
return R_FAIL;
buf += d; //adjust buf-ptr
read_bytes -= d; //this is dangerous and can overflow
maddr += d; //adjust maddr
}
paddr = maddr - map->from + map->delta; //resolve paddr
desc = io->desc; //save io->desc
io->desc = r_io_desc_get (io, fd); //resolve desc for fd
if (!io->desc) { //check if desc exists
eprintf ("r_io_mread: cannot get desc for fd %i\n", fd);
io->desc = desc; //restore io->desc
return R_ERROR;
}
read_bytes = r_io_pread (io, paddr, buf, read_bytes); //read
io->desc = desc; //restore io->desc
return read_bytes; //return bytes read
}
R_API int r_io_pread (RIO *io, ut64 paddr, ut8 *buf, int len) {
int bytes_read = 0;
#if VIO_DEBUG
char *read_from = NULL;
#endif
if (!io) {
#if VIO_DEBUG //show debug-info
eprintf ("r_io_pread: io is NULL\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", paddr, len);
r_sys_backtrace();
#endif
return 0;
}
if (paddr == UT64_MAX) {
if (io->ff) {
memset (buf, 0xff, len);
return len;
}
return R_FAIL;
}
(void) r_io_seek (io, paddr, R_IO_SEEK_SET);
if (io->buffer_enabled){
#if VIO_DEBUG
read_from = "buffer";
#endif
bytes_read = r_io_buffer_read (io, io->off, buf, len);
} else {
if (io->desc && io->desc->plugin && io->desc->plugin->read){
#if VIO_DEBUG
read_from = io->desc->plugin->name;
#endif
bytes_read = io->desc->plugin->read (io, io->desc, buf, len);
} else if (!io->desc) {
#if VIO_DEBUG
eprintf ("r_io_pread: io->desc is NULL\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", paddr, len);
r_sys_backtrace();
#endif
return 0;
} else {
#if VIO_DEBUG
read_from = "File";
#endif
bytes_read = read (io->desc->fd, buf, len);
}
if (bytes_read<0) {
#if VIO_DEBUG
eprintf ("r_io_pread: bytes_read %i\n"
"from: %s\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", bytes_read, read_from, paddr, len);
r_sys_backtrace();
#endif
}
}
return bytes_read;
}
// This is not so good commented, because it's mostly copy-pasta from mread
R_API int r_io_mwrite (RIO *io, int fd, ut64 maddr, ut8 *buf, int len) {
int write_bytes = len;
ut64 endaddr, paddr, d;
RIODesc *desc; //desc for tmp use
RIOMap *map; //map
if (len<0) {
eprintf ("r_io_mwrite: wrong usage; len is smaller than 0, len: %i\n", len);
return R_FAIL;
}
if ((UT64_MAX - len) < maddr) { //no overflows please
eprintf ("r_io_mwrite: no, you cannot overflow this ut64\n");
write_bytes = UT64_MAX - maddr;
}
endaddr = maddr + write_bytes;
map = r_io_map_resolve_in_range (io, maddr, endaddr, fd);
if (!map)
map = r_io_map_resolve (io, fd);
if (!map) {
eprintf ("r_io_mwrite: cannot resolve map for fd%i\n", fd);
return R_ERROR;
}
if (endaddr > map->to) {
if (maddr > map->to)
return R_FAIL;
endaddr = map->to;
write_bytes = endaddr - maddr;
}
if (maddr < map->from) {
if (endaddr < map->from)
return R_FAIL;
d = map->from - maddr;
if (write_bytes < d)
return R_FAIL;
buf += d;
write_bytes -= d;
maddr += d;
}
if (!(map->flags & R_IO_WRITE)) //check if the map allows writing
return write_bytes;
paddr = maddr - map->from + map->delta;
desc = io->desc;
io->desc = r_io_desc_get (io, fd);
if (!io->desc) {
eprintf ("r_io_mwrite: cannot get desc for fd %i\n", fd);
io->desc = desc;
return R_ERROR;
}
write_bytes = r_io_pwrite (io, paddr, buf, write_bytes);
io->desc = desc;
return write_bytes;
}
R_API int r_io_pwrite (RIO *io, ut64 paddr, const ut8 *buf, int len)
{
int bytes_written = 0;
#if VIO_DEBUG
char *written_to = NULL;
#endif
if (!io) {
#if VIO_DEBUG
eprintf ("r_io_pwrite: io is NULL\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", paddr, len);
r_sys_backtrace();
#endif
return 0;
}
if ((UT64_MAX - len) < paddr) //prevent overflows
len = UT64_MAX - paddr;
(void) r_io_seek (io, paddr, R_IO_SEEK_SET);
if (io->desc && io->desc->plugin && io->desc->plugin->write) {
#if VIO_DEBUG
written_to = io->desc->plugin->name;
#endif
bytes_written = io->desc->plugin->write (io, io->desc, buf, len);
} else if (!io->desc) {
#if VIO_DEBUG //show debug-info
eprintf ("r_io_pwrite: io->desc is NULL\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", paddr, len);
r_sys_backtrace();
#endif
return 0;
} else {
#if VIO_DEBUG
written_to = "File";
#endif
bytes_written = write (io->desc->fd, buf, len);
}
if (bytes_written < 0) {
#if VIO_DEBUG
eprintf ("r_io_pwrite: bytes_written: %i\n"
"to: %s\n"
"paddr: 0x%016"PFMT64x"\n"
"len: 0x%x\n", bytes_written, written_to, paddr, len);
r_sys_backtrace();
#endif
}
return bytes_written;
}