16.1.2 Basic blocks

A basic block is cosidered a sequence of opcodes ended up by a jump/branch/ret instruction. Radare allows you to determine which kind of basic block splitting you want to use to have a more personalized way to read the code and be able to split the functions as basic blocks for example.

Use these variables to configure how the code analysis should work to determine basic blocks:

graph.jmpblocks = true
graph.refblocks = false
graph.callblocks = false
graph.flagblocks = true

The 'ab' command will look for a basic block definition starting at current seek:

[0xB7FC4810]> ab
offset = 0xb7fc4810
type = head
size = 73
call0 = 0xb7fc4a60
call1 = 0xb7fc4800
call2 = 0xb7fd1a40
n_calls = 3
bytes = 89 e0 e8 49 02 00 00 89 c7 e8 e2 ff ff ff ...

The output is quite parsing friendly, so you can easily use the python API to extract this information:

[0xB7F14810]> H python
python> block = radare.analyze_block()
python> print "This basic block have %d calls.\n" % radare.block['n_calls']

This basic block have 3 calls.

python> print "Its size is %d bytes.\n" % block['size']

Its size is 74 bytes

There's a human friendly version of 'ab' called 'ac' which stands for 'analyze code'. It accepts a numeric argument to determine the depth level when performing the basic block analysis.

[0xB7F93A60]> ac 10
0xb7f93a60 (0) -> 0xb7f93ae1, 0xb7f93a99
         0xB7F93A60,       eip:   push ebp         
         0xB7F93A61               ebp = esp        
         0xB7F93A63               push edi         
         ...
         0xB7F93A8F               [ebx+0x2b4] = eax
         0xB7F93A95               test edx, edx
         0xB7F93A97             v jz 0xB7F93AE1      ; 2 = eip+0x7b

0xb7f93ae1 (0) -> 0xb7f93b53, 0xb7f93aeb
         0xB7F93AE1               edx = [ebx+0x2ac]
         0xB7F93AE7               test edx, edx
         0xB7F93AE9             v jz 0xB7F93B53      ; 1 

0xb7f93b53 (0) -> 0xb7f93b67, 0xb7f93b5d
         0xB7F93B53               eax = [ebx+0x31c]
         0xB7F93B59               test eax, eax
    .==< 0xB7F93B5B             v jz 0xB7F93B67      ; 1 = eip+0x107

0xb7f93b67 (0) -> 0xb7f93b81, 0xb7f93b71
         0xB7F93B67               eax = [ebx+0x310]
         0xB7F93B6D               test eax, eax
    .==< 0xB7F93B6F             v jz 0xB7F93B81      ; 1 = eip+0x121
         ...

The values shown are:

address (0) -> true-jump, false-jump