After some googling and testing, I have compiled a list of commands that enabled me to look deeply into the code and get useful information. I intend to update this list while I’m learning new commands.
r2 -Ad ./crackme0x01 Opens r2 in debug mode with the Analyze all flag active Note: If I hadn't passed A flag, aa would be the first command to execute after running Radare
First of all, let me state that it’s always possible to use ? to list all commands available as well as use it at the end of every command to get more information about it.
? Used alone, lists all the commands available Used at the end of a command, shows a brief description about it (eg. afl?)
So, to start exploring an executable is always good idea list all the present functions, using afll. One can also use just afl which is not as verbose as afll.
afll Lists all functions and their location in memory
It’s possible to use afvd for variables.
afvd Shows the content of all local/args variables
When the time to set breakpoints come, one can use db command.
db 0x12345678 Sets a breakpoint at address 0x12345678. It's possible to set more than one breakpoint
To run the executable and stop at a breakpoint, I can use dc.
dc Runs the program until it hits a breakpoint
If the program is stopped at a breakpoint I can use dr to display the registers.
dr Shows the content of all registers. Use dr <register> for a specific register
You can also use the “telescoping” method.
drr Shows the content of all registers and the registers references.
To execute a single instruction, use ds.
ds Steps a single instruction
If I was looking for the “low hanging fruit” iz would be a good command to start.
iz Shows the strings present in the data section One can use izz to see the strings for the entire binary
To explore the code of the function that I sought to, I can use pdf which will display the code of that function. You can also use pdf @ sym.main (which means something like “show me the main function without seek to it”) .
pdf "Print Disassembling Function"
It’s also possible to print the content of a memory cell with pf.
pf Prints formatted data. Use pf?? to see available formats and pf??? for examples
To see raw data from some memory address, use px.
px 3 @0x08080808 Prints hexadecimal dump (3 bytes) from 0x08080808 address.
Now that the location of all functions is known, I can seek to one of those functions with the s command. It’s always a very good habit to type ? after a command to see all the options available.
s sym.main Seeks to function sym.main. Address in prompt will change
To edit the program an write instructions, use wa.
wa nop @ 0x08080808 Writes a nop instruction at 0x08080808 address. Note: The program must be started with w flag
Instead of instructions, it’s possible to write opcodes.
wx 90 @ 0x08080808 Writes the opcode 90 (nop) at 0x08080808 address.
The ? command is an interesting feature, I must confess. Apart of all the use described above, one can use it also to convert a value to another base.
? 0x10 Converts the number 0x10 to the most common bases
With all the previous commands we can perform some basic debugging. Somewhere in time I’ll write a similar post with an introduction for the Visual mode that I ended up discovering. In that mode, one can do all the tasks described previously with much less pain.