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
Enjoy!