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+
912static 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+
150246RzBinPlugin 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
0 commit comments