21.1 Debugging brainfuck

The 'bfdbg' IO plugin offers a debugging interface for a brainfuck virtual machine implemented inside the same plugin. Rabin can magically autodetect brainfuck files, so the 'e asm.arch=bf' will be defined if you use 'e file.id=true' in your ~/.radarerc.

The brainfuck disassembler decodes the bf instructions as complex instructions supporting repetitions. The translation would be:

+++++   ->   add [ptr], 5

Also loops are automatically detected between the '[' ']' opcodes, so the code analysis will show nice jump lines there:

[0x00000000]> pd
     0x00000000       3e              > inc [ptr]
     0x00000001       2b2b2b2b2b2b2b. + add [ptr], 9
.--> 0x0000000A  eip: 5b              [ loop {
|    0x0000000B       3c              < dec [ptr]
|    0x0000000C,      2b2b2b2b2b2b2b. + add [ptr], 8
|    0x00000014,      3e              > inc [ptr]
|    0x00000015       2d              - dec [ptr]
`==< 0x00000016       5d              ] }  ; 1 = 0x0000000a

The BF virtual machine supports user input and screen output emulating two virtual buffers located at 0x10000 for the 'input' section and 0x50000 for the 'screen'. Here's a 'hello.bf' example:

$ radare bfdbg://hello.bf
File type: Brainfuck
[0x00000000]> !!cat hello.bf
>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.

[0x00000000]> pz @ screen

[0x00000000]> !cont
Trap instruction at 0x000000b5

[0x00000000]> pz @ screen
Hello world!

You can query the section information using the !maps command:

[0x00000000]> !maps
0x00000000 - 0xffffffff rwxu 0xffffffff .code
0x000d0000 - 0x000dffff rw-- 0x0000ffff .data
0x00050000 - 0x00051000 rw-- 0x00001000 .screen
0x00010000 - 0x00011000 rw-- 0x00001000 .input

For getting/setting registers use the '!reg' command:

[0x00000000]> !reg
  eip  0x000000b5     esp  0x000d0000
  ptr  0x00000000     [ptr]  10 = 0x0a ' '

[0x00000000]> !reg eip 0
[0x00000000]> !reg
  eip  0x00000000     esp  0x000d0000
  ptr  0x00000000     [ptr]  10 = 0x0a ' '

The help for all the debugger commands is:

[0x00000000]> !help
Brainfuck debugger help:
20!step       ; perform 20 steps
!step         ; perform a step
!stepo        ; step over rep instructions
!maps         ; show registers
!reg          ; show registers
!cont [addr]  ; continue until address or ^C
!trace [addr] ; trace code execution
!contsc       ; continue until write or read syscall
!reg eip 3    ; force program counter
.!reg*        ; adquire register information into core

So.. as a fast overview, see that you can step, or step over all repeated instructions, continue the execution until an address, trace the executed opcodes with data information (bytes peeked and poked) or trace until syscall.

Obviously all these commands can be used from the visual mode..so press 'V<enter>' in the radare prompt and use these keys:

F6 : continue until syscall
F7 : step instruction
F8 : step over repeated instructions
F9 : continue until trap or user ^C