Radare2 allows not only to browse and analyze programs, but also to debug them. There are a huge amount of commands and developers continue to work on it.
To run radare2 in debug mode, use -d option.
Let’s download the training program and make it executable:
cd /tmp wget https://github.com/wapiflapi/exrs/raw/master/reverse/r1 chmod +x ./r1
Now run this program in debug mode of radare2. Use -d option and the program name, pass some argument because r1 (our reversing program) requires it (this is a password we need to find out):
r2 -d ./r1 argument
We are in radare2 commandline. To see all debug-specific commands, use d? command:
d? # List of debug commands ... db[?] Breakpoints commands dc[?] Continue execution dm[?] Show memory maps dr[?] Cpu registers ds[?] Step, over, source line ... And more
Breakpoint allows us to stop a program execution when it is reached. Let’s set a breakpoint on main function. This is the first function of a program, after the initialization of additional libraries which are specific for operating system:
db? # Breakpoints commands db main # Set breakpoint on main function
Now we need to run the program until this breakpoint:
dc? # Execution continuation commands dc # Continue execution until breakpoint
We are in main function. To see a program code, it is better to enter the visual mode. Type ‘V’ and press p/P to switch between visual modes:
V # Enter Visual mode, press p/P to switch between visual modes
As we can see, here is a simple code without other prompts. It is possible for radare2 to analyze the program code and name the functions and references.
To analyze the program without leaving the visual mode, press : ,then type ‘aaa‘ and press [Enter]. After analysis press [Enter] in a empty commandlime to return to the visual mode:
Now there are more tips, there are names of functions and references. This really simplifies work in radare2.
Note, at the very beginning of main function rsi register contains a pointer to argv array (it contains all argument strings passed to a program). This pointer is placed in var_10h variable (rbp-0x10 address, located in programs stack) – see tips on the image above.
This is the most comfortable visual mode for working in radare2 debug mode. At each step in debugger, the registers visually change their values and are highlighted after:
argc contains the number of arguments that were passed to a program. argc value is placed in var_4h variable (see the image below). Then it is compared with 2. This means that the program must contain two arguments – the name by which it was called and password:
To step on the next instruction press ‘s‘ key being in Visual mode. Make steps until we reach the instruction as on the image above.
Now we can look inside argv and see all the pointers it contains. By using  we automatically follow the address contained in rbp-0x10: rbp-0x10 content -> 8-byte reference -> content:
pxr @ [rbp-0x10] # rbp-0x10 is var_10h value. Note, usage of '0x' is really necessary!
So, argc stores the number of arguments passed exactly by the user, and not by the environment. After user arguments a null pointer follows, and then the environment variables.
Continue to step the instructions, there will be a jump. Scroll down until we see this picture:
Here the second argument of argv is moved (the address to our password string) to rdi register in order to pass it to compare_pwd function (this function checks our password).
There is a way not to walk all instructions and move right before function call, use dcc command:
dc? # Execution continuation commands dcc # Continue until call
Then make a step and we are in password verifying function:
Radare2 already shows us a string with a password and its address. A password passed by us is compares with this string, and if they are equivalent, the program says that the password has been entered correctly.
Strings that are used with C functions must be \x00-terminated, so that C functions know where the string ends. Use password string address and psz command:
psz @ 0x4006d8 # Print zero-terminated string. ... my_password_to_easy
OK, what if we want to give the program the correct password right now, without leaving radare2?
So, we are right on the following instruction, right before string comparison function: