Swedish by Weronika Pawlak.
Update (2016-11-01): The Radare2 creator has informed me that all of the issues I mention below have been fixed.
.@stevecheckoway i fixed all the issues you say in the post. but anyway, r2 is far from perfect, but everything works if you use it properly— pancake (@trufae) November 1, 2016
Note carefully the date this was published. It’s entirely possible that all of the problems I mention below have long since been fixed.
I’ve spent a fair bit of time reverse engineering firmware using IDA. I have never been completely happy with IDA. It improved dramatically with the new UI and Python bindings, but I think it has been hampered by early design decisions. (To name but one, it’s impossible for a segment to be not 16-byte aligned which is a hold-over from the Intel 8086. The 34 year old Intel 80286 introduced protected mode which supports arbitrary segment alignment and IDA just cannot handle it.) Still, I’ve been moderately successful reverse engineering firmware for a wide variety of processor architectures using IDA. Unfortunately, IDA is expensive. Like, really, really expensive.
Several competing tools have recently become popular. Yesterday, I gave radare2 a spin for the first time. I started by reading through the Radare2 Book. Almost immediately, I noticed some odd design choices. For example, the
rax2 tool has a very unintuitive (to me) interface.
Mishmash of prefixes, suffixes, and prefix modifications. Does anyone find this intuitive?— Stephen Checkoway (@stevecheckoway) October 28, 2016
Better design: unambiguous input; specify output? pic.twitter.com/YCrCjZISlM
But any new tool is going to take some time to learn, so I pressed on. I compiled and installed the main radare2 binaries. As a first test, I ran
r2 /usr/bin/true and entered visual mode with the
So far so good! Since radare2 uses vim-esque movement key bindings (hjkl), I scrolled around a little bit but almost immediately noticed something odd. After scrolling down once (j) and then back up once (k), I’d expect to see the same thing as before, but instead, I get this.
So it scrolled a little too far, but wait, what’s that
call qword [rbp + 0x48]? Apparently, it decided to move the
ff byte that preceded
main into main, thus changing the disassembly! In fact, scrolling right or left, changes the offset of the start of the disassembly. As near as I can tell, left decrements the offset by one, right increments it by one, up decrements it by four, and down increments it by the size of the instruction. I can imagine why one might want similar functionality, but it’s surprising for it to be the default.
After performing some code analysis (command
aa), this behavior disappears and up and down scroll by an instruction. Left and right keep their behavior.
Next up: visual panel mode (command
! in visual mode). This seems neat (although the arrows don’t seem to respect the UTF-8 setting.) Unfortunately, this mode seems very buggy. For example, immediately after opening the visual panel mode, opening the
File menu and selecting
Close twice causes
r2 to segfault. I’ve managed other segfaults in this mode, but I’m not entirely sure what caused them. This reminds me a lot of GDB’s Text User Interface (TUI) mode which crashes essentially every time I use it.
After performing analyses which can take some time, renaming functions, or adding comments, it’d be great to be able to save my work and come back to it. Radare2 has a notion of a project. The
P command can open and save projects.
[0x100000f33]> 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 | PS [file] save script file | NOTE: See 'e??prj.' | NOTE: project are stored in ~/.config/radare2/projects
So let’s give that a shot. First, I’ll run
r2 /usr/bin/true again, run
aa, and then save the project.
[0x100000f33]> aa [x] Analyze all flags starting with sym. and entry0 (aa) [0x100000f33]> Ps true true
This creates a
~/.config/radare2/projects/true directory containing two files.
$ ls -l ~/.config/radare2/projects/true total 68 -rw-r--r-- 1 steve staff 64653 Oct 29 14:26 rc -rw-r--r-- 1 steve staff 1393 Oct 29 14:26 xrefs
So far so good. Now that I’ve saved a project, I should be able to see it in the list of projects using the
[0x100000f33]> Pl [0x100000f33]> Pl? [0x100000f33]>
I guess not? Okay, I’ll try seeking one byte forward, just to change the state a little and then reopen the project.
[0x100000f33]> s +1 [0x100000f34]> Po true Close current session? (Y/n) [0x100000f33]>
Okay, that seems good. Since I performed the
aa before saving the project, surely, that information has been saved, right? No, no it wasn’t. I have no idea why. That seems like pretty essential information to save.
-p command line flag, we can open a project. That seems handy. As a final project management test, I’ll open a project with
-p, ask for a list of projects and then quit and save.
$ r2 -p true [0x100000f31]> Pl [0x100000f31]> q Do you want to save the 'true' project? (Y/n) r_sys_mkdirp: fail '/Users/steve/.config/radare2/projects/true/rc/rop' of '/Users/steve/.config/radare2/projects/true/rc/rop' sdb: Cannot open '/Users/steve/.config/radare2/projects/true/rc/rop/nop.tmp' for writing. r_sys_mkdirp: fail '/Users/steve/.config/radare2/projects/true/rc/rop' of '/Users/steve/.config/radare2/projects/true/rc/rop' sdb: Cannot open '/Users/steve/.config/radare2/projects/true/rc/rop/mov.tmp' for writing. r_sys_mkdirp: fail '/Users/steve/.config/radare2/projects/true/rc/rop' of '/Users/steve/.config/radare2/projects/true/rc/rop' sdb: Cannot open '/Users/steve/.config/radare2/projects/true/rc/rop/const.tmp' for writing. r_sys_mkdirp: fail '/Users/steve/.config/radare2/projects/true/rc/rop' of '/Users/steve/.config/radare2/projects/true/rc/rop' sdb: Cannot open '/Users/steve/.config/radare2/projects/true/rc/rop/arithm.tmp' for writing. r_sys_mkdirp: fail '/Users/steve/.config/radare2/projects/true/rc/rop' of '/Users/steve/.config/radare2/projects/true/rc/rop' sdb: Cannot open '/Users/steve/.config/radare2/projects/true/rc/rop/arithm_ct.tmp' for writing.
rc is a file, not a directory, saving is failing. I have no idea why. Opening a project using
Po and then saving has the same behavior. I guess projects aren’t usable.
Finally, I took a look at a little bit of the broader radare2 ecosystem. Radare2 comes with a package manager
r2pm which can install packages. First up, the webui packages. Following the directions, I tried to install
$ r2pm -i www-m Processing www-m ... Already up-to-date. Install Done For www-m make -C www/m build ... /Users/steve/.config/radare2/r2pm/db/www-m: line 11: cd: dist/m: No such file or directory
So that didn’t work. What about the Python-GTK UI, Bokken?
$ r2pm -i bokken Processing bokken ... ... Install Done For bokken abort: error: Connection refused sys/bokken.sh: line 14: cd: bokken: No such file or directory
So r2pm installed it, but then failed twice. Since
r2pm -l claims Bokken is installed, but the installation clearly failed, let’s try removing it.
$ r2pm -u bokken Processing bokken ... Already up-to-date. Uninstall Done For bokken Sorry. This package cannot be uninstalled
Maybe the package manager isn’t up to date.
$ r2pm update Already up-to-date. r2pm database initialized. Use 'r2pm update' to update
Why does the update command tell me to run update?
Okay, final thing. IDA can decompile binaries for several architectures into C (assuming you’ve shelled out even more money for the decompiler). Radare2 has a package that can do that, although I understand it’s still a work in progress. Still, this could be a nice, free alternative.
I’ll spare you the hundreds of lines of errors that result from running
r2pm -i radeco.
In summary, I had a pretty frustrating day playing with radare2. It seems like it could be a nice alternative to spending thousands of dollars on IDA, but as far as I can tell, it’s currently buggy and unusable.