Getting started with Radare2

During the Boston Key Party, I decided to learn Radare2 the hard way. That means only to be allowed to use radare2 during the pown-ing exercises. In this article I'm writing down my experiences and encounterings with Radare2.

Radare2 is an excellent tool for reversing, and really enjoyed working with it. It is advised to always checkout the latest version from github.

Following the radare2 cheatsheet, I've configured my ~/.radare2rc with the following:

e cfg.fortunes=false  
e cfg.bigendian=true

# Show comments at right of disassembly if they fit in screen
e asm.cmtright=true

# Shows pseudocode in disassembly. Eg mov eax, str.ok = > eax = str.ok
e asm.pseudo = true

# Display stack and register values on top of disasembly view (visual mode)
e cmd.stack = true

# Solarized theme
eco solarized

# Use UTF-8 to show cool arrows that do not look like crap :)
e scr.utf8 = true  

Important to know about radare2 is that you've got inline documentation on every command. The documentation can be retrieved by just ending the command with an exclamation mark ?.

[0x004341b9]> P?
|Usage: P[?osi] [file]Project management
| Pc [file]    show project script to console
| Pd [file]    delete project
| Pi [file]    show project information
| Pl           list all projects
| Pn[j]        show project notes (Pnj for json)
| Pn [base64]  set notes text
| Pn -         edit notes with cfg.editor
| Po [file]    open project
| Ps [file]    save project
| NOTE:        See 'e file.project'
| NOTE:        project files are stored in ~/.config/radare2/projects

You can start radare2 with the binary using:

root@packer-vmware-iso /v/B/2/simple_calc# radare2 ./b28b103ea5f1171553554f0127696a18c6d2dcf7  

When reversing a binary, you first want to get some information about the executable. You can do this using i. It will show the following information:

[0x00400f4e]> i
type     EXEC (Executable file)  
file     ./b28b103ea5f1171553554f0127696a18c6d2dcf7  
fd       7  
size     0xd765a  
blksz    0x0  
mode     -r--  
block    0x100  
format   elf64  
pic      false  
canary   false  
nx       true  
crypto   false  
va       true  
bintype  elf  
class    ELF64  
lang     c  
arch     x86  
bits     64  
machine  AMD x86-64 architecture  
os       linux  
minopsz  1  
maxopsz  16  
pcalign  0  
subsys   linux  
endian   little  
stripped false  
static   true  
linenum  true  
lsyms    true  
relocs   true  
rpath    NONE  
binsz    882266  

This will tell us all relevant details about the binary. Now we want to analyze the complete file (using aaaa). Radare2 will find all functions, cross references, strings and sections which can be used and referenced to.

[0x00400f4e]> aaaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[0x00400596 esil_eq: invalid parametersences (aae)
0x004005a2 esil_eq: invalid parameters  
0x004007d3 esil_eq: invalid parameters  
0x0040081b esil_eq: invalid parameters  
.... shortened ....
[x] Emulate code to find computed references (aae)
[Analyzed 3 functions based on preludes
[x] Finding function by preludes (aap)
[x] Analyze consecutive function (aat)
[x] Construct a function name for all fcn.* (.afna @@ fcn.*)
fcns: 1140  
xref: 10719  
sect: 598452  
code: 653452  
covr: 109 %  

More information about the file:

  • iS: show all sections
  • izz: show all string references

I had some lesser experiences with the listen mode of rarun2, so I created the following profile. This profile allows my p0wn script to listen and communicate with the executable.

root@packer-vmware-iso /v/B/2/simple_calc# cat calc.rr2  
#!/usr/bin/rarun2
connect=127.0.0.1:4444  

Starting radare2 for debugging with the profile using the following command. Make sure you've got a listener active on port 4444, otherwise you'll get some errors.

root@packer-vmware-iso /v/B/2/simple_calc#  
radare2 -d ./b28b103ea5f1171553554f0127696a18c6d2dcf7 -e dbg.profile=calc.rr2  

Now you can use do to restart the executable, and dc to run. Within the radare shell you can use the ? for small calculations or translating numeric formats.

:> ? 5 - 4
1 0x1 01 1 0000:0001 1 00000001 1.0 0.000000f 0.000000  
:> ? 'A'
65 0x41 0101 65 0000:0041 65 "A" 01000001 65.0 0.000000f 0.000000  

Some other helpful commands:

  • pxr @ rsp: Show references on the stack
  • dbt: Display backtrace based on dbg.btdepth and dbg.btalgo
  • drr: Display in colors and words all the refs from registers or memory
  • dm=: List memory maps of target process (ascii-art bars)
  • /R pop rax, ret: Search for ROP gadgets
  • afl: Show functions
  • afg: non-interactive ascii-art basic-block graph (See VV)
  • afv: this shows the variables for current function
  • afvn {old} {new}: this renames the variable name.

When debugging an executable, the visual mode works great. This has a view with a overview of the code, together with register values. Entering visual mode can be done using V. Switch modes using p or P. When in visual mode you can always enter ? for an overview. The V command opens the call graph, which will give you a direct overview of the flow of the application. Use q to exit the call graph view.

The first thing I do is walking through the code and making sure that all functions are properly defined (using df to create a new function, de to set the end of the function, dr to rename the function at cursor).

The _ is perfect for finding flags, like string references. New functions can be created using df when you're on the start of a function. The . can be used to return to the current program counter.

  • F2 or b toggle breakpoint
  • F4 run to cursor
  • F7 single step
  • F8 step over
  • F9 continue

Using e in visual mode you'll get the configuration editor. This enables you to see the current configuration and change accordingly. If you want to enter radare commands, use the : prefix. A opens the visual assembler, where you can translate instructions to opcodes and write them to the cursor position. Adding comments to the cursor positions is done using ;.

If you use radare2 projects, it will save your current environment and comments to the projects folder. Use Po to open a project (you can also start radare2 using r2 -p {project}). Ps will save the project.

Other useful radare2 tools:

  • rabin2: information and operations on binaries
  • rarun2: helper to run binaries for debugging, using for example rr2 script. This command enables you to redirect the output to a listening adress, other tty, etc.
  • rahash2: command to help with different type of hashes, calculate, compare, etc.
(env)root@packer-vmware-iso /v/0/warmup# rahash2 -s test -a sha256
0x00000000-0x00000003 sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08  
  • rax2: helper for calculations or (byte) conversions, like the ? command.
  • ragg2(-cc): compile programs into tiny binaries, used for example for shellcoding
  • rafind2: find byte patterns into files
  • radiff2: unified binary diffing utility. Allows you to easily find differences between to binaries.
(env)root@packer-vmware-iso /v/0/warmup# radiff2 ./simple_calc ./complex_calc
0x000156e0 4885ff0f84af00 => 0f1f00660f1f44 0x000156e0  
  • rasm2: assembler and disassembler tool

Just some other notes / remarks:

  • oeax is not a hardware register, but it's exposed by the Linux regset struct in order to provide syscall num information when syscall tracing. it's the 'old value of eax'. The indentation is wrong indeed, but the name is fine.

This is just a small writeup of my radare2 experiences, hope you enjoyed it. I'll update the article with my new experiences.

References: