Rizin
unix-like reverse engineering framework and cli tools
debug_bf.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_debug.h>
5 #undef RZ_API
6 #define RZ_API static inline
7 #include "bfvm.c"
8 
9 typedef struct {
10  int desc;
11  ut8 *buf;
14 } RzIOBdescbg;
15 
16 struct bfvm_regs {
26 };
27 
28 static struct bfvm_regs r;
29 
30 static bool is_io_bf(RzDebug *dbg) {
31  RzIODesc *d = dbg->iob.io->desc;
32  if (d && d->plugin && d->plugin->name) {
33  if (!strcmp("bfdbg", d->plugin->name)) {
34  return true;
35  }
36  }
37  eprintf("error: the iodesc data is not brainfuck friendly\n");
38  return false;
39 }
40 
42  RzIOBdescbg *o = dbg->iob.io->desc->data;
43  int op, oop = 0;
44  for (;;) {
45  op = bfvm_op(o->bfvm);
46  if (oop != 0 && op != oop) {
47  break;
48  }
49  if (bfvm_in_trap(o->bfvm)) {
50  break;
51  }
52  bfvm_step(o->bfvm, 0);
53  oop = op;
54  }
55  return true;
56 }
57 
59  RzIOBdescbg *o = dbg->iob.io->desc->data;
60  bfvm_step(o->bfvm, 0);
61  return true;
62 }
63 
64 static int rz_debug_bf_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
65  rz_return_val_if_fail(dbg && buf && size > 0, -1);
66  if (!is_io_bf(dbg)) {
67  return 0;
68  }
69  if (!(dbg->iob.io) || !(dbg->iob.io->desc) || !(dbg->iob.io->desc->data)) {
70  return 0;
71  }
72  RzIOBdescbg *o = dbg->iob.io->desc->data;
73  r.pc = o->bfvm->eip;
74  r.ptr = o->bfvm->ptr;
75  r.sp = o->bfvm->esp;
76  r.scr = o->bfvm->screen;
77  r.scri = o->bfvm->screen_idx;
78  r.inp = o->bfvm->input;
79  r.inpi = o->bfvm->input_idx;
80  r.mem = o->bfvm->base;
81  r.memi = o->bfvm->ptr;
82  memcpy(buf, &r, sizeof(r));
83  // rz_io_system (dbg->iob.io, "dr");
84  return sizeof(r);
85 }
86 
87 static int rz_debug_bf_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
88  if (!dbg) {
89  return false;
90  }
91  if (!is_io_bf(dbg)) {
92  return 0;
93  }
94  if (!(dbg->iob.io) || !(dbg->iob.io->desc) || !(dbg->iob.io->desc->data)) {
95  return 0;
96  }
97  RzIOBdescbg *o = dbg->iob.io->desc->data;
98  memcpy(&r, buf, sizeof(r));
99  o->bfvm->eip = r.pc;
100  o->bfvm->ptr = r.ptr; // dup
101  o->bfvm->esp = r.sp;
102  o->bfvm->screen = r.scr;
103  o->bfvm->screen_idx = r.scri;
104  o->bfvm->input = r.inp;
105  o->bfvm->input_idx = r.inpi;
106  o->bfvm->base = r.mem;
107  o->bfvm->ptr = r.memi; // dup
108  return true;
109 }
110 
111 static int rz_debug_bf_continue(RzDebug *dbg, int pid, int tid, int sig) {
112  RzIOBdescbg *o = dbg->iob.io->desc->data;
113  bfvm_cont(o->bfvm, UT64_MAX);
114  return true;
115 }
116 
118  RzIOBdescbg *o = dbg->iob.io->desc->data;
119  bfvm_contsc(o->bfvm);
120  return true;
121 }
122 
124  /* do nothing */
125  return RZ_DEBUG_REASON_NONE;
126 }
127 
128 static int rz_debug_bf_attach(RzDebug *dbg, int pid) {
129  if (!is_io_bf(dbg)) {
130  return false;
131  }
132  return true;
133 }
134 
135 static int rz_debug_bf_detach(RzDebug *dbg, int pid) {
136  // reset vm?
137  return true;
138 }
139 
141  return strdup(
142  "=PC pc\n"
143  "=SP esp\n"
144  "=BP ptr\n"
145  "=A0 mem\n"
146  "gpr pc .32 0 0\n"
147  "gpr ptr .32 4 0\n"
148  "gpr esp .32 8 0\n"
149  "gpr scr .32 12 0\n"
150  "gpr scri .32 16 0\n"
151  "gpr inp .32 20 0\n"
152  "gpr inpi .32 24 0\n"
153  "gpr mem .32 28 0\n"
154  "gpr memi .32 32 0\n");
155 }
156 
157 static int rz_debug_bf_breakpoint(struct rz_bp_t *bp, RzBreakpointItem *b, bool set) {
158  // rz_io_system (dbg->iob.io, "db");
159  return false;
160 }
161 
162 static bool rz_debug_bf_kill(RzDebug *dbg, int pid, int tid, int sig) {
163  if (!is_io_bf(dbg)) {
164  return false;
165  }
166  RzIOBdescbg *o = dbg->iob.io->desc->data;
167  if (o) {
168  bfvm_reset(o->bfvm);
169  }
170  return true;
171 }
172 
174  if (!is_io_bf(dbg)) {
175  return false;
176  }
177  RzIOBdescbg *o = dbg->iob.io->desc->data;
178  BfvmCPU *c = o->bfvm;
180  if (!list) {
181  return NULL;
182  }
183  rz_list_append(list, rz_debug_map_new("code", 0, 4096, 6, 0));
184  rz_list_append(list, rz_debug_map_new("memory", c->base, c->base + c->size, 6, 0));
185  rz_list_append(list, rz_debug_map_new("screen", c->screen, c->screen + c->screen_size, 6, 0));
186  rz_list_append(list, rz_debug_map_new("input", c->input, c->input + c->input_size, 6, 0));
187  return list;
188 }
189 
191  if (!is_io_bf(dbg)) {
192  return false;
193  }
194  RzIOBdescbg *o = dbg->iob.io->desc->data;
195  BfvmCPU *c = o->bfvm;
196  c->breaked = true;
197  return true;
198 }
199 
201  .name = "bf",
202  .arch = "bf",
203  .license = "LGPL3",
204  .bits = RZ_SYS_BITS_32 | RZ_SYS_BITS_64,
205  .step = rz_debug_bf_step,
206  .step_over = rz_debug_bf_step_over,
207  .cont = rz_debug_bf_continue,
209  .attach = &rz_debug_bf_attach,
210  .detach = &rz_debug_bf_detach,
211  .wait = &rz_debug_bf_wait,
212  .stop = rz_debug_bf_stop,
213  .kill = rz_debug_bf_kill,
214  .breakpoint = &rz_debug_bf_breakpoint,
215  .reg_read = &rz_debug_bf_reg_read,
216  .reg_write = &rz_debug_bf_reg_write,
217  .reg_profile = rz_debug_bf_reg_profile,
218  .map_get = rz_debug_native_map_get,
219 };
220 
221 #ifndef RZ_PLUGIN_INCORE
224  .data = &rz_debug_plugin_bf,
226 };
227 #endif
ut8 op
Definition: 6502dis.c:13
RZ_API int bfvm_in_trap(BfvmCPU *c)
Definition: bfvm.c:15
RZ_API void bfvm_reset(BfvmCPU *c)
Definition: bfvm.c:25
RZ_API int bfvm_cont(BfvmCPU *c, ut64 until)
Definition: bfvm.c:255
static ut8 bfvm_op(BfvmCPU *c)
Definition: bfvm.c:6
RZ_API int bfvm_contsc(BfvmCPU *c)
Definition: bfvm.c:233
RZ_API int bfvm_step(BfvmCPU *c, int over)
Definition: bfvm.c:180
#define NULL
Definition: cris-opc.c:27
static RzList * rz_debug_native_map_get(RzDebug *dbg)
Definition: debug_bf.c:173
RzDebugPlugin rz_debug_plugin_bf
Definition: debug_bf.c:200
static RzDebugReasonType rz_debug_bf_wait(RzDebug *dbg, int pid)
Definition: debug_bf.c:123
static int rz_debug_bf_step(RzDebug *dbg)
Definition: debug_bf.c:58
static int rz_debug_bf_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size)
Definition: debug_bf.c:87
#define RZ_API
Definition: debug_bf.c:6
static int rz_debug_bf_detach(RzDebug *dbg, int pid)
Definition: debug_bf.c:135
static struct bfvm_regs r
Definition: debug_bf.c:28
static int rz_debug_bf_step_over(RzDebug *dbg)
Definition: debug_bf.c:41
static int rz_debug_bf_attach(RzDebug *dbg, int pid)
Definition: debug_bf.c:128
static bool is_io_bf(RzDebug *dbg)
Definition: debug_bf.c:30
RZ_API RzLibStruct rizin_plugin
Definition: debug_bf.c:222
static int rz_debug_bf_stop(RzDebug *dbg)
Definition: debug_bf.c:190
static int rz_debug_bf_reg_read(RzDebug *dbg, int type, ut8 *buf, int size)
Definition: debug_bf.c:64
static int rz_debug_bf_continue(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_bf.c:111
static bool rz_debug_bf_kill(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_bf.c:162
static int rz_debug_bf_continue_syscall(RzDebug *dbg, int pid, int num)
Definition: debug_bf.c:117
static int rz_debug_bf_breakpoint(struct rz_bp_t *bp, RzBreakpointItem *b, bool set)
Definition: debug_bf.c:157
static char * rz_debug_bf_reg_profile(RzDebug *dbg)
Definition: debug_bf.c:140
uint32_t ut32
RzDebug * dbg
Definition: desil.c:30
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
RZ_API RzDebugMap * rz_debug_map_new(char *name, ut64 addr, ut64 addr_end, int perm, int user)
Definition: dmap.c:7
voidpf void uLong size
Definition: ioapi.h:138
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))
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
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 static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
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 pid
Definition: sflib.h:64
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")
int type
Definition: mipsasm.c:17
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_NONE
Definition: rz_debug.h:91
@ RZ_LIB_TYPE_DBG
Definition: rz_lib.h:70
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
ut32 size
Definition: debug_bf.c:12
ut8 * buf
Definition: debug_bf.c:11
BfvmCPU * bfvm
Definition: debug_bf.c:13
int desc
Definition: debug_bf.c:10
ut64 esp
Definition: bfvm.h:21
int input_idx
Definition: bfvm.h:33
ut64 base
Definition: bfvm.h:25
ut64 input
Definition: bfvm.h:32
ut64 eip
Definition: bfvm.h:20
ut64 screen
Definition: bfvm.h:28
int screen_idx
Definition: bfvm.h:29
int ptr
Definition: bfvm.h:22
ut32 memi
Definition: debug_bf.c:25
ut32 inpi
Definition: debug_bf.c:23
ut32 ptr
Definition: debug_bf.c:18
ut32 sp
Definition: debug_bf.c:19
ut32 scr
Definition: debug_bf.c:20
ut32 inp
Definition: debug_bf.c:22
ut32 scri
Definition: debug_bf.c:21
ut32 pc
Definition: debug_bf.c:17
ut32 mem
Definition: debug_bf.c:24
Definition: rz_bp.h:78
const char * version
Definition: rz_debug.h:362
const char * name
Definition: rz_debug.h:359
RzIOBind iob
Definition: rz_debug.h:293
RzIO * io
Definition: rz_io.h:232
void * data
Definition: rz_io.h:102
struct rz_io_desc_t * desc
Definition: rz_io.h:60
Definition: dis.c:32