Skip to content

Commit 6880cb4

Browse files
authored
add iH support for for bf (#5943)
1 parent 95f94ae commit 6880cb4

File tree

2 files changed

+125
-8
lines changed

2 files changed

+125
-8
lines changed

librz/bin/p/bin_bf.c

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include <rz_lib.h>
77
#include <rz_bin.h>
88

9+
#define BF_DATA_AREA_VADDR 0x10000
10+
#define BF_DATA_AREA_SIZE 30000
11+
912
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
1013
return true;
1114
}
@@ -138,15 +141,108 @@ static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
138141
return NULL;
139142
}
140143
map->paddr = 0;
141-
map->vaddr = 0x10000;
144+
map->vaddr = BF_DATA_AREA_VADDR;
142145
map->psize = 0;
143-
map->vsize = 30000;
146+
map->vsize = BF_DATA_AREA_SIZE;
144147
map->perm = RZ_PERM_RW;
145148
map->name = rz_str_dup("mem");
146149
rz_pvector_push(ret, map);
147150
return ret;
148151
}
149152

153+
typedef struct {
154+
ut64 increment;
155+
ut64 decrement;
156+
ut64 move_right;
157+
ut64 move_left;
158+
ut64 loop_start;
159+
ut64 loop_end;
160+
ut64 input;
161+
ut64 output;
162+
} BfInstrStats;
163+
164+
static void bf_count_instructions(RzBinFile *bf, BfInstrStats *stats) {
165+
if (!bf->buf) {
166+
return;
167+
}
168+
169+
ut64 size = rz_buf_size(bf->buf);
170+
for (ut64 i = 0; i < size; i++) {
171+
ut8 c;
172+
if (rz_buf_read_at(bf->buf, i, &c, 1) != 1) {
173+
break;
174+
}
175+
switch (c) {
176+
case '+': stats->increment++; break;
177+
case '-': stats->decrement++; break;
178+
case '>': stats->move_right++; break;
179+
case '<': stats->move_left++; break;
180+
case '[': stats->loop_start++; break;
181+
case ']': stats->loop_end++; break;
182+
case ',': stats->input++; break;
183+
case '.': stats->output++; break;
184+
default: break;
185+
}
186+
}
187+
}
188+
189+
static void bf_structure_add_instructions(RzStructuredData *parent, const BfInstrStats *stats) {
190+
RzStructuredData *instr = rz_structured_data_map_add_map(parent, "instructions");
191+
if (!instr) {
192+
return;
193+
}
194+
195+
rz_structured_data_map_add_unsigned(instr, "increment", stats->increment, false);
196+
rz_structured_data_map_add_unsigned(instr, "decrement", stats->decrement, false);
197+
rz_structured_data_map_add_unsigned(instr, "move_right", stats->move_right, false);
198+
rz_structured_data_map_add_unsigned(instr, "move_left", stats->move_left, false);
199+
rz_structured_data_map_add_unsigned(instr, "loop_start", stats->loop_start, false);
200+
rz_structured_data_map_add_unsigned(instr, "loop_end", stats->loop_end, false);
201+
rz_structured_data_map_add_unsigned(instr, "input", stats->input, false);
202+
rz_structured_data_map_add_unsigned(instr, "output", stats->output, false);
203+
}
204+
205+
static void bf_structure_add_memory_layout(RzStructuredData *parent) {
206+
RzStructuredData *mem = rz_structured_data_map_add_map(parent, "memory");
207+
if (!mem) {
208+
return;
209+
}
210+
211+
rz_structured_data_map_add_unsigned(mem, "data_area", BF_DATA_AREA_VADDR, true);
212+
rz_structured_data_map_add_unsigned(mem, "data_size", BF_DATA_AREA_SIZE, false);
213+
}
214+
215+
static RzStructuredData *bf_structure(RzBinFile *bf) {
216+
rz_return_val_if_fail(bf, NULL);
217+
218+
RzStructuredData *info = rz_structured_data_new_map();
219+
if (!info) {
220+
return NULL;
221+
}
222+
223+
RzStructuredData *root = rz_structured_data_map_add_map(info, "bf");
224+
if (!root) {
225+
rz_structured_data_free(info);
226+
return NULL;
227+
}
228+
229+
rz_structured_data_map_add_unsigned(root, "file_size", bf->size, false);
230+
rz_structured_data_map_add_unsigned(root, "entry_point", 0, true);
231+
232+
BfInstrStats stats = { 0 };
233+
bf_count_instructions(bf, &stats);
234+
235+
ut64 total = stats.increment + stats.decrement + stats.move_right +
236+
stats.move_left + stats.loop_start + stats.loop_end +
237+
stats.input + stats.output;
238+
rz_structured_data_map_add_unsigned(root, "total_instructions", total, false);
239+
240+
bf_structure_add_instructions(root, &stats);
241+
bf_structure_add_memory_layout(root);
242+
243+
return info;
244+
}
245+
150246
RzBinPlugin rz_bin_plugin_bf = {
151247
.name = "bf",
152248
.desc = "Brainfuck",
@@ -161,6 +257,7 @@ RzBinPlugin rz_bin_plugin_bf = {
161257
.strings = &strings,
162258
.maps = &maps,
163259
.info = &info,
260+
.bin_structure = &bf_structure,
164261
};
165262

166263
#ifndef RZ_PLUGIN_INCORE

test/db/formats/bf

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
NAME=bf with comments
1+
NAME=bf with comments and 30,000 nulls
22
FILE=bins/bf/2+5.bf
3-
CMDS=i~^format
3+
CMDS=<<EOF
4+
i~^format
5+
ol~null
6+
EOF
47
EXPECT=<<EOF
58
format bf
9+
4 - rw- 0x00007530 null://30000
610
EOF
711
RUN
812

@@ -19,10 +23,26 @@ size 0x2af
1923
EOF
2024
RUN
2125

22-
NAME=30,000 nulls
23-
FILE=bins/bf/2+5.bf
24-
CMDS=ol~null
26+
NAME=bf iH
27+
FILE=bins/bf/hello-ok.bf
28+
CMDS=iH
2529
EXPECT=<<EOF
26-
4 - rw- 0x00007530 null://30000
30+
bf:
31+
file_size: 111
32+
entry_point: 0x0
33+
total_instructions: 111
34+
instructions:
35+
increment: 65
36+
decrement: 15
37+
move_right: 10
38+
move_left: 6
39+
loop_start: 1
40+
loop_end: 1
41+
input: 0
42+
output: 13
43+
memory:
44+
data_area: 0x10000
45+
data_size: 30000
46+
2747
EOF
2848
RUN

0 commit comments

Comments
 (0)