Rizin
unix-like reverse engineering framework and cli tools
cvfile.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_core.h>
5 
6 #define URI_SCHEME "vfile://"
7 #define URI_SCHEME_LEN 8
8 
9 typedef struct {
13 } VFileCtx;
14 
16 
17 static bool vf_check(RzIO *io, const char *pathname, bool many) {
18  // be careful if changing this, vf_open relies on its behavior!
19  return !strncmp(pathname, URI_SCHEME, URI_SCHEME_LEN);
20 }
21 
22 static RzBinVirtualFile *find_vfile(RzBinFile *bf, const char *name) {
23  if (!bf->o || !bf->o->vfiles) {
24  return NULL;
25  }
26  RzListIter *it;
27  RzBinVirtualFile *vfile;
28  rz_list_foreach (bf->o->vfiles, it, vfile) {
29  if (!strcmp(vfile->name, name)) {
30  return vfile;
31  }
32  }
33  return NULL;
34 }
35 
36 static RzIODesc *vf_open(RzIO *io, const char *pathname, int rw, int mode) {
37  if (!vf_check(io, pathname, false)) {
38  return NULL;
39  }
40  char *vfile_path = strdup(pathname + URI_SCHEME_LEN); // path like "<binfile id>/<filename>"
41  if (!vfile_path) {
42  return NULL;
43  }
44  RzIODesc *desc = NULL;
45  char *filename = strchr(vfile_path, '/');
46  if (!filename) {
47  RZ_LOG_ERROR("Invalid URI \"%s\", expected " URI_SCHEME "<fd>/<filename>\n", pathname);
48  goto beach;
49  }
50  *filename++ = '\0';
51  ut32 bfid = (ut32)strtoull(vfile_path, NULL, 0);
52  RzCore *core = io->corebind.core; // We are in the core already so this is fine.
53  RzBinFile *bf = rz_bin_file_find_by_id(core->bin, bfid);
54  if (!bf) {
55  RZ_LOG_ERROR("No bin file for id %" PFMT32u " from URI \"%s\"\n", bfid, pathname);
56  goto beach;
57  }
58  RzBinVirtualFile *vfile = find_vfile(bf, filename);
59  if (!vfile) {
60  RZ_LOG_ERROR("No virtual file called \"%s\" for bin file id %" PFMT32u " from URI \"%s\"\n", filename, bfid, pathname);
61  goto beach;
62  }
64  if (!ctx) {
65  goto beach;
66  }
67  ctx->bf = bf;
68  ctx->vfile = vfile;
69  ctx->off = 0;
71  if (!desc) {
72  free(ctx);
73  }
74 beach:
75  free(vfile_path);
76  return desc;
77 }
78 
79 static int vf_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
80  rz_return_val_if_fail(fd && fd->data, -1);
81  if (!(fd->perm & RZ_PERM_W)) {
82  return -1;
83  }
84  VFileCtx *ctx = fd->data;
85  return rz_buf_write_at(ctx->vfile->buf, ctx->off, buf, count);
86 }
87 
88 static int vf_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
89  rz_return_val_if_fail(fd && fd->data, -1);
90  VFileCtx *ctx = fd->data;
91  return rz_buf_read_at(ctx->vfile->buf, ctx->off, buf, count);
92 }
93 
94 static int vf_close(RzIODesc *fd) {
95  rz_return_val_if_fail(fd && fd->data, -1);
96  VFileCtx *ctx = fd->data;
97  free(ctx);
98  fd->data = NULL;
99  return 0;
100 }
101 
102 static ut64 vf_lseek(struct rz_io_t *io, RzIODesc *fd, ut64 offset, int whence) {
103  rz_return_val_if_fail(fd && fd->data, UT64_MAX);
104  VFileCtx *ctx = fd->data;
105  // we store the offset ourselves instead of using the RzBuffer's because
106  // there might be multiple io files accessing the same vfile.
107  switch (whence) {
108  case SEEK_SET:
109  ctx->off = offset;
110  break;
111  case SEEK_CUR:
112  ctx->off += offset;
113  break;
114  case SEEK_END:
115  ctx->off = rz_buf_size(ctx->vfile->buf);
116  break;
117  }
118  return ctx->off;
119 }
120 
121 static bool vf_resize(RzIO *io, RzIODesc *fd, ut64 size) {
122  rz_return_val_if_fail(fd && fd->data, false);
123  VFileCtx *ctx = fd->data;
124  return rz_buf_resize(ctx->vfile->buf, size);
125 }
126 
135  .name = "vfile",
136  .desc = "Virtual Files provided by RzBin Files",
137  .uris = URI_SCHEME,
138  .license = "LGPL",
139  .open = vf_open,
140  .close = vf_close,
141  .read = vf_read,
142  .check = vf_check,
143  .lseek = vf_lseek,
144  .write = vf_write,
145  .resize = vf_resize
146 };
147 
148 #ifndef RZ_PLUGIN_INCORE
150  .type = RZ_LIB_TYPE_IO,
151  .data = &rz_io_plugin_vfile,
152  .version = RZ_VERSION
153 };
154 #endif
155 
157  // close all vfile descs that point into the binfile that is about to be closed
158  // This is strictly necessary because VFileCtx holds pointers into it!
159  RzList *descs = rz_id_storage_list(core->io->files);
160  if (!descs) {
161  return;
162  }
163  RzListIter *it;
164  RzIODesc *desc;
165  rz_list_foreach (descs, it, desc) {
166  if (strcmp(desc->plugin->name, rz_core_io_plugin_vfile.name)) {
167  continue;
168  }
169  VFileCtx *ctx = desc->data;
170  if (ctx->bf == bf) {
172  }
173  }
174  rz_list_free(descs);
175 }
#define RZ_IPI
Definition: analysis_wasm.c:11
RZ_API RzBinFile * rz_bin_file_find_by_id(RzBin *bin, ut32 bf_id)
Definition: bfile.c:188
const char * desc
Definition: bin_vsf.c:19
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RzIOPlugin rz_core_io_plugin_vfile
IO Plugin that opens RzBinVirtualFiles supplied by the plugin of an RzBinFile.
Definition: cvfile.c:134
static int vf_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: cvfile.c:88
static int vf_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: cvfile.c:79
static bool vf_resize(RzIO *io, RzIODesc *fd, ut64 size)
Definition: cvfile.c:121
static int vf_close(RzIODesc *fd)
Definition: cvfile.c:94
RZ_API RzLibStruct rizin_plugin
Definition: cvfile.c:149
static bool vf_check(RzIO *io, const char *pathname, bool many)
Definition: cvfile.c:17
RZ_IPI void rz_core_vfile_bin_file_deleted(RzCore *core, RzBinFile *bf)
Definition: cvfile.c:156
#define URI_SCHEME_LEN
Definition: cvfile.c:7
static ut64 vf_lseek(struct rz_io_t *io, RzIODesc *fd, ut64 offset, int whence)
Definition: cvfile.c:102
#define URI_SCHEME
Definition: cvfile.c:6
static RzBinVirtualFile * find_vfile(RzBinFile *bf, const char *name)
Definition: cvfile.c:22
static RzIODesc * vf_open(RzIO *io, const char *pathname, int rw, int mode)
Definition: cvfile.c:36
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char pathname
Definition: sflib.h:66
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_buf_resize(RZ_NONNULL RzBuffer *b, ut64 newsize)
Resize the buffer size.
Definition: buf.c:890
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
RZ_API RzList * rz_id_storage_list(RzIDStorage *s)
Definition: idpool.c:283
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define PFMT32u
Definition: rz_types.h:409
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_PERM_W
Definition: rz_types.h:94
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
Definition: cvfile.c:9
ut64 off
Definition: cvfile.c:12
RzBinFile * bf
Definition: cvfile.c:10
RzBinVirtualFile * vfile
Definition: cvfile.c:11
Definition: z80asm.h:102
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
RzList * vfiles
Definition: rz_bin.h:265
RZ_OWN RZ_NONNULL char * name
Definition: rz_bin.h:596
void * core
Definition: rz_bind.h:31
RzBin * bin
Definition: rz_core.h:298
RzIO * io
Definition: rz_core.h:313
const char * name
Definition: rz_io.h:115
Definition: rz_io.h:59
RzCoreBind corebind
Definition: rz_io.h:92
RzIDStorage * files
Definition: rz_io.h:75
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
#define SEEK_SET
Definition: zip.c:88
#define SEEK_CUR
Definition: zip.c:80
#define SEEK_END
Definition: zip.c:84