I think this is enough information, you can go now and write that program. Or, you could just reverse engineer the quick'n'dirty one I've used during the CTF:
\x90\x00PSAMuAP\x01AMcAP\x01AMhAP\x01AM
AP\x01AMVAP\x01AMMAP\x01AM!AP\x01AM
AP\x01AMMAP\x01AMuAP\x01AMCAP\x01AMHAP\x01AM
AP\x01AMrAP\x01AMeAP\x01AMVAP\x01AM3AP\x01AMrAP\x01AMsAP\x01AMeIPAM!X\x00CAJ\xc1SC\x00DCR*
Keep in mind though, that it was written on-the-fly, parallel to the reversing phase - for example there are parts that was written without the knowledge of all possible instructions. This means that the code is ugly and unefficient.
Well, what can I say? Such VM, much reverse! :)
What started out as a simple writeup for a simple crackme, became a rather lengthy writeup/r2 tutorial, so kudos if you've read through it. I hope you enjoyed it (I know I did), and maybe even learnt something from it. I've surely learnt a lot about r2 during the process, and I've even contributed some small patches, and got a few ideas of more possible improvements.
This chapter is based on the Radare 2 reference card by Thanat0s, which is under the GNU GPL. Original license is as follows:
This card may be freely distributed under the terms of the GNU
general public licence — Copyright by Thanat0s - v0.1 -
Those are the basic commands you will want to know and use for moving around a binary and getting information about it.
| Command | Description |
|---|---|
| s (tab) | Seek to a different place |
| x [nbytes] | Hexdump of nbytes, $b by default |
| aa | Auto analyze |
| pdf@ funcname | Disassemble function (main, fcn, etc.) |
| f fcn(Tab) | List functions |
| f str(Tab) | List strings |
| fr [flagname] [newname] | Rename flag |
| psz [offset]~grep | Print strings and grep for one |
| axF [flag] | Find cross reference for a flag |
Flags are like bookmarks, but they carry some extra information like size, tags or associated flagspace. Use the f command to list, set, get them.
| Command | Description |
|---|---|
| f | List flags |
| fd $$ | Describe an offset |
| fj | Display flags in JSON |
| fl | Show flag length |
| fx [flagname] | Show hexdump of flag |
| fC [name] [comment] | Set flag comment |
Flags are created into a flagspace, by default none is selected, and listing flags will list them all. To display a subset of flags you can use the fs command to restrict it.
| Command | Description |
|---|---|
| fs | Display flagspaces |
| fs * | Select all flagspaces |
| fs [space] | Select one flagspace |
Binary files have information stored inside the headers. The i command uses the RBin api and allows us to the same things rabin2 do. Those are the most common ones.
| Command | Description |
|---|---|
| ii | Information on imports |
| iI | Info on binary |
| ie | Display entrypoint |
| iS | Display sections |
| ir | Display relocations |
| iz | List strings (izz, izzz) |
There are different ways to represent a string in memory. The ps command allows us to print it in utf-16, pascal, zero terminated, .. formats.
| Command | Description |
|---|---|
| psz [offset] | Print zero terminated string |
| psb [offset] | Print strings in current block |
| psx [offset] | Show string with scaped chars |
| psp [offset] | Print pascal string |
| psw [offset] | Print wide string |
The visual mode is the standard interactive interface of radare2.
To enter in visual mode use the v or V command, and then you'll only have to press keys to get the actions happen instead of commands.
| Command | Description |
|---|---|
| V | Enter visual mode |
| p/P | Rotate modes (hex, disasm, debug, words, buf) |
| c | Toggle (c)ursor |
| q | Back to Radare shell |
| hjkl | Move around (or HJKL) (left-down-up-right) |
| Enter | Follow address of jump/call |
| sS | Step/step over |
| o | Toggle asm.pseudo and asm.esil |
| . | Seek to program counter |
| / | In cursor mode, search in current block |
| :cmd | Run radare command |
| ;[-]cmt | Add/remove comment |
| /*+-[] | Change block size, [] = resize hex.cols |
| <,> | Seek aligned to block size |
| i/a/A | (i)nsert hex, (a)ssemble code, visual (A)ssembler |
| b | Toggle breakpoint |
| B | Browse evals, symbols, flags, classes, ... |
| d[f?] | Define function, data, code, .. |
| D | Enter visual diff mode (set diff.from/to) |
| e | Edit eval configuration variables |
| f/F | Set/unset flag |
| gG | Go seek to begin and end of file (0-$s) |
| mK/’K | Mark/go to Key (any key) |
| M | Walk the mounted filesystems |
| n/N | Seek next/prev function/flag/hit (scr.nkey) |
| C | Toggle (C)olors |
| R | Randomize color palette (ecr) |
| tT | Tab related. see also tab |
| v | Visual code analysis menu |
| V | (V)iew graph (agv?) |
| wW | Seek cursor to next/prev word |
| uU | Undo/redo seek |
| x | Show xrefs of current func from/to data/code |
| yY | Copy and paste selection |
| z | fold/unfold comments in diassembly |