Kill RIOSection ##refactor

This commit is contained in:
Riccardo Schirone 2019-01-31 17:53:34 +01:00 committed by radare
parent dafbf2df35
commit a88c7e1e3b
16 changed files with 169 additions and 423 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 ("]");

View File

@ -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;

View File

@ -233,7 +233,6 @@ typedef struct r_core_t {
RDebug *dbg;
RFlag *flags;
RSearch *search;
RIOSection *section;
RFS *fs;
REgg *egg;
RCoreLog *log;

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -6,7 +6,6 @@ r_io_sources = [
'ioutils.c',
'map.c',
'plugin.c',
'section.c',
'undo.c',
'p_cache.c',
'p/io_ar.c',

View File

@ -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;
}