Radare2 can be cross-compiled for other architectures/systems as well, like Android.
Prerequisites
• Python 3
• Meson
• Ninja
• Git
• Android NDK
Step-by-step
Download and extract the Android NDK
Download the Android NDK from the official site and extract it somewhere on your system (e.g. /tmp/android-ndk)
Make
Specify NDK base path
$ echo NDK=/tmp/android-ndk > ~/.r2androidrc
Compile + create tar.gz + push it to connected android device
./sys/android-build.sh arm64-static
You can build for different architectures by changing the argument to ./sys/android-build.sh. Run the script without any argument to see the accepted values.
Meson
Create a cross-file for meson
Meson needs a configuration file that describes the cross compilation environment (e.g. meson-android.ini). You can adjust it as necessary, but something like the following should be a good starting point:
[binaries]
c = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang'
cpp = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang++'
ar = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar'
as = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-as'
ranlib = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ranlib'
ld = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld'
strip = '/tmp/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip'
pkgconfig = 'false'
[properties]
sys_root = '/tmp/android-ndk/sysroot'
[host_machine]
system = 'android'
cpu_family = 'arm'
cpu = 'aarch64'
endian = 'little'
Compile with meson + ninja
Now setup the build directory with meson as usual:
$
CFLAGS="-static" LDFLAGS="-static" meson --default-library static
--prefix=/tmp/android-dir -Dblob=true build --cross-file
./meson-android.ini
A bit of explanation about all the options:
• CFLAGS="-static", LDFLAGS="-static", --default-library static: this ensure that libraries and binaries are statically compiled, so you do not need to properly set LD_* environment variables in your Android environment to make it find the right libraries. Binaries have everything they need inside.
• -Dblob=true: it tells meson to compile just one binary with all the needed code for running radare2, rabin2, rasm2, etc. and creates symbolic links to those names. This avoids creating many statically compiled large binaries and just create one that provides all features. You will still have rabin2, rasm2, rax2, etc. but they are just symlinks to radare2.
• --cross-file ./meson-android.ini: it describes how to compile radare2 for Android
Then compile and install the project:
$ ninja -C build
$ ninja -C build install
Move files to your android device and enjoy
At this point you can copy the generated files in /tmp/android-dir to your Android device and running radare2 from it. For example:
$ cd /tmp && tar -cvf radare2-android.tar.gz android-dir
$ adb push radare2-android.tar.gz /data/local/tmp
$ adb shell
DEVICE:/ $ cd /data/local/tmp
DEVICE:/data/local/tmp $ tar xvf radare2-android.tar.gz
DEVICE:/data/local/tmp $ ./android-dir/bin/radare2
Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]
[-s addr] [-B baddr] [-m maddr] [-c cmd] [-e k=v] file|pid|-|--|=
User Interfaces
Radare2 has seen many different user interfaces being developed over the years.
Maintaining a GUI is far from the scope of developing the core machinery of a reverse engineering toolkit: it is preferred to have a separate project and community, allowing both projects to collaborate and to improve together - rather than forcing cli developers to think in gui problems and having to jump back and forth between the graphic aspect and the low level logic of the implementations.
In the past, there have been at least 5 different native user interfaces (ragui, r2gui, gradare, r2net, bokken) but none of them got enough maintenance power to take off and they all died.
In addition, r2 has an embedded webserver and ships some basic user interfaces written in html/js. You can start them like this:
$ r2 -c=H /bin/ls
After 3 years of private development, Hugo Teso; the author of Bokken (python-gtk gui of r2) released to the public another frontend of r2, this time written in c++ and qt, which has been very welcomed by the community.
This GUI was named Iaito, but as long as he prefered not to keep maintaining it, Xarkes decided to fork it under the name of Cutter (name voted by the community), and lead the project. This is how it looks:
• https://github.com/radareorg/cutter.
Basic Radare2 Usage
The learning curve is usually somewhat steep at the beginning. Although after an hour of using it you should easily understand how most things work, and how to combine the various tools radare offers. You are encouraged to read the rest of this book to understand how some non-trivial things work, and to ultimately improve your skills.
Navigation, inspection and modification of a loaded binary file is performed using three simple actions: seek (to position), print (buffer), and alternate (write, append).
The 'seek' command is abbreviated as s and accepts an expression as its argument. The expression can be something like 10, +0x25, or [0x100+ptr_table]. If you are working with block-based files, you may prefer to set the block size to a required value with b command, and seek forward or backwards with positions aligned to it. Use s++ and s-- commands to navigate this way.
If radare2 opens an executable file, by default it will open the file in Virtual Addressing (VA) mode and the sections will be mapped to their virtual addresses. In VA mode, seeking is based on the virtual address and the starting position is set to the entry point of the executable. Using -n option you can suppress this default behavior and ask radare2 to open the file in non-VA mode for you. In non-VA mode, seeking is based on the offset from the beginning of the file.
The 'print' command is abbreviated as p and has a number of submodes — the second letter specifying a desired print mode. Frequent variants include px to print in hexadecimal, and pd for disassembling.
To be allowed to write files, specify the -w option to radare2 when opening a file. The w command can be used to write strings, hexpairs (x subcommand), or even assembly opcodes (a subcommand). Examples:
> w hello world ; string
> wx 90 90 90 90 ; hexpairs
> wa jmp 0x8048140 ; assemble
> wf inline.bin ; write contents of file
Appending a ? to a command will show its help message, for example, p?. Appending ?* will show commands starting with the given string, e.g. p?*.
To enter visual mode, press V. Use q to quit visual mode and return to the prompt.
In visual mode you can use HJKL keys to navigate (left, down, up, and right, respectively). You can use these keys in cursor mode toggled by c key. To select a byte range in cursor mode, hold down SHIFT key, and press navigation keys HJKL to mark your selection.
While in visual mode, you can also overwrite bytes by pressing i. You can press TAB to switch between the hex (middle) and string (right) columns. Pressing q inside the hex panel returns you to visual mode. By pressing p or P you can scroll different visual mode representations. There is a second most important visual mode - curses-like panels interface, accessible with V! command.
Command-line Options
The radare core accepts many flags from the command line.
This is an excerpt from the usage help message:
$ radare2 -h
Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]
[-s addr] [-B baddr] [-m maddr] [-c cmd] [-e k=v] file|pid|-|--|=
-- run radare2 without opening any file
- same as 'r2 malloc://512'
= read file from stdin (use -i and -c to run cmds)
-= perform !=! command to run all commands remotely
-0 print \x00 after init and every command
-2 close stderr file descriptor (silent warning messages)
-a [arch] set asm.arch
-A run 'aaa' command to analyze all referenced code
-b [bits] set asm.bits
-B [baddr] set base address for PIE binaries
-c 'cmd..' execute radare command
-C file is host:port (alias for -c+=http://%s/cmd/)
-d debug the executable 'file' or running process 'pid'
-D [backend] enable debug mode (e cfg.debug=true)
-e k=v evaluate config var
-f block size = file size
-F [binplug] force to use that rbin plugin
-h, -hh show help message, -hh for long
-H ([var]) display variable
-i [file] run script file
-I [file] run script file before the file is opened
-k [OS/kern] set asm.os (linux, macos, w32, netbsd, ...)
-l [lib] load plugin file
-L list supported IO plugins
-m [addr] map file at given address (loadaddr)
-M do not demangle symbol names
-n, -nn do not load RBin info (-nn only load bin structures)
-N do not load user settings and scripts
-q quiet mode (no prompt) and quit after -i
-Q quiet mode (no prompt) and quit faster (quickLeak=true)
-p [prj] use project, list if no arg, load if no file
-P [file] apply rapatch file and quit
-r [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X)
-R [rr2rule] specify custom rarun2 directive
-s [addr] initial seek
-S start r2 in sandbox mode
-t load rabin2 info in thread
-u set bin.filter=false to get raw sym/sec/cls names
-v, -V show radare2 version (-V show lib versions)
-w open file in write mode
-x open without exec-flag (asm.emu will not work), See io.exec
-X same as -e bin.usextr=false (useful for dyldcache)
-z, -zz do not load strings or load them even in raw
Common usage patterns
Open a file in write mode without parsing the file format headers.
$ r2 -nw file
Quickly get into an r2 shell without opening any file.
$ r2 -
Specify which sub-binary you want to select when opening a fatbin file:
$ r2 -a ppc -b 32 ls.fat
Run a script before showing interactive command-line prompt:
$ r2 -i patch.r2 target.bin
Execute a command and quit without entering the interactive mode:
$ r2 -qc ij hi.bin > imports.json
Set the configuration variable:
$ r2 -e scr.color=0 blah.bin
Debug a program:
$ r2 -d ls
Use an existing project file:
$ r2 -p test
Command Format