mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-04 19:47:31 +00:00
Kill RIOSection ##refactor
This commit is contained in:
parent
dafbf2df35
commit
a88c7e1e3b
@ -796,7 +796,6 @@ R_API RList *r_bin_get_sections(RBin *bin) {
|
||||
return o ? o->sections : NULL;
|
||||
}
|
||||
|
||||
// TODO: Move into section.c and rename it to r_io_section_get_at ()
|
||||
R_API RBinSection *r_bin_get_section_at(RBinObject *o, ut64 off, int va) {
|
||||
RBinSection *section;
|
||||
RListIter *iter;
|
||||
|
@ -3360,7 +3360,6 @@ static struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0, j = 0; i < bin->num_sections; i++) {
|
||||
//if sz = 0 r_io_section_add will not add it so just skeep
|
||||
if (!shdr[i].SizeOfRawData && !shdr[i].Misc.VirtualSize) {
|
||||
continue;
|
||||
}
|
||||
|
@ -847,14 +847,14 @@ static RList* patch_relocs(RBin *b) {
|
||||
RIO *io = NULL;
|
||||
RBinObject *obj = NULL;
|
||||
struct Elf_(r_bin_elf_obj_t) *bin = NULL;
|
||||
RIOSection *g = NULL, *s = NULL;
|
||||
RIOMap *g = NULL, *s = NULL;
|
||||
HtUU *relocs_by_sym;
|
||||
SdbListIter *iter;
|
||||
RBinElfReloc *relcs = NULL;
|
||||
RBinInfo *info;
|
||||
int cdsz;
|
||||
int i;
|
||||
ut64 n_off, n_vaddr, vaddr, size, offset = 0;
|
||||
ut64 n_vaddr, vaddr, size, offset = 0;
|
||||
|
||||
if (!b)
|
||||
return NULL;
|
||||
@ -877,22 +877,31 @@ static RList* patch_relocs(RBin *b) {
|
||||
info = obj ? obj->info: NULL;
|
||||
cdsz = info? (info->bits == 64? 8: info->bits == 32? 4: info->bits == 16 ? 4: 0): 0;
|
||||
|
||||
ls_foreach (io->sections, iter, s) {
|
||||
if (s->paddr > offset) {
|
||||
offset = s->paddr;
|
||||
ls_foreach (io->maps, iter, s) {
|
||||
if (s->itv.addr > offset) {
|
||||
offset = s->itv.addr;
|
||||
g = s;
|
||||
}
|
||||
}
|
||||
if (!g) {
|
||||
return NULL;
|
||||
}
|
||||
n_off = g->paddr + g->size;
|
||||
n_vaddr = g->vaddr + g->vsize;
|
||||
n_vaddr = g->itv.addr + g->itv.size;
|
||||
//reserve at least that space
|
||||
size = bin->reloc_num * 4;
|
||||
if (!b->iob.section_add (io, n_off, n_vaddr, size, size, R_PERM_R, ".got.r2", 0, io->desc->fd)) {
|
||||
char *muri = r_str_newf ("malloc://%" PFMT64u, size);
|
||||
RIODesc *gotr2desc = b->iob.open_at (io, muri, R_PERM_R, 0664, n_vaddr);
|
||||
free (muri);
|
||||
if (!gotr2desc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RIOMap *gotr2map = b->iob.map_get (io, n_vaddr);
|
||||
if (!gotr2map) {
|
||||
return NULL;
|
||||
}
|
||||
gotr2map->name = strdup (".got.r2");
|
||||
|
||||
if (!(relcs = Elf_(r_bin_elf_get_relocs) (bin))) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -232,21 +232,21 @@ R_API ut64 r_core_anal_address(RCore *core, ut64 addr) {
|
||||
}
|
||||
} else {
|
||||
int _perm = -1;
|
||||
RBinSection *s;
|
||||
RIOMap *s;
|
||||
SdbListIter *iter;
|
||||
if (core->io) {
|
||||
// sections
|
||||
ls_foreach (core->io->sections, iter, s) {
|
||||
if (addr >= s->vaddr && addr < (s->vaddr + s->vsize)) {
|
||||
ls_foreach (core->io->maps, iter, s) {
|
||||
if (addr >= s->itv.addr && addr < (s->itv.addr + s->itv.size)) {
|
||||
// sections overlap, so we want to get the one with lower perms
|
||||
_perm = (_perm != -1) ? R_MIN (_perm, s->perm) : s->perm;
|
||||
// TODO: we should identify which maps come from the program or other
|
||||
//types |= R_ANAL_ADDR_TYPE_PROGRAM;
|
||||
// find function those sections should be created by hand or esil init
|
||||
if (strstr (s->name, "heap")) {
|
||||
if (s->name && strstr (s->name, "heap")) {
|
||||
types |= R_ANAL_ADDR_TYPE_HEAP;
|
||||
}
|
||||
if (strstr (s->name, "stack")) {
|
||||
if (s->name && strstr (s->name, "stack")) {
|
||||
types |= R_ANAL_ADDR_TYPE_STACK;
|
||||
}
|
||||
}
|
||||
|
151
libr/core/cbin.c
151
libr/core/cbin.c
@ -2271,6 +2271,111 @@ static void list_section_visual(RIO *io, RList *sections, ut64 seek, ut64 len, i
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *uri;
|
||||
int perm;
|
||||
RIODesc *desc;
|
||||
} FindFile;
|
||||
|
||||
static bool findFile(void *user, void *data, ut32 id) {
|
||||
FindFile *res = (FindFile*)user;
|
||||
RIODesc *desc = (RIODesc*)data;
|
||||
if (desc->perm && res->perm && !strcmp (desc->uri, res->uri)) {
|
||||
res->desc = desc;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static RIODesc *findReusableFile(RIO *io, const char *uri, int perm) {
|
||||
FindFile arg = {
|
||||
.uri = uri,
|
||||
.perm = perm,
|
||||
.desc = NULL,
|
||||
};
|
||||
r_id_storage_foreach (io->files, findFile, &arg);
|
||||
return arg.desc;
|
||||
}
|
||||
|
||||
static bool io_create_mem_map(RIO *io, RBinSection *sec, ut64 at) {
|
||||
r_return_val_if_fail (io && sec, false);
|
||||
|
||||
bool reused = false;
|
||||
ut64 gap = sec->vsize - sec->size;
|
||||
char *uri = r_str_newf ("null://%"PFMT64u, gap);
|
||||
RIODesc *desc = findReusableFile (io, uri, sec->perm);
|
||||
if (desc) {
|
||||
RIOMap *map = r_io_map_get (io, at);
|
||||
if (!map) {
|
||||
r_io_map_add_batch (io, desc->fd, desc->perm, 0LL, at, gap);
|
||||
}
|
||||
reused = true;
|
||||
}
|
||||
if (!desc) {
|
||||
desc = r_io_open_at (io, uri, sec->perm, 0664, at);
|
||||
}
|
||||
free (uri);
|
||||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
// this works, because new maps are always born on the top
|
||||
RIOMap *map = r_io_map_get (io, at);
|
||||
// check if the mapping failed
|
||||
if (!map) {
|
||||
if (!reused) {
|
||||
r_io_desc_close (desc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// let the section refere to the map as a memory-map
|
||||
map->name = r_str_newf ("mmap.%s", sec->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void add_section(RCore *core, RBinSection *sec, ut64 addr, int fd) {
|
||||
if (!r_io_desc_get (core->io, fd) || UT64_ADD_OVFCHK (sec->size, sec->paddr) ||
|
||||
UT64_ADD_OVFCHK (sec->size, addr) || !sec->vsize) {
|
||||
return;
|
||||
}
|
||||
|
||||
ut64 size = sec->vsize;
|
||||
// if there is some part of the section that needs to be zeroed by the loader
|
||||
// we add a null map that takes care of it
|
||||
if (sec->vsize > sec->size) {
|
||||
if (!io_create_mem_map (core->io, sec, addr + sec->size)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size = sec->size;
|
||||
}
|
||||
|
||||
// then we map the part of the section that comes from the physical file
|
||||
char *map_name = r_str_newf ("fmap.%s", sec->name);
|
||||
if (!map_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
int perm = sec->perm;
|
||||
// workaround to force exec bit in text section
|
||||
if (sec->name && strstr (sec->name, "text")) {
|
||||
perm |= R_PERM_X;
|
||||
}
|
||||
|
||||
RIOMap *map = r_io_map_add_batch (core->io, fd, perm, sec->paddr, addr, size);
|
||||
if (!map) {
|
||||
free (map_name);
|
||||
return;
|
||||
}
|
||||
map->name = map_name;
|
||||
return;
|
||||
}
|
||||
|
||||
struct io_bin_section_info_t {
|
||||
RBinSection *sec;
|
||||
ut64 addr;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const char *name, const char *chksum, bool print_segments) {
|
||||
char *str = NULL;
|
||||
RBinSection *section;
|
||||
@ -2289,6 +2394,7 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
|
||||
bool ret = false;
|
||||
const char *type = print_segments ? "segment" : "section";
|
||||
bool segments_only = true;
|
||||
RList *io_section_info = NULL;
|
||||
|
||||
if (!dup_chk_ht) {
|
||||
return false;
|
||||
@ -2325,6 +2431,8 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
io_section_info = r_list_newf ((RListFree)free);
|
||||
}
|
||||
r_list_foreach (sections, iter, section) {
|
||||
char perms[] = "----";
|
||||
@ -2434,10 +2542,20 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
|
||||
section->paddr, addr, section->size, section->vsize, section->perm, section->name, r->bin->cur->id, fd);
|
||||
ht_pp_find (dup_chk_ht, str, &found);
|
||||
if (!found) {
|
||||
r_io_section_add (r->io, section->paddr, addr,
|
||||
section->size, section->vsize,
|
||||
section->perm, section->name,
|
||||
r->bin->cur->id, fd);
|
||||
// can't directly add maps because they
|
||||
// need to be reversed, otherwise for
|
||||
// the way IO works maps would be shown
|
||||
// in reverse order
|
||||
struct io_bin_section_info_t *ibs = R_NEW (struct io_bin_section_info_t);
|
||||
if (!ibs) {
|
||||
eprintf ("Could not allocate memory\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ibs->sec = section;
|
||||
ibs->addr = addr;
|
||||
ibs->fd = fd;
|
||||
r_list_append (io_section_info, ibs);
|
||||
ht_pp_insert (dup_chk_ht, str, NULL);
|
||||
}
|
||||
R_FREE (str);
|
||||
@ -2513,25 +2631,11 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
|
||||
str[0] = 0;
|
||||
}
|
||||
if (r->bin->prefix) {
|
||||
#if 0
|
||||
r_cons_printf ("idx=%02i vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
|
||||
"perm=%s %s%sname=%s.%s\n",
|
||||
i, addr, section->paddr, section->size, section->vsize,
|
||||
perms, str, hashstr ?hashstr : "", r->bin->prefix, section->name);
|
||||
#endif
|
||||
// r_cons_printf ("%02i 0x%08"PFMT64x" %10"PFMT64d" 0x%08"PFMT64x" %10"PFMT64d" "
|
||||
r_cons_printf ("%02i 0x%08"PFMT64x" %5"PFMT64d" 0x%08"PFMT64x" %5"PFMT64d" "
|
||||
"%s %s%s%s.%s\n",
|
||||
i, section->paddr, section->size, addr, section->vsize,
|
||||
perms, str, hashstr ?hashstr : "", r->bin->prefix, section->name);
|
||||
} else {
|
||||
#if 0
|
||||
r_cons_printf ("idx=%02i vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
|
||||
"perm=%s %s%sname=%s\n",
|
||||
i, addr, section->paddr, section->size, section->vsize,
|
||||
perms, str, hashstr ?hashstr : "", section->name);
|
||||
#endif
|
||||
// r_cons_printf ("%02i 0x%08"PFMT64x" %10"PFMT64d" 0x%08"PFMT64x" %10"PFMT64d" "
|
||||
r_cons_printf ("%02i 0x%08"PFMT64x" %5"PFMT64d" 0x%08"PFMT64x" %5"PFMT64d" "
|
||||
"%s %s%s%s\n",
|
||||
i, section->paddr, (ut64)section->size, addr, (ut64)section->vsize,
|
||||
@ -2545,8 +2649,15 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r->bin && r->bin->cur && r->io && !r_io_desc_is_dbg (r->io->desc)) {
|
||||
r_io_section_apply_bin (r->io, r->bin->cur->id, R_IO_SECTION_APPLY_FOR_ANALYSIS);
|
||||
if (IS_MODE_SET (mode) && !r_io_desc_is_dbg (r->io->desc)) {
|
||||
RListIter *it;
|
||||
struct io_bin_section_info_t *ibs;
|
||||
r_list_foreach_prev (io_section_info, it, ibs) {
|
||||
add_section (r, ibs->sec, ibs->addr, ibs->fd);
|
||||
}
|
||||
r_io_update (r->io);
|
||||
r_list_free (io_section_info);
|
||||
io_section_info = NULL;
|
||||
}
|
||||
if (IS_MODE_JSON (mode) && !printHere) {
|
||||
r_cons_println ("]");
|
||||
|
@ -2342,7 +2342,6 @@ R_API bool r_core_init(RCore *core) {
|
||||
core->log = r_core_log_new ();
|
||||
core->times = R_NEW0 (RCoreTimes);
|
||||
core->vmode = false;
|
||||
core->section = NULL;
|
||||
core->oobi = NULL;
|
||||
core->oobi_len = 0;
|
||||
core->printidx = 0;
|
||||
|
@ -233,7 +233,6 @@ typedef struct r_core_t {
|
||||
RDebug *dbg;
|
||||
RFlag *flags;
|
||||
RSearch *search;
|
||||
RIOSection *section;
|
||||
RFS *fs;
|
||||
REgg *egg;
|
||||
RCoreLog *log;
|
||||
|
@ -90,12 +90,10 @@ typedef struct r_io_t {
|
||||
int p_cache;
|
||||
int debug;
|
||||
//#warning remove debug from RIO
|
||||
RIDPool *sec_ids;
|
||||
RIDPool *map_ids;
|
||||
SdbList *maps; //from tail backwards maps with higher priority are found
|
||||
RPVector map_skyline; // map parts that are not covered by others
|
||||
RPVector map_skyline_shadow; // map parts that are not covered by others
|
||||
SdbList *sections;
|
||||
RIDStorage *files;
|
||||
RCache *buffer;
|
||||
RList *cache; //sdblist?
|
||||
@ -198,29 +196,6 @@ typedef struct r_io_map_skyline_t {
|
||||
RInterval itv;
|
||||
} RIOMapSkyline;
|
||||
|
||||
// XXX must be deprecated maps should be enough
|
||||
typedef struct r_io_section_t {
|
||||
char *name;
|
||||
ut64 paddr;
|
||||
ut64 size;
|
||||
ut64 vaddr;
|
||||
ut64 vsize;
|
||||
int perm;
|
||||
ut32 id;
|
||||
ut32 bin_id;
|
||||
int arch;
|
||||
int bits;
|
||||
int fd;
|
||||
ut32 filemap;
|
||||
ut32 memmap;
|
||||
} RIOSection;
|
||||
|
||||
typedef enum {
|
||||
R_IO_SECTION_APPLY_FOR_PATCH,
|
||||
R_IO_SECTION_APPLY_FOR_ANALYSIS,
|
||||
R_IO_SECTION_APPLY_FOR_EMULATOR
|
||||
} RIOSectionApplyMethod;
|
||||
|
||||
typedef struct r_io_cache_t {
|
||||
RInterval itv;
|
||||
ut8 *data;
|
||||
@ -260,9 +235,7 @@ typedef bool (*RIOFdRemap) (RIO *io, int fd, ut64 addr);
|
||||
typedef bool (*RIOIsValidOff) (RIO *io, ut64 addr, int hasperm);
|
||||
typedef RIOMap *(*RIOMapGet) (RIO *io, ut64 addr);
|
||||
typedef bool (*RIOAddrIsMapped) (RIO *io, ut64 addr);
|
||||
typedef SdbList *(*RIOSectionVgetSecsAt) (RIO *io, ut64 vaddr);
|
||||
//typedef RIOSection *(*RIOSectionVgetSec) (RIO *io, ut64 vaddr);
|
||||
typedef RIOSection *(*RIOSectionAdd) (RIO *io, ut64 addr, ut64 vaddr, ut64 size, ut64 vsize, int rwx, const char *name, ut32 bin_id, int fd);
|
||||
typedef RIOMap *(*RIOMapAdd) (RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
|
||||
#if HAVE_PTRACE
|
||||
typedef long (*RIOPtraceFn) (RIO *io, r_ptrace_request_t request, pid_t pid, void *addr, r_ptrace_data_t data);
|
||||
typedef void *(*RIOPtraceFuncFn) (RIO *io, void *(*func)(void *), void *user);
|
||||
@ -295,9 +268,7 @@ typedef struct r_io_bind_t {
|
||||
RIOIsValidOff is_valid_offset;
|
||||
RIOAddrIsMapped addr_is_mapped;
|
||||
RIOMapGet map_get;
|
||||
//RIOSectionVgetSecsAt sections_vget;
|
||||
//RIOSectionVgetSec sect_vget;
|
||||
RIOSectionAdd section_add;
|
||||
RIOMapAdd map_add;
|
||||
#if HAVE_PTRACE
|
||||
RIOPtraceFn ptrace;
|
||||
RIOPtraceFuncFn ptrace_func;
|
||||
@ -314,7 +285,11 @@ R_API bool r_io_map_exists (RIO *io, RIOMap *map);
|
||||
R_API bool r_io_map_exists_for_id (RIO *io, ut32 id);
|
||||
R_API RIOMap *r_io_map_resolve (RIO *io, ut32 id);
|
||||
R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
|
||||
// same as r_io_map_add but used when many maps need to be added. Call r_io_update when all maps have been added.
|
||||
R_API RIOMap *r_io_map_add_batch(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
|
||||
R_API RIOMap *r_io_map_get(RIO *io, ut64 addr); //returns the map at vaddr with the highest priority
|
||||
// update the internal state of RIO after a series of _batch operations
|
||||
R_API void r_io_update(RIO *io);
|
||||
R_API bool r_io_map_is_mapped(RIO* io, ut64 addr);
|
||||
R_API RIOMap *r_io_map_get_paddr(RIO *io, ut64 paddr); //returns the map at paddr with the highest priority
|
||||
R_API void r_io_map_reset(RIO* io);
|
||||
@ -440,23 +415,6 @@ R_API void r_io_cache_reset(RIO *io, int set);
|
||||
R_API bool r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API bool r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
|
||||
/* io/section.c */
|
||||
R_API void r_io_section_init (RIO *io);
|
||||
R_API void r_io_section_fini (RIO *io);
|
||||
R_API RIOSection *r_io_section_add (RIO *io, ut64 addr, ut64 vaddr, ut64 size, ut64 vsize, int rwx, const char *name, ut32 bin_id, int fd);
|
||||
R_API RIOSection *r_io_section_get_i (RIO *io, ut32 id);
|
||||
R_API SdbList *r_io_section_bin_get (RIO *io, ut32 bin_id);
|
||||
R_API void r_io_section_cleanup (RIO *io);
|
||||
R_API SdbList *r_io_sections_get (RIO *io, ut64 addr);
|
||||
R_API SdbList *r_io_sections_vget (RIO *io, ut64 vaddr);
|
||||
R_API const char *r_io_section_get_archbits (RIO *io, ut64 vaddr, int *bits);
|
||||
R_API bool r_io_section_priorize (RIO *io, ut32 id);
|
||||
R_API bool r_io_section_priorize_bin (RIO *io, ut32 bin_id);
|
||||
R_API bool r_io_section_apply (RIO *io, ut32 id, RIOSectionApplyMethod method);
|
||||
R_API bool r_io_section_apply_bin (RIO *io, ut32 bin_id, RIOSectionApplyMethod method);
|
||||
R_API RIOSection* r_io_section_get(RIO *io, ut64 paddr);
|
||||
R_API RIOSection* r_io_section_vget(RIO *io, ut64 vaddr);
|
||||
|
||||
/* io/p_cache.c */
|
||||
R_API bool r_io_desc_cache_init (RIODesc *desc);
|
||||
R_API int r_io_desc_cache_write (RIODesc *desc, ut64 paddr, const ut8 *buf, int len);
|
||||
|
@ -5,7 +5,7 @@ DEPS+=r_util
|
||||
DEPS+=r_socket
|
||||
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 p_cache.o undo.o ioutils.o fd.o
|
||||
OBJS+=io.o plugin.o map.o desc.o cache.o p_cache.o undo.o ioutils.o fd.o
|
||||
|
||||
CFLAGS+=-Wall -DCORELIB
|
||||
|
||||
|
@ -84,7 +84,6 @@ R_API bool r_io_desc_del(RIO* io, int fd) { //can we pass this a riodesc and ch
|
||||
}
|
||||
// remove all dead maps
|
||||
r_io_map_cleanup (io);
|
||||
r_io_section_cleanup (io);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -160,7 +159,6 @@ R_API bool r_io_desc_close(RIODesc *desc) {
|
||||
r_io_desc_del (io, desc->fd);
|
||||
// remove all dead maps
|
||||
r_io_map_cleanup (io);
|
||||
r_io_section_cleanup (io);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,6 @@ R_API RIO* r_io_init(RIO* io) {
|
||||
r_pvector_init (&io->map_skyline, free);
|
||||
r_pvector_init (&io->map_skyline_shadow, free);
|
||||
r_io_map_init (io);
|
||||
r_io_section_init (io);
|
||||
r_io_cache_init (io);
|
||||
r_io_plugin_init (io);
|
||||
r_io_undo_init (io);
|
||||
@ -259,11 +258,9 @@ R_API int r_io_close_all(RIO* io) { // what about undo?
|
||||
}
|
||||
r_io_desc_fini (io);
|
||||
r_io_map_fini (io);
|
||||
r_io_section_fini (io);
|
||||
ls_free (io->plugins);
|
||||
r_io_desc_init (io);
|
||||
r_io_map_init (io);
|
||||
r_io_section_init (io);
|
||||
r_io_cache_fini (io);
|
||||
r_io_plugin_init (io);
|
||||
return true;
|
||||
@ -525,7 +522,7 @@ R_API void r_io_bind(RIO *io, RIOBind *bnd) {
|
||||
bnd->is_valid_offset = r_io_is_valid_offset;
|
||||
bnd->map_get = r_io_map_get;
|
||||
bnd->addr_is_mapped = r_io_addr_is_mapped;
|
||||
bnd->section_add = r_io_section_add;
|
||||
bnd->map_add = r_io_map_add;
|
||||
#if HAVE_PTRACE
|
||||
bnd->ptrace = r_io_ptrace;
|
||||
bnd->ptrace_func = r_io_ptrace_func;
|
||||
@ -659,7 +656,6 @@ R_API int r_io_fini(RIO* io) {
|
||||
r_io_desc_cache_fini_all (io);
|
||||
r_io_desc_fini (io);
|
||||
r_io_map_fini (io);
|
||||
r_io_section_fini (io);
|
||||
ls_free (io->plugins);
|
||||
r_list_free (io->cache);
|
||||
r_list_free (io->undo.w_list);
|
||||
|
@ -4,7 +4,5 @@
|
||||
RIOMap *io_map_new(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, bool do_skyline);
|
||||
RIOMap *io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, bool do_skyline);
|
||||
void io_map_calculate_skyline(RIO *io);
|
||||
bool io_create_mem_map(RIO *io, RIOSection *sec, ut64 at, bool null, bool do_skyline);
|
||||
bool io_create_file_map(RIO *io, RIOSection *sec, ut64 size, bool patch, bool do_skyline);
|
||||
|
||||
#endif
|
||||
|
@ -5,120 +5,6 @@
|
||||
#include <r_types.h>
|
||||
#include "io_private.h"
|
||||
|
||||
// TODO: we may probably take care of this when the binfiles have an associated list of fds
|
||||
#define REUSE_NULL_MAPS 1
|
||||
|
||||
typedef struct {
|
||||
const char *uri;
|
||||
int perm;
|
||||
RIODesc *desc;
|
||||
} FindFile;
|
||||
|
||||
#if REUSE_NULL_MAPS
|
||||
|
||||
static bool findFile(void *user, void *data, ut32 id) {
|
||||
FindFile *res = (FindFile*)user;
|
||||
RIODesc *desc = (RIODesc*)data;
|
||||
if (desc->perm && res->perm && !strcmp (desc->uri, res->uri)) {
|
||||
res->desc = desc;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static RIODesc *findReusableFile(RIO *io, const char *uri, int perm) {
|
||||
FindFile arg = {
|
||||
.uri = uri,
|
||||
.perm = perm,
|
||||
.desc = NULL,
|
||||
};
|
||||
r_id_storage_foreach (io->files, findFile, &arg);
|
||||
return arg.desc;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static RIODesc *findReusableFile(RIO *io, const char *uri, int perm) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool io_create_mem_map(RIO *io, RIOSection *sec, ut64 at, bool null, bool do_skyline) {
|
||||
RIODesc *desc = NULL;
|
||||
char *uri = NULL;
|
||||
bool reused = false;
|
||||
|
||||
if (!io || !sec) {
|
||||
return false;
|
||||
}
|
||||
ut64 gap = sec->vsize - sec->size;
|
||||
if (null) {
|
||||
uri = r_str_newf ("null://%"PFMT64u, gap);
|
||||
desc = findReusableFile (io, uri, sec->perm);
|
||||
if (desc) {
|
||||
RIOMap *map = r_io_map_get (io, at);
|
||||
if (!map) {
|
||||
io_map_new (io, desc->fd, desc->perm, 0LL, at, gap, false);
|
||||
}
|
||||
reused = true;
|
||||
}
|
||||
} else {
|
||||
uri = r_str_newf ("malloc://%"PFMT64u, gap);
|
||||
}
|
||||
if (!desc) {
|
||||
desc = r_io_open_at (io, uri, sec->perm, 0664, at);
|
||||
}
|
||||
free (uri);
|
||||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
if (do_skyline) {
|
||||
io_map_calculate_skyline (io);
|
||||
}
|
||||
// this works, because new maps are allways born on the top
|
||||
RIOMap *map = r_io_map_get (io, at);
|
||||
// check if the mapping failed
|
||||
if (!map) {
|
||||
if (!reused) {
|
||||
r_io_desc_close (desc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// let the section refere to the map as a memory-map
|
||||
sec->memmap = map->id;
|
||||
map->name = r_str_newf ("mmap.%s", sec->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool io_create_file_map(RIO *io, RIOSection *sec, ut64 size, bool patch, bool do_skyline) {
|
||||
if (!io || !sec) {
|
||||
return false;
|
||||
}
|
||||
RIODesc *desc = r_io_desc_get (io, sec->fd);
|
||||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
int perm = sec->perm;
|
||||
//create file map for patching
|
||||
// workaround to force exec bit in text section
|
||||
if (sec->name && strstr (sec->name, "text")) {
|
||||
perm |= R_PERM_X;
|
||||
}
|
||||
if (patch) {
|
||||
//add -w to the map for patching if needed
|
||||
//if the file was not opened with -w desc->perm won't have that bit active
|
||||
perm = perm | desc->perm;
|
||||
}
|
||||
RIOMap *map = io_map_add (io, sec->fd, perm, sec->paddr, sec->vaddr, size, do_skyline);
|
||||
if (map) {
|
||||
sec->filemap = map->id;
|
||||
map->name = r_str_newf ("fmap.%s", sec->name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//This helper function only check if the given vaddr is mapped, it does not account
|
||||
//for map perms
|
||||
R_API bool r_io_addr_is_mapped(RIO *io, ut64 vaddr) {
|
||||
|
@ -319,6 +319,14 @@ R_API RIOMap *r_io_map_add(RIO *io, int fd, int perm, ut64 delta, ut64 addr, ut6
|
||||
return io_map_add (io, fd, perm, delta, addr, size, true);
|
||||
}
|
||||
|
||||
R_API RIOMap *r_io_map_add_batch(RIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size) {
|
||||
return io_map_add (io, fd, perm, delta, addr, size, false);
|
||||
}
|
||||
|
||||
R_API void r_io_update(RIO *io) {
|
||||
io_map_calculate_skyline (io);
|
||||
}
|
||||
|
||||
R_API RIOMap* r_io_map_get_paddr(RIO* io, ut64 paddr) {
|
||||
r_return_val_if_fail (io, NULL);
|
||||
RIOMap* map;
|
||||
|
@ -6,7 +6,6 @@ r_io_sources = [
|
||||
'ioutils.c',
|
||||
'map.c',
|
||||
'plugin.c',
|
||||
'section.c',
|
||||
'undo.c',
|
||||
'p_cache.c',
|
||||
'p/io_ar.c',
|
||||
|
@ -1,213 +0,0 @@
|
||||
/* radare2 - LGPL - Copyright 2017-2018 - condret , alvarofe */
|
||||
|
||||
#include <r_io.h>
|
||||
#include <r_util.h>
|
||||
#include <sdb.h>
|
||||
#include <r_types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "io_private.h"
|
||||
|
||||
static void section_free(void *p) {
|
||||
RIOSection *s = (RIOSection *) p;
|
||||
if (s) {
|
||||
free (s->name);
|
||||
free (s);
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_io_section_init(RIO *io) {
|
||||
if (io) {
|
||||
if (!io->sections) {
|
||||
io->sections = ls_newf (section_free);
|
||||
}
|
||||
if (!io->sec_ids) {
|
||||
io->sec_ids = r_id_pool_new (0, UT32_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_io_section_fini(RIO *io) {
|
||||
if (!io) {
|
||||
return;
|
||||
}
|
||||
ls_free (io->sections);
|
||||
r_id_pool_free (io->sec_ids);
|
||||
io->sections = NULL;
|
||||
io->sec_ids = NULL;
|
||||
}
|
||||
|
||||
R_API RIOSection *r_io_section_add(RIO *io, ut64 paddr, ut64 vaddr, ut64 size,
|
||||
ut64 vsize, int perm, const char *name,
|
||||
ut32 bin_id, int fd) {
|
||||
if (!io || !io->sections || !io->sec_ids || !r_io_desc_get (io, fd) ||
|
||||
UT64_ADD_OVFCHK (size, paddr) || UT64_ADD_OVFCHK (size, vaddr) || !vsize) {
|
||||
return NULL;
|
||||
}
|
||||
RIOSection *sec = R_NEW0 (RIOSection);
|
||||
if (sec) {
|
||||
sec->paddr = paddr;
|
||||
sec->vaddr = vaddr;
|
||||
sec->size = size;
|
||||
sec->vsize = vsize;
|
||||
sec->perm = perm;
|
||||
sec->bin_id = bin_id;
|
||||
sec->fd = fd;
|
||||
if (!name) {
|
||||
sec->name = r_str_newf ("section.0x016%"PFMT64x "", vaddr);
|
||||
} else {
|
||||
sec->name = strdup (name);
|
||||
}
|
||||
if (!sec->name) {
|
||||
free (sec);
|
||||
return NULL;
|
||||
}
|
||||
if (!r_id_pool_grab_id (io->sec_ids, &sec->id)) {
|
||||
free (sec->name);
|
||||
free (sec);
|
||||
return NULL;
|
||||
}
|
||||
ls_append (io->sections, sec);
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
R_API void r_io_section_cleanup(RIO *io) {
|
||||
if (!io || !io->sections || !io->sec_ids) {
|
||||
return;
|
||||
}
|
||||
if (!io->files) {
|
||||
r_io_section_fini (io);
|
||||
r_io_section_init (io);
|
||||
return;
|
||||
}
|
||||
RIOSection *s;
|
||||
SdbListIter *iter, *ator;
|
||||
ls_foreach_safe (io->sections, iter, ator, s) {
|
||||
if (!s) {
|
||||
ls_delete (io->sections, iter);
|
||||
} else if (!r_io_desc_get (io, s->fd)) {
|
||||
r_id_pool_kick_id (io->sec_ids, s->id);
|
||||
ls_delete (io->sections, iter);
|
||||
} else {
|
||||
if (!r_io_map_exists_for_id (io, s->filemap)) {
|
||||
s->filemap = 0;
|
||||
}
|
||||
if (!r_io_map_exists_for_id (io, s->memmap)) {
|
||||
s->memmap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool _section_apply_for_anal_patch(RIO *io, RIOSection *sec, bool patch) {
|
||||
if (sec->vsize > sec->size) {
|
||||
// in that case, we just have to allocate some memory of the size (vsize-size)
|
||||
if (!sec->memmap) {
|
||||
// offset,where the memory should be mapped to
|
||||
ut64 at = sec->vaddr + sec->size;
|
||||
// TODO: harden this, handle mapslit
|
||||
// craft the uri for the null-fd
|
||||
if (io_create_mem_map (io, sec, at, true, false)) {
|
||||
// we need to create this map for transfering the perm, no real remapping here
|
||||
if (io_create_file_map (io, sec, sec->size, patch, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// same as above
|
||||
if (!sec->filemap && io_create_file_map (io, sec, sec->vsize, patch, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _section_apply_for_emul(RIO *io, RIOSection *sec) {
|
||||
RIODesc *desc, *oldesc;
|
||||
RIOMap *map;
|
||||
char *uri;
|
||||
size_t size;
|
||||
ut8 *buf = NULL;
|
||||
// if the section doesn't allow writing, we don't need to initialize writeable memory
|
||||
if (!(sec->perm & R_PERM_W)) {
|
||||
return _section_apply_for_anal_patch (io, sec, R_IO_SECTION_APPLY_FOR_ANALYSIS);
|
||||
}
|
||||
if (sec->memmap) {
|
||||
return false;
|
||||
}
|
||||
size = (size_t) (sec->size > sec->vsize)? sec->vsize: sec->size;
|
||||
// allocate a buffer for copying from sec->fd to the malloc-map
|
||||
buf = calloc (1, size + 1);
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
// save the current desc
|
||||
oldesc = io->desc;
|
||||
// copy to the buffer
|
||||
r_io_use_fd (io, sec->fd);
|
||||
r_io_pread_at (io, sec->paddr, buf, (int)size);
|
||||
// craft the uri for the opening the malloc-fd
|
||||
uri = r_str_newf ("malloc://%"PFMT64u "", sec->vsize);
|
||||
// open the malloc-fd and map it to vaddr
|
||||
desc = r_io_open_at (io, uri, sec->perm, 664, sec->vaddr);
|
||||
if (!desc) {
|
||||
free (buf);
|
||||
return false;
|
||||
}
|
||||
io->desc = desc;
|
||||
// copy from buffer to the malloc-fd
|
||||
r_io_pwrite_at (io, 0LL, buf, (int) size);
|
||||
free (buf);
|
||||
// get the malloc-map
|
||||
if ((map = r_io_map_get (io, sec->vaddr))) {
|
||||
map->name = r_str_newf ("mmap.%s", sec->name);
|
||||
// set the perm correctly
|
||||
map->perm = sec->perm;
|
||||
// restore old RIODesc
|
||||
io->desc = oldesc;
|
||||
// let the section refere to the map
|
||||
sec->filemap = sec->memmap = map->id;
|
||||
return true;
|
||||
}
|
||||
io->desc = oldesc;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _section_apply(RIO *io, RIOSection *sec, RIOSectionApplyMethod method) {
|
||||
switch (method) {
|
||||
case R_IO_SECTION_APPLY_FOR_PATCH:
|
||||
case R_IO_SECTION_APPLY_FOR_ANALYSIS:
|
||||
return _section_apply_for_anal_patch (io, sec,
|
||||
method == R_IO_SECTION_APPLY_FOR_ANALYSIS? false : true);
|
||||
case R_IO_SECTION_APPLY_FOR_EMULATOR:
|
||||
return _section_apply_for_emul (io, sec);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
R_API bool r_io_section_apply(RIO *io, ut32 id, RIOSectionApplyMethod method) {
|
||||
RIOSection *sec = r_io_section_get_i (io, id);
|
||||
return sec ? _section_apply (io, sec, method): false;
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API bool r_io_section_apply_bin(RIO *io, ut32 bin_id, RIOSectionApplyMethod method) {
|
||||
RIOSection *sec;
|
||||
SdbListIter *iter;
|
||||
bool ret = false;
|
||||
if (!io || !io->sections) {
|
||||
return false;
|
||||
}
|
||||
ls_foreach_prev (io->sections, iter, sec) {
|
||||
if (sec && (sec->bin_id == bin_id)) {
|
||||
ret = true;
|
||||
_section_apply (io, sec, method);
|
||||
}
|
||||
}
|
||||
io_map_calculate_skyline (io);
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user