The work on binary files makes the task of taking notes and defining information on top of the file quite important. Radare offers multiple ways to retrieve and adquire this information from many kind of file types.
Following some *nix principles becomes quite easy to write a small utility in shellscript that using objdump, otool, etc.. to get information from a binary and import it into radare just making echo's of the commands script.
You can have a look on one of the many 'rsc' scripts that are distributed with radare like 'idc2rdb':
$ cat src/rsc/pool/idc2rdb
while(<STDIN>) {
$str=$_;
if ($str=~/MakeName[^X]*.([^,]*)[^"]*.([^"]*)/) {
print "f idc_$2 @ 0x$1\n";
}
elsif ($str=~/MakeRptCmt[^X]*.([^,]*)[^"]*.([^"]*)/) {
$cmt = $2;
$off = $1;
$cmt=~s/\\n//g;
print "CC $cmt @ 0x$off\n";
}
}
This script is called with 'rsc idc2rdb < file.idc > file.rdb'. It reads an IDC file exported from an IDA database and imports the comments and the names of the functions.
We can import the 'file.rdb' using the '.' command of radare (similar to the shell):
[0x00000000]> . file.rdb
The command '.' is used to interpret data from external resources like files, programs, etc.. In the same way we can do the same without writing a file.
[0x00000000]> .!rsc idc2rdb < file.idc
The 'C' command is the one used to manage comments and data conversions. So you can define a range of bytes to be interpreted as code, or a string. It is also possible to define flags and execute code in a certain seek to fetch a comment from an external file or database.
Here's the help:
[0x4A13B8C0]> C?
Usage: C[op] [arg] <@ offset>
CC [-][comment] @ here - add/rm comment
CF [-][len] @ here - add/rm function
Cx [-][addr] @ here - add/rm code xref
CX [-][addr] @ here - add/rm data xref
Cm [num] [expr] ; define memory format (pm?)
Cc [num] ; converts num bytes to code
Cd [num] ; converts to data bytes
Cs [num] ; converts to string
Cf [num] ; folds num bytes
Cu [num] ; unfolds num bytes
C* ; list metadata database
For example, if you want to add a comment just type:
[0x00000000]> CC this guy seems legit @ 0x8048536
You can execute code inside the disassembly just placing a flag and assigning a command to it:
[0x00000000]> fc !regs @ eip
This way radare will show the registers of the cpu printing the opcode at the address where 'eip' points.
In the same way you can interpret structures or fetch information from external files. If you want to execute more than one command in a single address you will have to type them in a file and use the '.' command as explained before.
[0x00000000]> fc . script @ eip
The 'C' command allows us to change the type of data. The three basic types are: code (disassembly using asm.arch), data (byte array) or string.
In visual mode is easier to manage this because it is hooked to the 'd' key trying to mean 'data type change'. Use the cursor to select a range of bytes ('c' key to toggle cursor mode and HJKL to move with selection) and then press 'ds' to convert to string.
You can use the Cs command from the shell also:
[0x00000000]> pz 0x800
HelloWorld
[0x00000000]> f string_foo @ 0x800
[0x00000000]> Cs 10 @ string_foo
The folding/unfolding is quite premature but the idea comes from the 'folder' concepts in vim. So you can select a range of bytes in the disassembly view and press '<' to fold these bytes in a single line or '>' to unfold them. Just to ease the readability of the code.
The Cm
command is used to define a memory format string (the same used by the pm command). Here's a example:
[0x4A13B8C0]> Cm 16 2xi foo bar
[0x4A13B8C0]> pd
0x4A13B8C0, eip: (pm 2xi foo bar)
0x4a13b8c0 [0] {
foo : 0x4a13b8c0 = 0x39e8e089
bar : 0x4a13b8c4 = -1996488697
}
0x4a13b8c8 [1] {
foo : 0x4a13b8c8 = 0xffe2e8c7
bar : 0x4a13b8cc = -1014890497
}
.==< 0x4A13B927 7600 jbe 0x4a13b8c2 ; 1 = eip+0x69
`--> 0x4A13B929 8dbc2700000000 lea edi, [edi+0x0]
0x4A13B930, 55 push ebp
0x4A13B931 89e5 mov ebp, esp
This way it is possible to define structures by just using simple oneliners. See 'print memory' for more information.
All those C* commands can also be accessed from the visual mode by pressing 'd' (data conversion) key.