/* radare2 - LGPL - Copyright 2017-2026 - condret, pancake */ #ifndef R2_IO_H #define R2_IO_H #include #include #include #include #include #include #define R_IO_SEEK_SET 0 #define R_IO_SEEK_CUR 1 #define R_IO_SEEK_END 2 #define R_IO_SEEK_HOLE 3 #define R_IO_UNDOS 64 #define r_io_map_begin(map) r_itv_begin ((map)->itv) #define r_io_map_to(map) ( r_itv_end ((map)->itv) - 1 ) #define r_io_map_from r_io_map_begin #define r_io_submap_from(sm) (r_io_map_begin (sm)) #define r_io_submap_to(sm) (r_io_map_to (sm)) #define r_io_map_end(map) r_itv_end ((map)->itv) #define r_io_map_size(map) r_itv_size ((map)->itv) #define r_io_map_contain(map, addr) r_itv_contain ((map)->itv, addr) #define r_io_submap_contain(sm, addr) r_io_map_contain (sm, addr) #define r_io_submap_overlap(bd, sm) r_itv_overlap((bd)->itv, (sm)->itv) #define r_io_map_set_begin(map, new_addr) \ do { \ map->itv.addr = new_addr; \ } while (0) #define r_io_map_set_size(map, new_size) \ do { \ map->itv.size = new_size; \ } while (0) #if HAVE_PTRACE #if __sun #include #else #if DEBUGGER && HAVE_PTRACE && !R2__WINDOWS__ && !APPLE_SDK_IPHONEOS && !defined(__HAIKU__) #include #endif #endif #if (defined(__GLIBC__) && defined(__linux__)) typedef enum __ptrace_request r_ptrace_request_t; typedef void * r_ptrace_data_t; #define R_PTRACE_NODATA NULL #else #if __ANDROID__ typedef int r_ptrace_request_t; typedef void * r_ptrace_data_t; #define R_PTRACE_NODATA NULL #elif __APPLE__ typedef int r_ptrace_request_t; typedef int r_ptrace_data_t; #elif __OpenBSD__ || __FreeBSD__ || __NetBSD__ typedef int r_ptrace_request_t; typedef int r_ptrace_data_t; #define R_PTRACE_NODATA 0 #else typedef int r_ptrace_request_t; typedef void *r_ptrace_data_t; #define R_PTRACE_NODATA 0 #endif #endif #endif #if __cplusplus extern "C" { #endif R_LIB_VERSION_HEADER(r_io); typedef struct r_io_undos_t { ut64 off; int cursor; } RIOUndos; typedef struct r_io_undo_t { bool s_enable; bool 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]; // XXX R2_590 - use an RVec here } RIOUndo; typedef struct r_io_undo_w_t { bool set; ut64 off; ut8 *o; /* old data */ ut8 *n; /* new data */ size_t len; /* length */ } RIOUndoWrite; typedef struct io_cache_item_t { RInterval *tree_itv; RInterval itv; ut8 *data; ut8 *odata; // is this a good idea? bool written; } RIOCacheItem; R_VEC_TYPE (RVecRIOCacheItemPtr, RIOCacheItem *); // io cache typedef struct r_io_cache_layer_t { #if 0 char *name; int fd, bd, ... :? #endif RVecRIOCacheItemPtr *vec; // a vector of items RRBTree *tree; // faster access to the items // RRBComparator ci_cmp_cb; // this comparator can be inside the rbtree impl } RIOCacheLayer; typedef struct r_io_cache_t { RList *layers; // a list of cache layers-- must be a vector O(n) ut32 mode; // read, write, exec (enabled) sperm = requires maps bool enabled; } RIOCache; // -io-cache- typedef struct r_io_t { struct r_io_desc_t *desc; // XXX R2_600 - deprecate... we should use only the fd integer, not hold a weak pointer ut64 off; // XXX maybe deprecate this global seek? also it should be addr, not off R2_600 ut32 bank; // current bank int bits; int va; // keep it as int, value can be 0, 1 or 2 bool ff; ut8 Oxff; // which printable char to use instead of 0xff for unallocated bytes size_t addrbytes; // XXX also available in RArchConfig.addrbytes bool autofd; bool overlay; // moved into cache.mode // ut32 cached; // uses R_PERM_RWX // wtf cache for exec? bool cachemode; // write in cache all the read operations (EXPERIMENTAL) ut32 p_cache; // uses 1, 2, 4.. probably R_PERM_RWX :D ut64 mts; // map "timestamps", this sucks somehow RIDStorage files; // RIODescs accessible by their fd RIDStorage maps; // RIOMaps accessible by their id RIDStorage banks; // RIOBanks accessible by their id RIOCache cache; ut8 *write_mask; int write_mask_len; ut64 mask; RIOUndo undo; bool nodup; char *runprofile; char *envprofile; char *args; REvent *event; PrintfCallback cb_printf; RCoreBind coreb; RMutaBind mb; // TODO Wrap ... well its more like a proxy, should unify across OS instead of using separate apis bool want_ptrace_wrap; #if R2__WINDOWS__ RW32Dw *dbgwrap; #endif #if USE_PTRACE_WRAP // TODO: rename to dbgwrap struct ptrace_wrap_instance_t *ptrace_wrap; #endif RLibStore *libstore; } RIO; typedef struct r_io_desc_t { int fd; int perm; char *uri; char *name; char *referer; HtUP/**/ *cache; void *data; struct r_io_plugin_t *plugin; RIO *io; } RIODesc; // Move somewhere else? typedef struct { RSocket *fd; RSocket *client; bool listener; } RIORap; typedef struct r_io_plugin_t { const RPluginMeta meta; void *data; // kind of globals, used by rlang-io in this case const char *uris; int (*listener)(RIODesc *io); bool isdbg; // int (*is_file_opened)(RIO *io, RIODesc *fd, const char *); char *(*system)(RIO *io, RIODesc *fd, const char *); // Rename to call? or cmd? unify with anal and core RIODesc* (*open)(RIO *io, const char *, int perm, int mode); RList* /*RIODesc* */ (*open_many)(RIO *io, const char *, int perm, int mode); int (*read)(RIO *io, RIODesc *fd, ut8 *buf, int count); ut64 (*seek)(RIO *io, RIODesc *fd, ut64 offset, int whence); int (*write)(RIO *io, RIODesc *fd, const ut8 *buf, int count); bool (*close)(RIODesc *desc); // maybe just have a getinfo() that returns this struct // RIOInfo * = struct { isblock, ischar, pid, tid, base, size } bool (*is_blockdevice)(RIODesc *desc); bool (*is_chardevice)(RIODesc *desc); int (*getpid)(RIODesc *desc); int (*gettid)(RIODesc *desc); bool (*getbase)(RIODesc *desc, ut64 *base); /// bool (*resize)(RIO *io, RIODesc *fd, ut64 size); bool (*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; #define R_IO_MAP_TIE_FLG_BACK 1 //ties a map so that it resizes when the desc resizes #define R_IO_MAP_TIE_FLG_FORTH (1 << 1) //ties a map so that the desc resizes when the map resizes typedef enum { R_IO_MAP_META_TYPE_NONE = 0, R_IO_MAP_META_TYPE_HEAP, // heap memory R_IO_MAP_META_TYPE_STACK, // program stack R_IO_MAP_META_TYPE_MMAP, // mapped memory R_IO_MAP_META_TYPE_MMIO, // mapped devices R_IO_MAP_META_TYPE_DMA, // high speed hw data transfer R_IO_MAP_META_TYPE_JIT, // just in time code R_IO_MAP_META_TYPE_BSS, // block started symbol (zero paged memory) R_IO_MAP_META_TYPE_SHARED, // ipc, etc R_IO_MAP_META_TYPE_KERNEL, // VDSO, etc, text|data|buffers R_IO_MAP_META_TYPE_GUARD, // surrounding stack for protections R_IO_MAP_META_TYPE_NULL, // to catch null derefs R_IO_MAP_META_TYPE_GPU, // graphics memory R_IO_MAP_META_TYPE_TLS, // thread-local storage R_IO_MAP_META_TYPE_BUFFER, // temporal R_IO_MAP_META_TYPE_COW, // copy on write R_IO_MAP_META_TYPE_PAGETABLES, // mmu settings R_IO_MAP_META_TYPE_LAST } RIOMapMetaType; #define R_IO_MAP_META_FLAG_LAST 16 typedef enum { R_IO_MAP_META_FLAG_PAGED, // anything can be non-paged.. must be bitfield R_IO_MAP_META_FLAG_PRIVATE, // private memory R_IO_MAP_META_FLAG_PERSISTENT, // non volatile R_IO_MAP_META_FLAG_ASLR, // randomizable R_IO_MAP_META_FLAG_SWAP, // swappage to disk R_IO_MAP_META_FLAG_DEP, // same as W^X R_IO_MAP_META_FLAG_ENCLAVE, // protected by a secure enclave R_IO_MAP_META_FLAG_COMPRESSED, // compressed memory R_IO_MAP_META_FLAG_ENCRYPTED, // cryptographically secure R_IO_MAP_META_FLAG_LARGE, // different alignment for big data R_IO_MAP_META_FLAG_SYSTEM, // frameworks, dyldcache, .. R_IO_MAP_META_FLAG_LIBRARY, // maybe the same of system? } RIOMapMetaFlags; typedef struct r_io_map_t { int fd; int perm; int sperm; ut32 id; ut64 ts; RInterval itv; ut64 delta; // paddr = vaddr - itv.addr + delta RRBTree *overlay; char *name; ut32 tie_flags; ut32 meta; // metadata attributes } RIOMap; typedef struct r_io_map_ref_t { ut32 id; ut64 ts; } RIOMapRef; typedef struct r_io_submap_t { RIOMapRef mapref; RInterval itv; } RIOSubMap; typedef struct r_io_bank_t { char *name; RRBTree *submaps; RList *maprefs; // references to maps, avoid double-free and dups RQueue *todo; // needed for operating on submap tree RRBNode *last_used; ut32 id; // for fast selection with RIDStorage bool drain_me; // speedup r_io_nread_at } RIOBank; typedef struct r_io_region_t { RInterval itv; int perm; int sperm; } RIORegion; R_VEC_TYPE (RVecRIORegion, RIORegion); #define R_IO_DESC_CACHE_SIZE (sizeof (ut64) * 8) typedef struct r_io_desc_cache_t { ut64 cached; ut8 cdata[R_IO_DESC_CACHE_SIZE]; } RIODescCache; struct r_io_bind_t; typedef bool (*RIODescUse)(RIO *io, int fd); typedef RIODesc *(*RIODescGet)(RIO *io, int fd); typedef ut64(*RIODescSize)(RIODesc *desc); typedef RIODesc *(*RIOOpen)(RIO *io, const char *uri, int flags, int mode); typedef RIODesc *(*RIOOpenAt)(RIO *io, const char *uri, int flags, int mode, ut64 at); typedef bool (*RIOClose)(RIO *io, int fd); typedef bool (*RIOReadAt)(RIO *io, ut64 addr, ut8 *buf, int len); typedef bool (*RIOWriteAt)(RIO *io, ut64 addr, const ut8 *buf, int len); typedef bool (*RIOOverlayWriteAt)(RIO *io, ut64 addr, const ut8 *buf, int len); typedef char *(*RIOSystem)(RIO *io, const char* cmd); typedef int (*RIOFdOpen)(RIO *io, const char *uri, int flags, int mode); typedef bool (*RIOFdClose)(RIO *io, int fd); typedef ut64 (*RIOFdSeek)(RIO *io, int fd, ut64 addr, int whence); typedef ut64 (*RIOFdSize)(RIO *io, int fd); typedef bool (*RIOFdResize)(RIO *io, int fd, ut64 newsize); typedef bool (*RIOP2V)(RIO *io, ut64 p, ut64 *v); typedef ut64 (*RIOV2P)(RIO *io, ut64 va); typedef int (*RIOFdRead)(RIO *io, int fd, ut8 *buf, int len); typedef int (*RIOFdWrite)(RIO *io, int fd, const ut8 *buf, int len); typedef int (*RIOFdReadAt)(RIO *io, int fd, ut64 addr, ut8 *buf, int len); typedef int (*RIOFdWriteAt)(RIO *io, int fd, ut64 addr, const ut8 *buf, int len); typedef bool (*RIOFdIsDbg)(RIO *io, int fd); typedef const char *(*RIOFdGetName)(RIO *io, int fd); typedef RList *(*RIOFdGetMap)(RIO *io, int fd); typedef bool (*RIOFdRemap)(RIO *io, int fd, ut64 addr); typedef bool (*RIOIsValidOff)(RIO *io, ut64 addr, int hasperm); typedef RIOBank *(*RIOBankGet)(RIO *io, ut32 bankid); typedef bool (*RIOBankUse)(RIO *io, ut32 bankid); typedef RIOMap *(*RIOMapGet)(RIO *io, ut32 id); typedef RIOMap *(*RIOMapGetAt)(RIO *io, ut64 addr); typedef RIOMap *(*RIOMapGetPaddr)(RIO *io, ut64 paddr); typedef bool (*RIOAddrIsMapped)(RIO *io, ut64 addr); typedef bool (*RIOGetRegionAt)(RIO *io, RIORegion *region, ut64 addr); typedef RIOMap *(*RIOMapAdd)(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size); typedef bool (*RIOMapLocate)(RIO *io, ut64 *addr, const ut64 size, ut64 load_align); #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); #endif typedef struct r_io_bind_t { int init; RIO *io; RIODescUse desc_use; RIODescGet desc_get; RIODescSize desc_size; RIOOpen open; RIOOpenAt open_at; RIOClose close; RIOReadAt read_at; RIOWriteAt write_at; RIOOverlayWriteAt overlay_write_at; RIOSystem system; RIOFdOpen fd_open; RIOFdClose fd_close; RIOFdSeek fd_seek; //needed for esil RIOFdSize fd_size; RIOFdResize fd_resize; RIOFdRead fd_read; //needed for esil RIOFdWrite fd_write; //needed for esil RIOFdReadAt fd_read_at; RIOFdWriteAt fd_write_at; RIOFdIsDbg fd_is_dbg; RIOFdGetName fd_get_name; RIOFdGetMap fd_get_map; RIOFdRemap fd_remap; RIOIsValidOff is_valid_offset; RIOAddrIsMapped addr_is_mapped; RIOGetRegionAt get_region_at; RIOBankGet bank_get; RIOBankUse bank_use; RIOMapGet map_get; RIOMapGetAt map_get_at; RIOMapGetPaddr map_get_paddr; RIOMapAdd map_add; RIOMapLocate map_locate; RIOV2P v2p; RIOP2V p2v; #if HAVE_PTRACE RIOPtraceFn ptrace; RIOPtraceFuncFn ptrace_func; #endif } RIOBind; //map.c R_API void r_io_map_init(RIO *io); R_API bool r_io_map_remap(RIO *io, ut32 id, ut64 addr); R_API bool r_io_map_remap_fd(RIO *io, int fd, ut64 addr); 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_get(RIO *io, ut32 id); R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size); R_API RIOMap *r_io_map_add_bottom(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size); R_API RIOMap *r_io_map_get_at(RIO *io, ut64 vaddr); // returns the map at vaddr with the highest priority R_API RIOMap *r_io_map_get_by_ref(RIO *io, RIOMapRef *ref); R_API int r_io_map_get_perm(RIO *io, ut32 id); R_API int r_io_map_get_sperm(RIO *io, ut32 id); R_API bool r_io_map_set_perm(RIO *io, ut32 id, int perm); 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); R_API void r_io_map_del(RIO *io, ut32 id); R_API bool r_io_map_del_for_fd(RIO *io, int fd); R_API bool r_io_map_depriorize(RIO* io, ut32 id); R_API bool r_io_map_priorize(RIO *io, ut32 id); R_API bool r_io_map_priorize_for_fd(RIO *io, int fd); R_API void r_io_map_cleanup(RIO *io); R_API void r_io_map_fini(RIO *io); R_API bool r_io_map_is_in_range(RIOMap *map, ut64 from, ut64 to); R_API void r_io_map_set_name(RIOMap *map, const char *name); R_API void r_io_map_del_name(RIOMap *map); R_API RList* r_io_map_get_by_fd(RIO *io, int fd); R_IPI bool io_map_resize(RIO *io, ut32 id, ut64 newsize); R_API bool r_io_map_resize(RIO *io, ut32 id, ut64 newsize); R_API void r_io_map_read_from_overlay(RIOMap *map, ut64 addr, ut8 *buf, int len); R_API bool r_io_map_write_to_overlay(RIOMap *map, ut64 addr, const ut8 *buf, int len); R_IPI bool io_map_get_overlay_intersects(RIOMap *map, RQueue *q, ut64 addr, int len); R_API void r_io_map_drain_overlay(RIOMap *map); typedef void (*RIOMapOverlayForeach)(RInterval itv, const ut8 *data, void *user); R_API void r_io_map_overlay_foreach(RIOMap *map, RIOMapOverlayForeach cb, void *user); // next free address to place a map.. maybe just unify R_API bool r_io_map_locate(RIO *io, ut64 *addr, const ut64 size, ut64 load_align); // p2v/v2p R_API bool r_io_p2v(RIO *io, ut64 p, ut64 *v); R_API ut64 r_io_v2p(RIO *io, ut64 va); //io_submap.c R_API RIOSubMap *r_io_submap_new(RIO *io, RIOMapRef *mapref); R_API bool r_io_submap_set_from(RIOSubMap *sm, const ut64 from); R_API bool r_io_submap_set_to(RIOSubMap *sm, const ut64 to); //io_bank.c R_API RIOBank *r_io_bank_new(const char *name); R_API void r_io_bank_del(RIO *io, const ut32 bankid); R_API ut32 r_io_bank_first(RIO *io); R_API bool r_io_bank_add(RIO *io, RIOBank *bank); R_API void r_io_bank_clear(RIOBank *bank); R_API void r_io_bank_free(RIOBank *bank); R_API void r_io_bank_init(RIO *io); R_API void r_io_bank_fini(RIO *io); R_API RIOBank *r_io_bank_get(RIO *io, const ut32 bankid); R_API RIOBank *r_io_bank_get_byname(RIO *io, const char *bankname); R_API bool r_io_bank_use(RIO *io, ut32 bankid); R_API bool r_io_bank_map_add_top(RIO *io, const ut32 bankid, const ut32 mapid); R_API bool r_io_bank_map_add_bottom(RIO *io, const ut32 bankid, const ut32 mapid); R_API bool r_io_bank_map_priorize(RIO *io, const ut32 bankid, const ut32 mapid); R_API bool r_io_bank_map_depriorize(RIO *io, const ut32 bankid, const ut32 mapid); R_API bool r_io_bank_update_map_boundaries(RIO *io, const ut32 bankid, const ut32 mapid, ut64 ofrom, ut64 oto); R_API bool r_io_bank_locate(RIO *io, const ut32 bankid, ut64 *addr, const ut64 size, ut64 load_align); R_API void r_io_bank_del_map(RIO *io, const ut32 bankid, const ut32 mapid); R_API RIOMap *r_io_bank_get_map_at(RIO *io, const ut32 bankid, const ut64 addr); R_API bool r_io_bank_read_at(RIO *io, const ut32 bankid, ut64 addr, ut8 *buf, int len); R_API bool r_io_bank_write_at(RIO *io, const ut32 bankid, ut64 addr, const ut8 *buf, int len); R_API bool r_io_bank_write_to_overlay_at(RIO *io, const ut32 bankid, ut64 addr, const ut8 *buf, int len); typedef void (*RIOOverlayForeach)(RInterval itv, const ut8 *m_data, const ut8 *o_data, void *user); R_API void r_io_bank_overlay_foreach(RIO *io, const ut32 bankid, RIOOverlayForeach cb, void *user); R_API int r_io_bank_read_from_submap_at(RIO *io, const ut32 bankid, ut64 addr, ut8 *buf, int len); R_API int r_io_bank_write_to_submap_at(RIO *io, const ut32 bankid, ut64 addr, const ut8 *buf, int len); R_API void r_io_bank_drain(RIO *io, const ut32 bankid); R_API bool r_io_bank_get_region_at(RIO *io, const ut32 bankid, RIORegion *region, ut64 addr); R_API RVecRIORegion *r_io_bank_get_regions(RIO *io, const ut32 bankid, RInterval itv); //io.c R_API RIO *r_io_new(void); R_API void r_io_init(RIO *io); R_API RIODesc *r_io_open_nomap(RIO *io, const char *uri, int flags, int mode); R_API RIODesc *r_io_open(RIO *io, const char *uri, int flags, int mode); R_API RIODesc *r_io_open_at(RIO *io, const char *uri, int flags, int mode, ut64 at); R_API RList *r_io_open_many(RIO *io, const char *uri, int flags, int mode); R_API RIODesc* r_io_open_buffer(RIO *io, RBuffer *b, int flags, int mode); R_API bool r_io_close(RIO *io); R_API bool r_io_reopen(RIO *io, int fd, int flags, int mode); R_API void r_io_close_all(RIO *io); R_API int r_io_pread_at(RIO *io, ut64 paddr, ut8 *buf, int len); R_API int r_io_pwrite_at(RIO *io, ut64 paddr, const ut8 *buf, int len); R_API bool r_io_vread_at(RIO *io, ut64 vaddr, ut8 *buf, int len); R_API bool r_io_vwrite_at(RIO *io, ut64 vaddr, const ut8 *buf, int len); R_API bool r_io_vwrite_to_overlay_at(RIO *io, ut64 caddr, const ut8 *buf, int len); R_API bool r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len); R_API int r_io_nread_at(RIO *io, ut64 addr, ut8 *buf, int len); R_API bool r_io_write_at(RIO *io, ut64 addr, const ut8 *buf, int len); R_API bool r_io_read(RIO *io, ut8 *buf, int len); R_API bool r_io_write(RIO *io, ut8 *buf, int len); R_API ut64 r_io_size(RIO *io); R_API bool r_io_is_listener(RIO *io); R_API char *r_io_system(RIO *io, const char* cmd); R_API bool r_io_resize(RIO *io, ut64 newsize); R_API bool r_io_extend_at(RIO *io, ut64 addr, ut64 size); R_API bool r_io_set_write_mask(RIO *io, const ut8 *mask, int len); R_API void r_io_bind(RIO *io, RIOBind *bnd); R_API bool r_io_shift(RIO *io, ut64 start, ut64 end, st64 move); R_API ut64 r_io_seek(RIO *io, ut64 offset, int whence); R_API void r_io_drain_overlay(RIO *io); R_API bool r_io_get_region_at(RIO *io, RIORegion *region, ut64 addr); R_API void r_io_fini(RIO *io); R_API void r_io_free(RIO *io); #define r_io_bind_init(x) (x) = (const RIOBind){0} R_IPI bool r_io_plugins_reset(RIO *io); R_API int r_io_plugin_read(RIODesc *desc, ut8 *buf, int len); R_API int r_io_plugin_write(RIODesc *desc, const ut8 *buf, int len); R_API int r_io_plugin_read_at(RIODesc *desc, ut64 addr, ut8 *buf, int len); R_API int r_io_plugin_write_at(RIODesc *desc, ut64 addr, const ut8 *buf, int len); R_API RIOPlugin *r_io_plugin_resolve(RIO *io, const char *filename, bool many); R_API RIOPlugin *r_io_plugin_get_default(RIO *io, const char *filename, bool many); /* 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 RList *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 bool r_io_wundo_apply_all(RIO *io, bool set); R_API bool r_io_wundo_apply(RIO *io, RIOUndoWrite *u, bool set); R_API void r_io_wundo_clear(RIO *io); R_API int r_io_wundo_size(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); //desc.c R_API RIODesc *r_io_desc_new(RIO *io, RIOPlugin *plugin, const char *uri, int flags, int mode, void *data); R_API RIODesc *r_io_desc_open(RIO *io, const char *uri, int flags, int mode); R_API RIODesc *r_io_desc_open_plugin(RIO *io, RIOPlugin *plugin, const char *uri, int flags, int mode); R_API bool r_io_desc_close(RIODesc *desc); R_API int r_io_desc_read(RIODesc *desc, ut8 *buf, int count); R_API int r_io_desc_write(RIODesc *desc, const ut8 *buf, int count); R_API void r_io_desc_free(RIODesc *desc); R_API bool r_io_desc_add(RIO *io, RIODesc *desc); R_API bool r_io_desc_del(RIO *io, int fd); R_API RIODesc *r_io_desc_get(RIO *io, int fd); R_API RIODesc *r_io_desc_get_byuri(RIO *io, const char *uri); R_API RIODesc *r_io_desc_get_next(RIO *io, RIODesc *desc); R_API RIODesc *r_io_desc_get_prev(RIO *io, RIODesc *desc); R_API RIODesc *r_io_desc_get_highest(RIO *io); R_API RIODesc *r_io_desc_get_lowest(RIO *io); R_API ut64 r_io_desc_seek(RIODesc *desc, ut64 offset, int whence); R_API ut64 r_io_desc_size(RIODesc *desc); R_API bool r_io_desc_resize(RIODesc *desc, ut64 newsize); R_API char *r_io_desc_system(RIODesc *desc, const char *cmd); R_API bool r_io_desc_is_blockdevice(RIODesc *desc); R_API bool r_io_desc_is_chardevice(RIODesc *desc); R_API bool r_io_desc_exchange(RIO *io, int fd, int fdx); R_API bool r_io_desc_is_dbg(RIODesc *desc); R_API int r_io_desc_get_pid(RIODesc *desc); R_API int r_io_desc_get_tid(RIODesc *desc); R_API bool r_io_desc_get_base(RIODesc *desc, ut64 *base); R_API int r_io_desc_read_at(RIODesc *desc, ut64 addr, ut8 *buf, int len); R_API int r_io_desc_write_at(RIODesc *desc, ut64 addr, const ut8 *buf, int len); /* lifecycle */ R_IPI bool r_io_desc_init(RIO *io); R_IPI void r_io_desc_fini(RIO *io); /* io/cache.c */ R_API void r_io_cache_init(RIO *io); R_API void r_io_cache_fini(RIO *io); R_API char *r_io_cache_list(RIO *io, int rad, bool many); R_API bool r_io_cache_empty(RIO *io); R_API void r_io_cache_reset(RIO *io); R_API bool r_io_cache_at(RIO *io, ut64 addr); R_API bool r_io_cache_writable(RIO *io); // apply patches in given buffer R_API bool r_io_cache_write_at(RIO *io, ut64 addr, const ut8 *buf, int len); R_API bool r_io_cache_read_at(RIO *io, ut64 addr, ut8 *buf, int len); // invalidate ranges and commit to io R_API int r_io_cache_invalidate(RIO *io, ut64 from, ut64 to, bool many); R_API void r_io_cache_commit(RIO *io, ut64 from, ut64 to, bool many); // cache layers R_API void r_io_cache_push(RIO *io); R_API bool r_io_cache_pop(RIO *io); R_API bool r_io_cache_undo(RIO *io); R_API bool r_io_cache_redo(RIO *io); /* 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); R_API int r_io_desc_cache_read(RIODesc *desc, ut64 paddr, ut8 *buf, int len); R_API bool r_io_desc_cache_commit(RIODesc *desc); R_API void r_io_desc_cache_cleanup(RIODesc *desc); R_API void r_io_desc_cache_fini(RIODesc *desc); R_API void r_io_desc_cache_fini_all(RIO *io); R_API RList *r_io_desc_cache_list(RIODesc *desc); R_API bool r_io_desc_extend(RIODesc *desc, ut64 size); /* io/fd.c */ R_API int r_io_fd_open(RIO *io, const char *uri, int flags, int mode); R_API bool r_io_fd_close(RIO *io, int fd); R_API int r_io_fd_read(RIO *io, int fd, ut8 *buf, int len); R_API int r_io_fd_write(RIO *io, int fd, const ut8 *buf, int len); R_API ut64 r_io_fd_seek(RIO *io, int fd, ut64 addr, int whence); R_API ut64 r_io_fd_size(RIO *io, int fd); R_API bool r_io_fd_resize(RIO *io, int fd, ut64 newsize); R_API char *r_io_fd_system(RIO *io, int fd, const char *cmd); R_API bool r_io_fd_is_blockdevice(RIO *io, int fd); R_API bool r_io_fd_is_chardevice(RIO *io, int fd); R_API int r_io_fd_read_at(RIO *io, int fd, ut64 addr, ut8 *buf, int len); R_API int r_io_fd_write_at(RIO *io, int fd, ut64 addr, const ut8 *buf, int len); R_API bool r_io_fd_is_dbg(RIO *io, int fd); R_API int r_io_fd_get_pid(RIO *io, int fd); R_API int r_io_fd_get_tid(RIO *io, int fd); R_API bool r_io_fd_get_base(RIO *io, int fd, ut64 *base); R_API const char *r_io_fd_get_name(RIO *io, int fd); R_API int r_io_fd_get_current(RIO *io); R_API bool r_io_use_fd(RIO *io, int fd); R_API int r_io_fd_get_next(RIO *io, int fd); R_API int r_io_fd_get_prev(RIO *io, int fd); R_API int r_io_fd_get_highest(RIO *io); R_API int r_io_fd_get_lowest(RIO *io); R_API bool r_io_map_setattr_fromstring(RIOMap *map, const char *s); R_API bool r_io_map_setattr(RIOMap *map, ut32 type, ut32 flags); R_API char *r_io_map_getattr(RIOMap *map); /* io/ioutils.c */ R_API bool r_io_is_valid_offset(RIO *io, ut64 offset, int hasperm); R_API bool r_io_addr_is_mapped(RIO *io, ut64 vaddr); R_API bool r_io_read_i(RIO* io, ut64 addr, ut64 *val, int size, bool endian); R_API bool r_io_write_i(RIO* io, ut64 addr, ut64 *val, int size, bool endian); #if HAVE_PTRACE R_API long r_io_ptrace(RIO *io, r_ptrace_request_t request, pid_t pid, void *addr, r_ptrace_data_t data); R_API pid_t r_io_ptrace_fork(RIO *io, void(*child_callback)(void *), void *child_callback_user); R_API void *r_io_ptrace_func(RIO *io, void *(*func)(void *), void *user); #endif extern RIOPlugin r_io_plugin_procpid; extern RIOPlugin r_io_plugin_ebpf; 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_windbg; 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_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_dsc; extern RIOPlugin r_io_plugin_ihex; extern RIOPlugin r_io_plugin_srec; extern RIOPlugin r_io_plugin_self; extern RIOPlugin r_io_plugin_gzip; extern RIOPlugin r_io_plugin_winkd; extern RIOPlugin r_io_plugin_r2pipe; extern RIOPlugin r_io_plugin_r2web; extern RIOPlugin r_io_plugin_qnx; extern RIOPlugin r_io_plugin_r2k; extern RIOPlugin r_io_plugin_tcpslurp; extern RIOPlugin r_io_plugin_bochs; extern RIOPlugin r_io_plugin_null; extern RIOPlugin r_io_plugin_ar; extern RIOPlugin r_io_plugin_rbuf; extern RIOPlugin r_io_plugin_winedbg; extern RIOPlugin r_io_plugin_gprobe; extern RIOPlugin r_io_plugin_fd; extern RIOPlugin r_io_plugin_socket; extern RIOPlugin r_io_plugin_xattr; extern RIOPlugin r_io_plugin_isotp; extern RIOPlugin r_io_plugin_xalz; extern RIOPlugin r_io_plugin_reg; extern RIOPlugin r_io_plugin_treebuf; extern RIOPlugin r_io_plugin_sysgdb; extern RIOPlugin r_io_plugin_pvm; extern RIOPlugin r_io_plugin_serial; extern RIOPlugin r_io_plugin_cyclic; extern RIOPlugin r_io_plugin_uf2; extern RIOPlugin r_io_plugin_tap; #if __cplusplus } #endif #endif