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: