#ifndef R2_IO_H #define R2_IO_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* these should be equals to R_BIN_SCN_* permissions */ #define R_IO_EXEC (1 << 0) #define R_IO_WRITE (1 << 1) #define R_IO_READ (1 << 2) #define R_IO_MAP (1 << 4) #define R_IO_RW (R_IO_READ | R_IO_WRITE) #define R_IO_SEEK_SET 0 #define R_IO_SEEK_CUR 1 #define R_IO_SEEK_END 2 #define R_IO_NFDS 32 #define RMT_MAX 4096 #define RMT_OPEN 0x01 #define RMT_READ 0x02 #define RMT_WRITE 0x03 #define RMT_SEEK 0x04 #define RMT_CLOSE 0x05 #define RMT_CMD 0x06 #define RMT_REPLY 0x80 R_LIB_VERSION_HEADER (r_io); // #define RMT_DLDIR "/tmp/$USER/r2" // #define RMT_UPLOAD 0x08 // #define RMT_DOWNLOAD 0x09 // - upload a file giving a chksum #define IO_MAP_N 128 typedef struct r_io_map_t { int fd; int flags; ut64 delta; ut64 from; ut64 to; } RIOMap; typedef struct r_io_section_t { char *name; ut64 offset; // TODO: rename to paddr or maddr? ut64 vaddr; ut64 size; ut64 vsize; int rwx; // rename to perm? like in rdebug? what about rbin? int id; /* */ int arch; int bits; ut32 bin_id; int fd; } RIOSection; typedef struct r_io_desc_t { int fd; int flags; int state; int obsz; // optimal block size char *uri; char *referer; char *name; void *data; struct r_io_plugin_t *plugin; const struct r_io_t *io; } RIODesc; typedef struct { RSocket *fd; RSocket *client; int listener; } RIORap; // enum? #define R_IO_DESC_TYPE_OPENED 1 #define R_IO_DESC_TYPE_CLOSED 0 typedef struct r_undo_t { ut64 off; int cursor; } RIOUndos; /* stores write and seek changes */ #define R_IO_UNDOS 64 typedef struct r_io_undo_t { int s_enable; int w_enable; /* write stuff */ RList *w_list; int w_init; /* seek stuff */ int idx; int undos; /* available undos */ int redos; /* available redos */ RIOUndos seek[R_IO_UNDOS]; /*int fd[R_IO_UNDOS]; // XXX: Must be RIODesc* */ } RIOUndo; typedef struct r_io_undo_w_t { int set; ut64 off; ut8 *o; /* old data */ ut8 *n; /* new data */ int len; /* length */ } RIOUndoWrite; typedef struct r_io_t { RIODesc *desc; int enforce_rwx; int enforce_seek; int cached; int bits; int cached_read; ut64 off; int debug; int raised; int va; int raw; int vio; // remove that when vio replaces the old stuff int sectonly; char *referer; char *redirect; /* write mask */ void (*cb_printf)(const char *str, ...); int write_mask_fd; ut8 *write_mask_buf; int write_mask_len; struct r_io_plugin_t *plugin; RIOUndo undo; RList *plugins; RList *sections; int next_section_id; RIOSection *section; /* current section (cache) */ /* maps */ RList *maps; /**/ RList *files; RList *cache; RCache *buffer; int buffer_enabled; bool ff; ut8 Oxff; int autofd; int aslr; ut64 winbase; ut64 maxalloc; char *runprofile; char *args; /* Core Callbacks (used by rap) */ void *user; int (*cb_core_cmd)(void *user, const char *str); char* (*cb_core_cmdstr)(void *user, const char *str); struct r_io_plugin_t *plugin_default; } RIO; typedef struct r_io_plugin_t { // void *plugin; char *name; char *desc; char *license; void *widget; int (*listener)(RIODesc *io); int (*init)(); RIOUndo undo; bool isdbg; // int (*is_file_opened)(RIO *io, RIODesc *fd, const char *); int (*system)(RIO *io, RIODesc *fd, const char *); RIODesc* (*open)(RIO *io, const char *, int rw, int mode); RList* /*RIODesc* */ (*open_many)(RIO *io, const char *, int rw, int mode); int (*read)(RIO *io, RIODesc *fd, ut8 *buf, int count); ut64 (*lseek)(RIO *io, RIODesc *fd, ut64 offset, int whence); int (*write)(RIO *io, RIODesc *fd, const ut8 *buf, int count); int (*close)(RIODesc *desc); bool (*resize)(RIO *io, RIODesc *fd, ut64 size); int (*extend)(RIO *io, RIODesc *fd, ut64 size); bool (*accept)(RIO *io, RIODesc *desc, int fd); int (*create)(RIO *io, const char *file, int mode, int type); bool (*check)(RIO *io, const char *, bool many); } RIOPlugin; struct r_io_bind_t; /* TODO: find better name... RIOSetFd_Callback? ..Func? .. too camels here */ typedef RIO * (*RIOGetIO) (struct r_io_bind_t *iob); typedef int (*RIOSetFd)(RIO *io, int fd); typedef int (*RIOReadAt)(RIO *io, ut64 addr, ut8 *buf, int size); typedef int (*RIOWriteAt)(RIO *io, ut64 addr, const ut8 *buf, int size); typedef ut64 (*RIOSize)(RIO *io); typedef ut64 (*RIOSeek)(RIO *io, ut64 offset, int whence); typedef RIODesc* (*RIODescGetFD)(RIO *io, int fd); typedef RIODesc* (*RIODescOpen)(RIO *io, const char *file, int flags, int mode); typedef RIODesc* (*RIODescOpenAt)(RIO *io, const char *file, int flags, int mode, ut64 maddr); typedef int (*RIODescClose)(RIO *io, RIODesc *); typedef ut8 * (*RIODescRead)(RIO *io, RIODesc *desc, ut64 *sz); typedef ut64 (*RIODescSeek)(RIO *io, RIODesc *desc, ut64 offset); typedef ut64 (*RIODescSize)(RIO *io, RIODesc *desc); typedef int (*RIOIsValidOffset)(RIO *io, ut64 addr, int hasperm); typedef RIOSection* (*RIOSectionVGet)(RIO *io, ut64 addr); typedef RIOSection* (*RIOSectionAdd)(RIO *io, ut64 offset, ut64 vaddr, ut64 size, ut64 vsize, int rwx, const char *name, ut32 bin_id, int fd); typedef int (*RIOSectionSetArchBinID)(RIO *io, ut64 addr, const char *arch, int bits, ut32 bin_id); typedef int (*RIOSectionSetArchBin)(RIO *io, ut64 addr, const char *arch, int bits); /* compile time dependency */ typedef struct r_io_bind_t { int init; RIO *io; RIOGetIO get_io; RIOSetFd set_fd; // XXX : this is conceptually broken with the new RIODesc foo RIOReadAt read_at; RIOWriteAt write_at; RIOSize size; RIOSeek seek; RIOIsValidOffset is_valid_offset; RIOSectionVGet section_vget; RIOSectionAdd section_add; RIOSectionSetArchBin section_set_arch; RIOSectionSetArchBinID section_set_arch_bin_id; RIODescOpen desc_open; RIODescOpenAt desc_open_at; //esil-gb needs that to allocate mem on init RIODescClose desc_close; RIODescRead desc_read; RIODescSize desc_size; RIODescSeek desc_seek; RIODescGetFD desc_get_by_fd; } RIOBind; typedef struct r_io_cache_t { ut64 from; ut64 to; int size; ut8 *data; ut8 *odata; int written; } RIOCache; typedef struct r_io_range_t { ut64 from; ut64 to; } RIORange; // XXX: HACK this must be io->desc_new() maybe? #define RETURN_IO_DESC_NEW(fplugin,ffd,fname,fflags,mode,fdata) { \ if (!fname) return NULL; \ RIODesc *desc = R_NEW0 (RIODesc); \ if (desc != NULL) { \ desc->state = R_IO_DESC_TYPE_OPENED; \ desc->name = fname? strdup (fname): NULL; \ if (desc->name != NULL) { \ desc->plugin = fplugin; \ desc->flags = fflags; \ if (ffd == -2) { \ desc->fd = ((size_t)desc)&0xffffff; \ } else \ if (ffd == -1) { \ desc->fd = ((size_t)desc)&0xffffff; \ } else desc->fd = ffd; \ desc->data = fdata; \ } else { \ free (desc); \ free (fdata); \ desc = NULL; \ } \ } \ /* free (fname); */ \ return desc; \ } #ifdef R_API #define r_io_bind_init(x) memset(&x,0,sizeof(x)) /* io/plugin.c */ R_API RIO *r_io_new(void); R_API RIO *r_io_free(RIO *io); R_API void r_io_set_raw(RIO *io, int raw); R_API bool r_io_plugin_init(RIO *io); R_API void r_io_raise (RIO *io, int fd); R_API int r_io_plugin_generate(RIO *io); R_API bool r_io_plugin_add(RIO *io, RIOPlugin *plugin); R_API int r_io_plugin_list(RIO *io); R_API int r_io_is_listener(RIO *io); R_API RIOPlugin *r_io_plugin_byname(RIO *io, const char *name); R_API RIOPlugin *r_io_plugin_resolve(RIO *io, const char *filename, bool many); R_API RIOPlugin *r_io_plugin_resolve_fd(RIO *io, int fd); R_API RIOPlugin *r_io_plugin_get_default(RIO *io, const char *filename, bool many); /* io/io.c */ R_API int r_io_set_write_mask(RIO *io, const ut8 *buf, int len); R_API RIODesc *r_io_open(RIO *io, const char *file, int flags, int mode); //opens a file with map at 0x0 R_API RIODesc *r_io_open_at (RIO *io, const char *file, int flags, int mode, ut64 maddr); //opens a file with map at maddr R_API RIODesc *r_io_open_nomap (RIO *io, const char *file, int flags, int mode); //opens a file without map -> only pread and pwrite can be used for access R_API RList *r_io_open_many(RIO *io, const char *file, int flags, int mode); R_API RIODesc *r_io_open_as(RIO *io, const char *urihandler, const char *file, int flags, int mode); R_API int r_io_reopen (RIO *io, RIODesc *desc, int flags, int mode); R_API int r_io_redirect(RIO *io, const char *file); //checks if io-access is reasonable at this offset R_API int r_io_is_valid_offset (RIO *io, ut64 offset, int hasperm); R_API RIODesc *r_io_use_fd(RIO *io, int fd); R_API int r_io_use_desc(RIO *io, RIODesc *fd); R_API const ut8* r_io_get_raw(RIO *io, ut64 addr, int *len); 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); R_API int r_io_plugin_close(RIO *io, RIODesc *desc); R_API int r_io_close(RIO *io, RIODesc *desc); R_API int r_io_close_all(RIO *io); R_API ut64 r_io_size(RIO *io); //, int fd); R_API bool r_io_resize(RIO *io, ut64 newsize); R_API int r_io_extend(RIO *io, ut64 size); R_API int r_io_extend_at(RIO *io, ut64 addr, ut64 size); R_API int r_io_accept(RIO *io, int fd); R_API int r_io_shift(RIO *io, ut64 start, ut64 end, st64 move); R_API int r_io_create (RIO *io, const char *file, int mode, int type); R_API int r_io_bind(RIO *io, RIOBind *bnd); R_API void r_io_sort_maps (RIO *io); /* io/cache.c */ R_API int r_io_cache_invalidate(RIO *io, ut64 from, ut64 to); R_API void r_io_cache_commit(RIO *io, ut64 from, ut64 to); R_API void r_io_cache_enable(RIO *io, int read, int write); R_API void r_io_cache_init(RIO *io); R_API int r_io_cache_list(RIO *io, int rad); R_API void r_io_cache_reset(RIO *io, int set); R_API int r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len); R_API int r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len); /* io/map.c */ R_API void r_io_map_init(RIO *io); R_API bool r_io_map_overlaps (RIO *io, RIODesc *fd, RIOMap *map); R_API ut64 r_io_map_next(RIO *io, ut64 addr); R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 offset, ut64 size); R_API int r_io_map_del_at(RIO *io, ut64 addr); R_API RIOMap *r_io_map_get(RIO *io, ut64 addr); R_API RIOMap *r_io_map_get_global(RIO *io, ut64 addr); R_API RIOMap *r_io_map_get_local(RIO *io, ut64 addr, int fd); R_API int r_io_map_del(RIO *io, int fd); R_API int r_io_map(RIO *io, const char *file, ut64 offset); R_API ut64 r_io_map_select(RIO *io, ut64 off); R_API ut64 r_io_map_select_current_fd(RIO *io, ut64 off, int fd); //R_API int r_io_map_read_rest(RIO *io, ut64 off, ut8 *buf, ut64 len); R_API RIOMap *r_io_map_resolve(RIO *io, int fd); R_API RIOMap *r_io_map_resolve_from_list (RList *maps, int fd); R_API RIOMap *r_io_map_resolve_in_range (RIO *io, ut64 addr, ut64 endaddr, int fd); R_API int r_io_map_sort (void *a, void *b); R_API RIOMap * r_io_map_add_next_available (RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, ut64 align); R_API RIOMap * r_io_map_new(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size); R_API RList * r_io_map_get_maps_in_range (RIO *io, ut64 addr, ut64 endaddr); R_API RIOMap * r_io_map_get_first_map_in_range(RIO *io, ut64 addr, ut64 endaddr); R_API int r_io_map_exists_for_offset (RIO *io, ut64 off); R_API int r_io_map_write_update(RIO *io, int fd, ut64 addr, ut64 len); R_API int r_io_map_truncate_update(RIO *io, int fd, ut64 sz); R_API int r_io_map_count (RIO *io); R_API void r_io_map_list (RIO *io, int rad); /* io/section.c */ R_API void r_io_section_init(RIO *io); R_API void r_io_section_free(void *ptr); R_API RIOSection *r_io_section_add(RIO *io, ut64 offset, ut64 vaddr, ut64 size, ut64 vsize, int rwx, const char *name, ut32 bin_id, int fd); R_API RIOSection *r_io_section_get_name(RIO *io, const char *name); R_API RIOSection *r_io_section_get_i(RIO *io, int idx); R_API RIOSection *r_io_section_getv(RIO *io, ut64 vaddr); R_API RIOSection *r_io_section_mget_in(RIO *io, ut64 maddr); R_API RIOSection *r_io_section_mget_prev(RIO *io, ut64 maddr); R_API RIOSection *r_io_section_vget(RIO *io, ut64 addr); R_API RIOSection *r_io_section_pget(RIO *io, ut64 addr); R_API int r_io_section_set_archbits(RIO *io, ut64 addr, const char *arch, int bits); R_API const char *r_io_section_get_archbits(RIO* io, ut64 addr, int *bits); R_API void r_io_section_clear(RIO *io); R_API int r_io_section_rm(RIO *io, int idx); R_API int r_io_section_rm_all (RIO *io, int fd); R_API void r_io_section_list(RIO *io, ut64 offset, int rad); R_API void r_io_section_list_visual(RIO *io, ut64 seek, ut64 len, int color, int cols); R_API void r_io_desc_list_visual(RIO *io, ut64 seek, ut64 len, int width, int use_color); R_API RIOSection *r_io_section_get(RIO *io, ut64 offset); R_API ut64 r_io_section_get_offset(RIO *io, ut64 offset); R_API ut64 r_io_section_get_vaddr(RIO *io, ut64 offset); R_API int r_io_section_get_rwx(RIO *io, ut64 offset); R_API int r_io_section_overlaps(RIO *io, RIOSection *s); R_API ut64 r_io_section_vaddr_to_maddr_try(RIO *io, ut64 vaddr); R_API ut64 r_io_section_vaddr_to_maddr(RIO *io, ut64 vaddr); R_API ut64 r_io_section_maddr_to_vaddr(RIO *io, ut64 maddr); R_API ut64 r_io_section_next(RIO *io, ut64 o); R_API int r_io_section_set_archbits_bin_id(RIO *io, ut64 addr, const char *arch, int bits, ut32 bin_id); R_API int r_io_section_exists_for_paddr (RIO *io, ut64 paddr, int hasperm); R_API int r_io_section_exists_for_vaddr (RIO *io, ut64 vaddr, int hasperm); R_API RList *r_io_section_get_in_vaddr_range(RIO *io, ut64 addr, ut64 endaddr); R_API RList *r_io_section_get_in_paddr_range(RIO *io, ut64 addr, ut64 endaddr); R_API RIOSection * r_io_section_get_first_in_vaddr_range(RIO *io, ut64 addr, ut64 endaddr); R_API RIOSection * r_io_section_get_first_in_paddr_range(RIO *io, ut64 addr, ut64 endaddr); /* undo api */ // track seeks and writes // TODO: needs cleanup..kinda big? R_API int r_io_undo_init(RIO *io); R_API void r_io_undo_enable(RIO *io, int seek, int write); /* seek undo */ R_API RIOUndos *r_io_sundo(RIO *io, ut64 offset); R_API RIOUndos *r_io_sundo_redo(RIO *io); R_API void r_io_sundo_push(RIO *io, ut64 off, int cursor); R_API void r_io_sundo_reset(RIO *io); R_API void r_io_sundo_list(RIO *io, int mode); /* write undo */ R_API void r_io_wundo_new(RIO *io, ut64 off, const ut8 *data, int len); R_API void r_io_wundo_apply_all(RIO *io, int set); R_API int r_io_wundo_apply(RIO *io, struct r_io_undo_w_t *u, int set); R_API void r_io_wundo_clear(RIO *io); R_API int r_io_wundo_size(RIO *io); R_API void r_io_wundo_list(RIO *io); R_API int r_io_wundo_set_t(RIO *io, RIOUndoWrite *u, int set) ; R_API void r_io_wundo_set_all(RIO *io, int set); R_API int r_io_wundo_set(RIO *io, int n, int set); /* io/desc.c */ R_API void r_io_desc_init(RIO *io); R_API void r_io_desc_fini(RIO *io); R_API RIODesc *r_io_desc_new(RIOPlugin *plugin, int fd, const char *name, int flags, int mode, void *data); R_API void r_io_desc_free(RIODesc *desc); R_API int r_io_desc_del(RIO *io, int fd); R_API RIODesc *r_io_desc_get(RIO *io, int fd); R_API int r_io_desc_add(RIO *io, RIODesc *desc); R_API int r_io_desc_del(RIO *io, int fd); R_API RIODesc *r_io_desc_get(RIO *io, int fd); R_API ut64 r_io_desc_size(RIO *io, RIODesc *desc); R_API ut64 r_io_fd_size(RIO *io, int fd); R_API ut64 r_io_desc_seek (RIO *io, RIODesc *desc, ut64 offset); R_API void r_io_desc_list (RIO *io); //R_API int r_io_desc_generate(RIO *io); /* buffer.c */ R_API void r_io_buffer_close(RIO* io); R_API int r_io_buffer_load(RIO* io, ut64 addr, int len); R_API const ut8* r_io_buffer_get (RIO *io, ut64 addr, int *len); R_API int r_io_buffer_read (RIO *io, ut64 addr, ut8* buf, int len); #define r_io_range_new() R_NEW0(RIORange) #define r_io_range_free(x) free(x) /* plugins */ extern RIOPlugin r_io_plugin_procpid; extern RIOPlugin r_io_plugin_malloc; extern RIOPlugin r_io_plugin_sparse; extern RIOPlugin r_io_plugin_ptrace; extern RIOPlugin r_io_plugin_w32dbg; extern RIOPlugin r_io_plugin_mach; extern RIOPlugin r_io_plugin_debug; extern RIOPlugin r_io_plugin_shm; extern RIOPlugin r_io_plugin_gdb; extern RIOPlugin r_io_plugin_qnx; extern RIOPlugin r_io_plugin_rap; extern RIOPlugin r_io_plugin_http; extern RIOPlugin r_io_plugin_bfdbg; extern RIOPlugin r_io_plugin_w32; extern RIOPlugin r_io_plugin_zip; extern RIOPlugin r_io_plugin_mmap; extern RIOPlugin r_io_plugin_default; extern RIOPlugin r_io_plugin_ihex; extern RIOPlugin r_io_plugin_self; extern RIOPlugin r_io_plugin_gzip; extern RIOPlugin r_io_plugin_windbg; extern RIOPlugin r_io_plugin_r2pipe; extern RIOPlugin r_io_plugin_r2web; extern RIOPlugin r_io_plugin_bochs; extern RIOPlugin r_io_plugin_r2k; #endif #ifdef __cplusplus } #endif #endif