Rizin
unix-like reverse engineering framework and cli tools
io_bfdbg.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2013 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "rz_io.h"
5 #include "rz_lib.h"
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #undef RZ_API
10 #define RZ_API static inline
11 #include "../debug/p/bfvm.h"
12 #include "../debug/p/bfvm.c"
13 
14 typedef struct {
16  int fd;
17  ut8 *buf;
20 } RzIOBfdbg;
21 
22 #define RzIOBFDBG_FD(x) (((RzIOBfdbg *)(x)->data)->fd)
23 #define RzIOBFDBG_SZ(x) (((RzIOBfdbg *)(x)->data)->size)
24 #define RzIOBFDBG_BUF(x) (((RzIOBfdbg *)(x)->data)->buf)
25 
26 static inline int is_in_screen(ut64 off, BfvmCPU *c) {
27  return (off >= c->screen && off < c->screen + c->screen_size);
28 }
29 
30 static inline int is_in_input(ut64 off, BfvmCPU *c) {
31  return (off >= c->input && off < c->input + c->input_size);
32 }
33 
34 static inline int is_in_base(ut64 off, BfvmCPU *c) {
35  return (off >= c->base && off < c->base + c->size);
36 }
37 
38 static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
39  RzIOBfdbg *riom;
40  int sz;
41  if (!fd || !fd->data) {
42  return -1;
43  }
44  riom = fd->data;
45  /* data base buffer */
46  if (is_in_base(io->off, riom->bfvm)) {
47  int n = io->off - riom->bfvm->base;
48  if (n > count) {
49  count = n;
50  }
51  memcpy(riom->bfvm->mem + n, buf, count);
52  return count;
53  }
54  /* screen buffer */
55  if (is_in_screen(io->off, riom->bfvm)) {
56  int n = io->off - riom->bfvm->screen;
57  if (n > count) {
58  count = riom->bfvm->screen_size - n;
59  }
60  memcpy(riom->bfvm->screen_buf + n, buf, count);
61  return count;
62  }
63  /* input buffer */
64  if (is_in_input(io->off, riom->bfvm)) {
65  int n = io->off - riom->bfvm->input;
66  if (n > count) {
67  count = riom->bfvm->input_size - n;
68  }
69  memcpy(riom->bfvm->input_buf + n, buf, count);
70  return count;
71  }
72  /* read from file */
73  sz = RzIOBFDBG_SZ(fd);
74  if (io->off + count >= sz) {
75  count = sz - io->off;
76  }
77  if (io->off >= sz) {
78  return -1;
79  }
80  memcpy(RzIOBFDBG_BUF(fd) + io->off, buf, count);
81  return count;
82 }
83 
84 static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
85  RzIOBfdbg *riom;
86  int sz;
87  if (!fd || !fd->data) {
88  return -1;
89  }
90  riom = fd->data;
91  /* data base buffer */
92  if (is_in_base(io->off, riom->bfvm)) {
93  int n = io->off - riom->bfvm->base;
94  if (n > count) {
95  count = n;
96  }
97  memcpy(buf, riom->bfvm->mem + n, count);
98  return count;
99  }
100  /* screen buffer */
101  if (is_in_screen(io->off, riom->bfvm)) {
102  int n = io->off - riom->bfvm->screen;
103  if (n > count) {
104  count = riom->bfvm->screen_size - n;
105  }
106  memcpy(buf, riom->bfvm->screen_buf + n, count);
107  return count;
108  }
109  /* input buffer */
110  if (is_in_input(io->off, riom->bfvm)) {
111  int n = io->off - riom->bfvm->input;
112  if (n > count) {
113  count = riom->bfvm->input_size - n;
114  }
115  memcpy(buf, riom->bfvm->input_buf + n, count);
116  return count;
117  }
118  /* read from file */
119  sz = RzIOBFDBG_SZ(fd);
120  if (io->off + count >= sz) {
121  count = sz - io->off;
122  }
123  if (io->off >= sz) {
124  return -1;
125  }
126  memcpy(buf, RzIOBFDBG_BUF(fd) + io->off, count);
127  return count;
128 }
129 
130 static int __close(RzIODesc *fd) {
131  RzIOBfdbg *riom;
132  if (!fd || !fd->data) {
133  return -1;
134  }
135  riom = fd->data;
136  bfvm_free(riom->bfvm);
137  RZ_FREE(riom->buf);
138  RZ_FREE(fd->data);
139  return 0;
140 }
141 
142 static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
143  switch (whence) {
144  case SEEK_SET: return offset;
145  case SEEK_CUR: return io->off + offset;
146  case SEEK_END: return RzIOBFDBG_SZ(fd);
147  }
148  return offset;
149 }
150 
151 static bool __plugin_open(RzIO *io, const char *pathname, bool many) {
152  return (!strncmp(pathname, "bfdbg://", 8));
153 }
154 
155 static inline int getmalfd(RzIOBfdbg *mal) {
156  return 0xffff & (int)(size_t)mal->buf;
157 }
158 
159 static RzIODesc *__open(RzIO *io, const char *pathname, int rw, int mode) {
160  char *out;
161  if (__plugin_open(io, pathname, 0)) {
162  RzIOBind iob;
164  if (!mal) {
165  return NULL;
166  }
167  rz_io_bind(io, &iob);
168  mal->fd = getmalfd(mal);
169  mal->bfvm = bfvm_new(&iob);
170  if (!mal->bfvm) {
171  free(mal);
172  return NULL;
173  }
174  size_t rlen;
175  out = rz_file_slurp(pathname + 8, &rlen);
176  if (!out || rlen < 1) {
177  free(mal);
178  free(out);
179  return NULL;
180  }
181  mal->size = (ut32)rlen;
182  mal->buf = malloc(mal->size + 1);
183  if (mal->buf != NULL) {
184  memcpy(mal->buf, out, rlen);
185  free(out);
187  pathname, rw, mode, mal);
188  }
189  eprintf("Cannot allocate (%s) %" PFMT32u " byte(s)\n",
190  pathname + 9, mal->size);
191  free(mal);
192  free(out);
193  }
194  return NULL;
195 }
196 
198  .name = "bfdbg",
199  .desc = "Attach to brainfuck Debugger instance",
200  .license = "LGPL3",
201  .uris = "bfdbg://",
202  .open = __open,
203  .close = __close,
204  .read = __read,
205  .check = __plugin_open,
206  .lseek = __lseek,
207  .write = __write,
208 };
209 
210 #ifndef RZ_PLUGIN_INCORE
212  .type = RZ_LIB_TYPE_IO,
213  .data = &rz_io_plugin_bfdbg,
215 };
216 #endif
RZ_API BfvmCPU * bfvm_new(RzIOBind *iob)
Definition: bfvm.c:67
RZ_API BfvmCPU * bfvm_free(BfvmCPU *c)
Definition: bfvm.c:74
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define NULL
Definition: cris-opc.c:27
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
static int is_in_screen(ut64 off, BfvmCPU *c)
Definition: io_bfdbg.c:26
#define RzIOBFDBG_BUF(x)
Definition: io_bfdbg.c:24
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_bfdbg.c:84
#define RZ_API
Definition: io_bfdbg.c:10
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
Definition: io_bfdbg.c:151
#define RzIOBFDBG_SZ(x)
Definition: io_bfdbg.c:23
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
Definition: io_bfdbg.c:159
RZ_API RzLibStruct rizin_plugin
Definition: io_bfdbg.c:211
RzIOPlugin rz_io_plugin_bfdbg
Definition: io_bfdbg.c:197
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_bfdbg.c:38
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_bfdbg.c:142
static int is_in_base(ut64 off, BfvmCPU *c)
Definition: io_bfdbg.c:34
static int __close(RzIODesc *fd)
Definition: io_bfdbg.c:130
static int getmalfd(RzIOBfdbg *mal)
Definition: io_bfdbg.c:155
static int is_in_input(ut64 off, BfvmCPU *c)
Definition: io_bfdbg.c:30
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
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
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
int n
Definition: mipsasm.c:19
int off
Definition: pal.c:13
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
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 void rz_io_bind(RzIO *io, RzIOBind *bnd)
Definition: io.c:550
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT32u
Definition: rz_types.h:409
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_VERSION
Definition: rz_version.h:8
static int
Definition: sfsocketcall.h:114
#define c(i)
Definition: sha256.c:43
ut8 * buf
Definition: io_bfdbg.c:17
BfvmCPU * bfvm
Definition: io_bfdbg.c:19
ut32 magic
Definition: io_bfdbg.c:15
int fd
Definition: io_bfdbg.c:16
ut32 size
Definition: io_bfdbg.c:18
int input_size
Definition: bfvm.h:34
int screen_size
Definition: bfvm.h:30
ut64 base
Definition: bfvm.h:25
ut64 input
Definition: bfvm.h:32
ut8 * mem
Definition: bfvm.h:26
ut64 screen
Definition: bfvm.h:28
ut8 * screen_buf
Definition: bfvm.h:31
ut8 * input_buf
Definition: bfvm.h:35
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
static struct @626 mal
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
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)