Rizin
unix-like reverse engineering framework and cli tools
bfvm.c File Reference
#include "bfvm.h"

Go to the source code of this file.

Macros

#define T   if (c->trace)
 

Functions

static ut8 bfvm_op (BfvmCPU *c)
 
RZ_API int bfvm_in_trap (BfvmCPU *c)
 
RZ_API void bfvm_reset (BfvmCPU *c)
 
RZ_API int bfvm_init (BfvmCPU *c, ut32 size, int circular)
 
RZ_API BfvmCPUbfvm_new (RzIOBind *iob)
 
RZ_API BfvmCPUbfvm_free (BfvmCPU *c)
 
RZ_API ut8bfvm_get_ptr_at (BfvmCPU *c, ut64 at)
 
RZ_API ut8bfvm_get_ptr (BfvmCPU *c)
 
RZ_API ut8 bfvm_get (BfvmCPU *c)
 
RZ_API void bfvm_inc (BfvmCPU *c)
 
RZ_API void bfvm_dec (BfvmCPU *c)
 
RZ_API int bfvm_reg_set (BfvmCPU *c, const char *str)
 
RZ_API void bfvm_peek (BfvmCPU *c)
 
RZ_API void bfvm_poke (BfvmCPU *c)
 
RZ_API int bfvm_trace_op (BfvmCPU *c, ut8 op)
 
RZ_API int bfvm_step (BfvmCPU *c, int over)
 
RZ_API int bfvm_contsc (BfvmCPU *c)
 
RZ_API int bfvm_cont (BfvmCPU *c, ut64 until)
 
RZ_API int bfvm_trace (BfvmCPU *c, ut64 until)
 
RZ_API void bfvm_show_regs (BfvmCPU *c, int rad)
 
RZ_API void bfvm_maps (BfvmCPU *c, int rad)
 

Macro Definition Documentation

◆ T

#define T   if (c->trace)

Definition at line 178 of file bfvm.c.

Function Documentation

◆ bfvm_cont()

RZ_API int bfvm_cont ( BfvmCPU c,
ut64  until 
)

Definition at line 255 of file bfvm.c.

255  {
256  c->breaked = 0;
257  while (!c->breaked && c->eip != until) {
258  bfvm_step(c, 0);
259  if (bfvm_in_trap(c)) {
260  eprintf("Trap instruction at 0x%" PFMT64x "\n", c->eip);
261  break;
262  }
263  }
264  return 0;
265 }
RZ_API int bfvm_in_trap(BfvmCPU *c)
Definition: bfvm.c:15
RZ_API int bfvm_step(BfvmCPU *c, int over)
Definition: bfvm.c:180
#define eprintf(x, y...)
Definition: rlcc.c:7
#define PFMT64x
Definition: rz_types.h:393
#define c(i)
Definition: sha256.c:43

References bfvm_in_trap(), bfvm_step(), c, eprintf, and PFMT64x.

Referenced by bfvm_trace(), and rz_debug_bf_continue().

◆ bfvm_contsc()

RZ_API int bfvm_contsc ( BfvmCPU c)

Definition at line 233 of file bfvm.c.

233  {
234  c->breaked = 0;
235  while (!c->breaked) {
236  bfvm_step(c, 0);
237  if (bfvm_in_trap(c)) {
238  eprintf("Trap instruction at 0x%08" PFMT64x "\n", c->eip);
239  break;
240  }
241  switch (bfvm_op(c)) {
242  case ',':
243  eprintf("contsc: read from input trap\n");
244  c->breaked = 1;
245  continue;
246  case '.':
247  eprintf("contsc: print to screen trap\n");
248  c->breaked = 1;
249  continue;
250  }
251  }
252  return 0;
253 }
static ut8 bfvm_op(BfvmCPU *c)
Definition: bfvm.c:6

References bfvm_in_trap(), bfvm_op(), bfvm_step(), c, eprintf, and PFMT64x.

Referenced by rz_debug_bf_continue_syscall().

◆ bfvm_dec()

RZ_API void bfvm_dec ( BfvmCPU c)

Definition at line 109 of file bfvm.c.

109  {
110  ut8 *mem = bfvm_get_ptr(c);
111  if (mem != NULL) {
112  mem[0]--;
113  }
114 }
RZ_API ut8 * bfvm_get_ptr(BfvmCPU *c)
Definition: bfvm.c:92
#define NULL
Definition: cris-opc.c:27
uint8_t ut8
Definition: lh5801.h:11
void * mem
Definition: libc.cpp:91

References bfvm_get_ptr(), c, mem, and NULL.

Referenced by bfvm_step().

◆ bfvm_free()

RZ_API BfvmCPU* bfvm_free ( BfvmCPU c)

Definition at line 74 of file bfvm.c.

74  {
75  free(c->mem);
76  c->mem = 0;
77  free(c->screen_buf);
78  c->screen_buf = 0;
79  free(c);
80  return NULL;
81 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References c, free(), and NULL.

Referenced by __close().

◆ bfvm_get()

RZ_API ut8 bfvm_get ( BfvmCPU c)

Definition at line 97 of file bfvm.c.

97  {
98  ut8 *ptr = bfvm_get_ptr(c);
99  return ptr ? *ptr : 0;
100 }

References bfvm_get_ptr(), and c.

Referenced by bfvm_poke(), bfvm_show_regs(), bfvm_step(), and bfvm_trace_op().

◆ bfvm_get_ptr()

RZ_API ut8* bfvm_get_ptr ( BfvmCPU c)

Definition at line 92 of file bfvm.c.

92  {
93  // return bfvm_cpu.mem;
94  return bfvm_get_ptr_at(c, c->ptr);
95 }
RZ_API ut8 * bfvm_get_ptr_at(BfvmCPU *c, ut64 at)
Definition: bfvm.c:83

References bfvm_get_ptr_at(), and c.

Referenced by bfvm_dec(), bfvm_get(), bfvm_inc(), and bfvm_peek().

◆ bfvm_get_ptr_at()

RZ_API ut8* bfvm_get_ptr_at ( BfvmCPU c,
ut64  at 
)

Definition at line 83 of file bfvm.c.

83  {
84  if (at >= c->base) {
85  at -= c->base;
86  } else if (at >= c->size) {
87  at = c->circular ? 0 : c->size - 1;
88  }
89  return c->mem + at;
90 }

References c.

Referenced by bfvm_get_ptr().

◆ bfvm_in_trap()

RZ_API int bfvm_in_trap ( BfvmCPU c)

Definition at line 15 of file bfvm.c.

15  {
16  switch (bfvm_op(c)) {
17  case 0x00:
18  case 0xcc:
19  case 0xff:
20  return 1;
21  }
22  return 0;
23 }

References bfvm_op(), and c.

Referenced by bfvm_cont(), bfvm_contsc(), and rz_debug_bf_step_over().

◆ bfvm_inc()

RZ_API void bfvm_inc ( BfvmCPU c)

Definition at line 102 of file bfvm.c.

102  {
103  ut8 *mem = bfvm_get_ptr(c);
104  if (mem != NULL) {
105  mem[0]++;
106  }
107 }

References bfvm_get_ptr(), c, mem, and NULL.

Referenced by bfvm_step().

◆ bfvm_init()

RZ_API int bfvm_init ( BfvmCPU c,
ut32  size,
int  circular 
)

Definition at line 39 of file bfvm.c.

39  {
40  memset(c, '\0', sizeof(BfvmCPU));
41 
42  /* data */
43  c->mem = (ut8 *)malloc(size);
44  if (!c->mem) {
45  return 0;
46  }
47  memset(c->mem, '\0', size);
48 
49  /* setup */
50  c->circular = circular;
51  c->size = size;
52 
53  // TODO: use RzBuffer or so here.. this is spagueti
54  /* screen */
55  c->screen = BFVM_SCREEN_ADDR;
56  c->screen_size = BFVM_SCREEN_SIZE;
57  c->screen_buf = (ut8 *)malloc(c->screen_size);
58  memset(c->screen_buf, '\0', c->screen_size);
59 
60  /* input */
61  c->input_size = BFVM_INPUT_SIZE;
62  c->input_buf = (ut8 *)malloc(c->input_size);
63  bfvm_reset(c);
64  return 1;
65 }
RZ_API void bfvm_reset(BfvmCPU *c)
Definition: bfvm.c:25
#define BFVM_SCREEN_ADDR
Definition: bfvm.h:10
#define BFVM_INPUT_SIZE
Definition: bfvm.h:13
#define BFVM_SCREEN_SIZE
Definition: bfvm.h:11
voidpf void uLong size
Definition: ioapi.h:138
return memset(p, 0, total)
void * malloc(size_t size)
Definition: malloc.c:123

References BFVM_INPUT_SIZE, bfvm_reset(), BFVM_SCREEN_ADDR, BFVM_SCREEN_SIZE, c, malloc(), and memset().

Referenced by bfvm_new().

◆ bfvm_maps()

RZ_API void bfvm_maps ( BfvmCPU c,
int  rad 
)

Definition at line 290 of file bfvm.c.

290  {
291  if (rad) {
292  eprintf("fs sections\n");
293  eprintf("e cmd.vprompt=px@screen\n");
294  eprintf("f section_code @ 0x%08" PFMT64x "\n", (ut64)BFVM_CODE_ADDR);
295  eprintf("f section_code_end @ 0x%08" PFMT64x "\n", (ut64)BFVM_CODE_ADDR + BFVM_CODE_SIZE);
296  eprintf("f section_data @ 0x%08" PFMT64x "\n", (ut64)c->base);
297  eprintf("f section_data_end @ 0x%08" PFMT64x "\n", (ut64)c->base + c->size);
298  eprintf("f screen @ 0x%08" PFMT64x "\n", (ut64)c->screen);
299  eprintf("f section_screen @ 0x%08" PFMT64x "\n", (ut64)c->screen);
300  eprintf("f section_screen_end @ 0x%08" PFMT64x "\n", (ut64)c->screen + c->screen_size);
301  eprintf("f input @ 0x%08" PFMT64x "\n", (ut64)c->input);
302  eprintf("f section_input @ 0x%08" PFMT64x "\n", (ut64)c->input);
303  eprintf("f section_input_end @ 0x%08" PFMT64x "\n", (ut64)c->input + c->input_size);
304  eprintf("fs *\n");
305  } else {
306  eprintf("0x%08" PFMT64x " - 0x%08" PFMT64x " rwxu 0x%08" PFMT64x " .code\n",
307  (ut64)0, (ut64)c->size, (ut64)c->size);
308  eprintf("0x%08" PFMT64x " - 0x%08" PFMT64x " rw-- 0x%08" PFMT64x " .data\n",
309  (ut64)c->base, (ut64)(c->base + c->size), (ut64)c->size);
310  eprintf("0x%08" PFMT64x " - 0x%08" PFMT64x " rw-- 0x%08" PFMT64x " .screen\n",
311  (ut64)c->screen, (ut64)(c->screen + c->screen_size), (ut64)c->screen_size);
312  eprintf("0x%08" PFMT64x " - 0x%08" PFMT64x " rw-- 0x%08" PFMT64x " .input\n",
313  (ut64)c->input, (ut64)(c->input + c->input_size), (ut64)c->input_size);
314  }
315 }
#define BFVM_CODE_ADDR
Definition: bfvm.h:16
#define BFVM_CODE_SIZE
Definition: bfvm.h:17
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References BFVM_CODE_ADDR, BFVM_CODE_SIZE, c, eprintf, PFMT64x, and ut64().

◆ bfvm_new()

RZ_API BfvmCPU* bfvm_new ( RzIOBind iob)

Definition at line 67 of file bfvm.c.

67  {
69  bfvm_init(c, 4096, 1);
70  memcpy(&c->iob, iob, sizeof(c->iob));
71  return c;
72 }
RZ_API int bfvm_init(BfvmCPU *c, ut32 size, int circular)
Definition: bfvm.c:39
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define RZ_NEW0(x)
Definition: rz_types.h:284

References bfvm_init(), c, memcpy(), and RZ_NEW0.

Referenced by __open().

◆ bfvm_op()

static ut8 bfvm_op ( BfvmCPU c)
static

Definition at line 6 of file bfvm.c.

6  {
7  // XXX: this is slow :(
8  ut8 buf[4] = { 0 };
9  if (c && c->iob.read_at && !c->iob.read_at(c->iob.io, c->eip, buf, 4)) {
10  return 0xff;
11  }
12  return buf[0];
13 }
voidpf void * buf
Definition: ioapi.h:138

References c.

Referenced by bfvm_contsc(), bfvm_in_trap(), bfvm_step(), and rz_debug_bf_step_over().

◆ bfvm_peek()

RZ_API void bfvm_peek ( BfvmCPU c)

Definition at line 132 of file bfvm.c.

132  {
133  int idx = c->input_idx;
134  ut8 *ptr = bfvm_get_ptr(c);
135 
136  if (idx >= c->input_size) {
137  idx = 0;
138  }
139 
140  if (ptr) {
141  *ptr = c->input_buf[idx];
142  c->input_idx = idx + 1;
143  }
144 }
int idx
Definition: setup.py:197

References bfvm_get_ptr(), c, and setup::idx.

Referenced by bfvm_step().

◆ bfvm_poke()

RZ_API void bfvm_poke ( BfvmCPU c)

Definition at line 146 of file bfvm.c.

146  {
147  int idx = c->screen_idx;
148  c->screen_buf[idx] = bfvm_get(c);
149  c->screen_idx = idx + 1;
150 }
RZ_API ut8 bfvm_get(BfvmCPU *c)
Definition: bfvm.c:97

References bfvm_get(), c, and setup::idx.

Referenced by bfvm_step().

◆ bfvm_reg_set()

RZ_API int bfvm_reg_set ( BfvmCPU c,
const char *  str 
)

Definition at line 116 of file bfvm.c.

116  {
117  char *ptr = strchr(str, ' ');
118  if (!ptr) {
119  return 0;
120  }
121  if (strstr(str, "eip")) {
122  c->eip = rz_num_math(NULL, ptr + 1);
123  } else if (strstr(str, "esp")) {
124  c->esp = rz_num_math(NULL, ptr + 1);
125  } else if (strstr(str, "ptr")) {
126  c->ptr = rz_num_math(NULL, ptr + 1);
127  }
128  return 1;
129 }
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456

References c, NULL, rz_num_math(), and cmd_descs_generate::str.

◆ bfvm_reset()

RZ_API void bfvm_reset ( BfvmCPU c)

Definition at line 25 of file bfvm.c.

25  {
26  memset(c->mem, '\0', c->size);
27  memset(c->input_buf, '\0', c->input_size);
28  memset(c->screen_buf, '\0', c->screen_size);
29  c->base = BFVM_DATA_ADDR;
30  c->input = BFVM_INPUT_ADDR;
31  c->input_idx = 0;
32  c->screen = BFVM_SCREEN_ADDR;
33  c->screen_idx = 0;
34  c->eip = 0; // TODO look forward nops
35  c->ptr = 0;
36  c->esp = c->base;
37 }
#define BFVM_INPUT_ADDR
Definition: bfvm.h:12
#define BFVM_DATA_ADDR
Definition: bfvm.h:14

References BFVM_DATA_ADDR, BFVM_INPUT_ADDR, BFVM_SCREEN_ADDR, c, and memset().

Referenced by bfvm_init(), and rz_debug_bf_kill().

◆ bfvm_show_regs()

RZ_API void bfvm_show_regs ( BfvmCPU c,
int  rad 
)

Definition at line 274 of file bfvm.c.

274  {
275  if (rad) {
276  eprintf("fs regs\n");
277  eprintf("f eip @ 0x%08" PFMT64x "\n", (ut64)c->eip);
278  eprintf("f esp @ 0x%08" PFMT64x "\n", (ut64)c->esp);
279  eprintf("f ptr @ 0x%08" PFMT64x "\n", (ut64)c->ptr + c->base);
280  eprintf("fs *\n");
281  } else {
282  ut8 ch = bfvm_get(c);
283  eprintf(" eip 0x%08" PFMT64x " esp 0x%08" PFMT64x "\n",
284  (ut64)c->eip, (ut64)c->esp);
285  eprintf(" ptr 0x%08x [ptr] %d = 0x%02x '%c'\n",
286  (ut32)c->ptr, ch, ch, IS_PRINTABLE(ch) ? ch : ' ');
287  }
288 }
uint32_t ut32
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10

References bfvm_get(), c, eprintf, IS_PRINTABLE, PFMT64x, and ut64().

◆ bfvm_step()

RZ_API int bfvm_step ( BfvmCPU c,
int  over 
)

Definition at line 180 of file bfvm.c.

180  {
181  ut8 op2, op = bfvm_op(c);
182 
183  do {
184  T bfvm_trace_op(c, op);
185  switch (op) {
186  case '\0':
187  /* trap */
188  return 1;
189  case '.':
190  // bfvm_get_ptr (c);
191  bfvm_poke(c);
192  break;
193  case ',':
194  bfvm_peek(c);
195  /* TODO read */
196  break;
197  case '+':
198  bfvm_inc(c);
199  break;
200  case '-':
201  bfvm_dec(c);
202  break;
203  case '>':
204  c->ptr++;
205  break;
206  case '<':
207  c->ptr--;
208  break;
209  case '[':
210  break;
211  case ']':
212  if (bfvm_get(c) != 0) {
213  do {
214  /* control underflow */
215  if (c->eip < (c->eip - 1)) {
216  c->eip = 0;
217  break;
218  }
219  c->eip--;
220  } while (bfvm_op(c) != '[');
221  }
222  break;
223  default:
224  break;
225  }
226  c->eip++;
227  op2 = bfvm_op(c);
228  } while (over && op == op2);
229 
230  return 0;
231 }
#define T
Definition: bfvm.c:178
RZ_API void bfvm_inc(BfvmCPU *c)
Definition: bfvm.c:102
RZ_API void bfvm_peek(BfvmCPU *c)
Definition: bfvm.c:132
RZ_API void bfvm_poke(BfvmCPU *c)
Definition: bfvm.c:146
RZ_API void bfvm_dec(BfvmCPU *c)
Definition: bfvm.c:109
RZ_API int bfvm_trace_op(BfvmCPU *c, ut8 op)
Definition: bfvm.c:152
Definition: dis.c:32

References bfvm_dec(), bfvm_get(), bfvm_inc(), bfvm_op(), bfvm_peek(), bfvm_poke(), bfvm_trace_op(), c, and T.

Referenced by bfvm_cont(), bfvm_contsc(), rz_debug_bf_step(), and rz_debug_bf_step_over().

◆ bfvm_trace()

RZ_API int bfvm_trace ( BfvmCPU c,
ut64  until 
)

Definition at line 267 of file bfvm.c.

267  {
268  c->trace = 1;
269  bfvm_cont(c, until);
270  c->trace = 0;
271  return 0;
272 }
RZ_API int bfvm_cont(BfvmCPU *c, ut64 until)
Definition: bfvm.c:255

References bfvm_cont(), and c.

◆ bfvm_trace_op()

RZ_API int bfvm_trace_op ( BfvmCPU c,
ut8  op 
)

Definition at line 152 of file bfvm.c.

152  {
153  ut8 g;
154  switch (op) {
155  case '\0':
156  eprintf(" ; trap (%02x)\n", op);
157  // fallthrough
158  case '.':
159  case ',':
160  case '+':
161  case '-':
162  case '>':
163  case '<':
164  eprintf("%c", op);
165  break;
166  case '[':
167  case ']':
168  g = bfvm_get(c);
169  eprintf("%c ; [ptr] = %d\n", op, g);
170  if (g != 0) {
171  eprintf("[");
172  }
173  break;
174  }
175  return 0;
176 }
struct @667 g

References bfvm_get(), c, eprintf, and g.

Referenced by bfvm_step().