Rabin2 — Show Properties of a Binary

Under this bunny-arabic-like name, radare hides a powerful tool to handle binary files, to get information on imports, sections, headers and other data. Rabin2 can present it in several formats accepted by other tools, including radare2 itself. Rabin2 understands many file formats: Java CLASS, ELF, PE, Mach-O or any format supported by plugins, and it is able to obtain symbol import/exports, library dependencies, strings of data sections, xrefs, entrypoint address, sections, architecture type.

$ rabin2 -h

Usage: rabin2 [-AcdeEghHiIjlLMqrRsSvVxzZ] [-@ at] [-a arch] [-b bits] [-B addr]

[-C F:C:D] [-f str] [-m addr] [-n str] [-N m:M] [-P[-P] pdb]

[-o str] [-O str] [-k query] [-D lang symname] | file

-@ [addr] show section, symbol or import at addr

-A list sub-binaries and their arch-bits pairs

-a [arch] set arch (x86, arm, .. or _)

-b [bits] set bits (32, 64 ...)

-B [addr] override base address (pie bins)

-c list classes

-C [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a)

-d show debug/dwarf information

-D lang name demangle symbol name (-D all for bin.demangle=true)

-e entrypoint

-E globally exportable symbols

-f [str] select sub-bin named str

-F [binfmt] force to use that bin plugin (ignore header check)

-g same as -SMZIHVResizcld (show all info)

-G [addr] load address . offset to header

-h this help message

-H header fields

-i imports (symbols imported from libraries)

-I binary info

-j output in json

-k [sdb-query] run sdb query. for example: '*'

-K [algo] calculate checksums (md5, sha1, ..)

-l linked libraries

-L [plugin] list supported bin plugins or plugin details

-m [addr] show source line at addr

-M main (show address of main symbol)

-n [str] show section, symbol or import named str

-N [min:max] force min:max number of chars per string (see -z and -zz)

-o [str] output file/folder for write operations (out by default)

-O [str] write/extract operations (-O help)

-p show physical addresses

-P show debug/pdb information

-PP download pdb file for binary

-q be quiet, just show fewer data

-qq show less info (no offset/size for -z for ex.)

-Q show load address used by dlopen (non-aslr libs)

-r radare output

-R relocations

-s symbols

-S sections

-u unfiltered (no rename duplicated symbols/sections)

-v display version and quit

-V Show binary version information

-x extract bins contained in file

-X [fmt] [f] .. package in fat or zip the given files and bins contained in file

-z strings (from data section)

-zz strings (from raw bins [e bin.rawstr=1])

-zzz dump raw strings to stdout (for huge files)

-Z guess size of binary program

......

File Properties Identification

File type identification is done using -I. With this option, rabin2 prints information on a binary type, like its encoding, endianness, class, operating system:

$ rabin2 -I /bin/ls

arch x86

binsz 128456

bintype elf

bits 64

canary true

class ELF64

crypto false

endian little

havecode true

intrp /lib64/ld-linux-x86-64.so.2

lang c

linenum false

lsyms false

machine AMD x86-64 architecture

maxopsz 16

minopsz 1

nx true

os linux

pcalign 0

pic true

relocs false

relro partial

rpath NONE

static false

stripped true

subsys linux

va true

To make rabin2 output information in format that the main program, radare2, can understand, pass -Ir option to it:

$ rabin2 -Ir /bin/ls

e cfg.bigendian=false

e asm.bits=64

e asm.dwarf=true

e bin.lang=c

e file.type=elf

e asm.os=linux

e asm.arch=x86

e asm.pcalign=0

Code Entrypoints

The -e option passed to rabin2 will show entrypoints for given binary. Two examples:

$ rabin2 -e /bin/ls

[Entrypoints]

vaddr=0x00005310 paddr=0x00005310 baddr=0x00000000 laddr=0x00000000 haddr=0x00000018 type=program


1 entrypoints


$ rabin2 -er /bin/ls

fs symbols

f entry0 1 @ 0x00005310

f entry0_haddr 1 @ 0x00000018

s entry0

Imports

Rabin2 is able to find imported objects by an executable, as well as their offsets in its PLT. This information is useful, for example, to understand what external function is invoked by call instruction. Pass -i flag to rabin2 to get a list of imports. An example:

$ rabin2 -i /bin/ls

[Imports]

nth vaddr bind type lib name

―――――――――――――――――――――――――――――――――――――

1 0x000032e0 GLOBAL FUNC __ctype_toupper_loc

2 0x000032f0 GLOBAL FUNC getenv

3 0x00003300 GLOBAL FUNC sigprocmask

4 0x00003310 GLOBAL FUNC __snprintf_chk

5 0x00003320 GLOBAL FUNC raise

6 0x00000000 GLOBAL FUNC free

7 0x00003330 GLOBAL FUNC abort

8 0x00003340 GLOBAL FUNC __errno_location

9 0x00003350 GLOBAL FUNC strncmp

10 0x00000000 WEAK NOTYPE _ITM_deregisterTMCloneTable

11 0x00003360 GLOBAL FUNC localtime_r

12 0x00003370 GLOBAL FUNC _exit

13 0x00003380 GLOBAL FUNC strcpy

14 0x00003390 GLOBAL FUNC __fpending

15 0x000033a0 GLOBAL FUNC isatty

16 0x000033b0 GLOBAL FUNC sigaction

17 0x000033c0 GLOBAL FUNC iswcntrl

18 0x000033d0 GLOBAL FUNC wcswidth

19 0x000033e0 GLOBAL FUNC localeconv

20 0x000033f0 GLOBAL FUNC mbstowcs

21 0x00003400 GLOBAL FUNC readlink

...


Exports

Rabin2 is able to find exports. For example:

$ rabin2 -E /usr/lib/libr_bin.so | head

[Exports]


nth paddr vaddr bind type size lib name

―――――――――――――――――――――――――――――――――――――――――――――――――――――

210 0x000ae1f0 0x000ae1f0 GLOBAL FUNC 200 r_bin_java_print_exceptions_attr_summary

211 0x000afc90 0x000afc90 GLOBAL FUNC 135 r_bin_java_get_args

212 0x000b18e0 0x000b18e0 GLOBAL FUNC 35 r_bin_java_get_item_desc_from_bin_cp_list

213 0x00022d90 0x00022d90 GLOBAL FUNC 204 r_bin_class_add_method

214 0x000ae600 0x000ae600 GLOBAL FUNC 175 r_bin_java_print_fieldref_cp_summary

215 0x000ad880 0x000ad880 GLOBAL FUNC 144 r_bin_java_print_constant_value_attr_summary

216 0x000b7330 0x000b7330 GLOBAL FUNC 679 r_bin_java_print_element_value_summary

217 0x000af170 0x000af170 GLOBAL FUNC 65 r_bin_java_create_method_fq_str

218 0x00079b00 0x00079b00 GLOBAL FUNC 15 LZ4_createStreamDecode

Symbols (Exports)

With rabin2, the generated symbols list format is similar to the imports list. Use the -s option to get it:

rabin2 -s /bin/ls | head

[Symbols]


nth paddr vaddr bind type size lib name

――――――――――――――――――――――――――――――――――――――――――――――――――――――

110 0x000150a0 0x000150a0 GLOBAL FUNC 56 _obstack_allocated_p

111 0x0001f600 0x0021f600 GLOBAL OBJ 8 program_name

112 0x0001f620 0x0021f620 GLOBAL OBJ 8 stderr

113 0x00014f90 0x00014f90 GLOBAL FUNC 21 _obstack_begin_1

114 0x0001f600 0x0021f600 WEAK OBJ 8 program_invocation_name

115 0x0001f5c0 0x0021f5c0 GLOBAL OBJ 8 alloc_failed_handler

116 0x0001f5f8 0x0021f5f8 GLOBAL OBJ 8 optarg

117 0x0001f5e8 0x0021f5e8 GLOBAL OBJ 8 stdout

118 0x0001f5e0 0x0021f5e0 GLOBAL OBJ 8 program_short_name

With the -sr option rabin2 produces a radare2 script instead. It can later be passed to the core to automatically flag all symbols and to define corresponding byte ranges as functions and data blocks.

$ rabin2 -sr /bin/ls | head

fs symbols

f sym.obstack_allocated_p 56 0x000150a0

f sym.program_invocation_name 8 0x0021f600

f sym.stderr 8 0x0021f620

f sym.obstack_begin_1 21 0x00014f90

f sym.program_invocation_name 8 0x0021f600

f sym.obstack_alloc_failed_handler 8 0x0021f5c0

f sym.optarg 8 0x0021f5f8

f sym.stdout 8 0x0021f5e8

f sym.program_invocation_short_name 8 0x0021f5e0

List Libraries

Rabin2 can list libraries used by a binary with the -l option:

$ rabin2 -l `which r2`

[Linked libraries]

libr_core.so

libr_parse.so

libr_search.so

libr_cons.so

libr_config.so

libr_bin.so

libr_debug.so

libr_anal.so

libr_reg.so

libr_bp.so

libr_io.so

libr_fs.so

libr_asm.so

libr_syscall.so

libr_hash.so

libr_magic.so

libr_flag.so

libr_egg.so

libr_crypto.so

libr_util.so

libpthread.so.0

libc.so.6


22 libraries

Lets check the output with ldd command:

$ ldd `which r2`

linux-vdso.so.1 (0x00007fffba38e000)

libr_core.so => /usr/lib64/libr_core.so (0x00007f94b4678000)

libr_parse.so => /usr/lib64/libr_parse.so (0x00007f94b4425000)

libr_search.so => /usr/lib64/libr_search.so (0x00007f94b421f000)

libr_cons.so => /usr/lib64/libr_cons.so (0x00007f94b4000000)

libr_config.so => /usr/lib64/libr_config.so (0x00007f94b3dfa000)

libr_bin.so => /usr/lib64/libr_bin.so (0x00007f94b3afd000)

libr_debug.so => /usr/lib64/libr_debug.so (0x00007f94b38d2000)

libr_anal.so => /usr/lib64/libr_anal.so (0x00007f94b2fbd000)

libr_reg.so => /usr/lib64/libr_reg.so (0x00007f94b2db4000)

libr_bp.so => /usr/lib64/libr_bp.so (0x00007f94b2baf000)

libr_io.so => /usr/lib64/libr_io.so (0x00007f94b2944000)

libr_fs.so => /usr/lib64/libr_fs.so (0x00007f94b270e000)

libr_asm.so => /usr/lib64/libr_asm.so (0x00007f94b1c69000)

libr_syscall.so => /usr/lib64/libr_syscall.so (0x00007f94b1a63000)

libr_hash.so => /usr/lib64/libr_hash.so (0x00007f94b185a000)

libr_magic.so => /usr/lib64/libr_magic.so (0x00007f94b164d000)

libr_flag.so => /usr/lib64/libr_flag.so (0x00007f94b1446000)

libr_egg.so => /usr/lib64/libr_egg.so (0x00007f94b1236000)

libr_crypto.so => /usr/lib64/libr_crypto.so (0x00007f94b1016000)

libr_util.so => /usr/lib64/libr_util.so (0x00007f94b0d35000)

libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f94b0b15000)

libc.so.6 => /lib64/libc.so.6 (0x00007f94b074d000)

libr_lang.so => /usr/lib64/libr_lang.so (0x00007f94b0546000)

libr_socket.so => /usr/lib64/libr_socket.so (0x00007f94b0339000)

libm.so.6 => /lib64/libm.so.6 (0x00007f94affaf000)

libdl.so.2 => /lib64/libdl.so.2 (0x00007f94afdab000)

/lib64/ld-linux-x86-64.so.2 (0x00007f94b4c79000)

libssl.so.1.0.0 => /usr/lib64/libssl.so.1.0.0 (0x00007f94afb3c000)

libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x00007f94af702000)

libutil.so.1 => /lib64/libutil.so.1 (0x00007f94af4ff000)

libz.so.1 => /lib64/libz.so.1 (0x00007f94af2e8000)

If you compare the outputs of rabin2 -l and ldd, you will notice that rabin2 lists fewer libraries than ldd. The reason is that rabin2 does not follow and does not show dependencies of libraries. Only direct binary dependencies are shown.

Strings

The -z option is used to list readable strings found in the .rodata section of ELF binaries, or the .text section of PE files. Example:

$ rabin2 -z /bin/ls | head

[Strings]

nth paddr vaddr len size section type string

―――――――――――――――――――――――――――――――――――――――――――――――――――――――

000 0x000160f8 0x000160f8 11 12 (.rodata) ascii dev_ino_pop

001 0x00016188 0x00016188 10 11 (.rodata) ascii sort_files

002 0x00016193 0x00016193 6 7 (.rodata) ascii posix-

003 0x0001619a 0x0001619a 4 5 (.rodata) ascii main

004 0x00016250 0x00016250 10 11 (.rodata) ascii ?pcdb-lswd

005 0x00016260 0x00016260 65 66 (.rodata) ascii # Configuration file for dircolors, a utility to help you set the

006 0x000162a2 0x000162a2 72 73 (.rodata) ascii # LS_COLORS environment variable used by GNU ls with the --color option.

007 0x000162eb 0x000162eb 56 57 (.rodata) ascii # Copyright (C) 1996-2018 Free Software Foundation, Inc.

008 0x00016324 0x00016324 70 71 (.rodata) ascii # Copying and distribution of this file, with or without modification,

009 0x0001636b 0x0001636b 76 77 (.rodata) ascii # are permitted provided the copyright notice and this notice are preserved.

With the -zr option, this information is represented as a radare2 commands list. It can be used in a radare2 session to automatically create a flag space called "strings" pre-populated with flags for all strings found by rabin2. Furthermore, this script will mark corresponding byte ranges as strings instead of code.

$ rabin2 -zr /bin/ls | head

fs stringsf str.dev_ino_pop 12 @ 0x000160f8

Cs 12 @ 0x000160f8

f str.sort_files 11 @ 0x00016188

Cs 11 @ 0x00016188

f str.posix 7 @ 0x00016193

Cs 7 @ 0x00016193

f str.main 5 @ 0x0001619a

Cs 5 @ 0x0001619a

f str.pcdb_lswd 11 @ 0x00016250

Cs 11 @ 0x00016250

Program Sections

Rabin2 called with the -S option gives complete information about the sections of an executable. For each section the index, offset, size, alignment, type and permissions, are shown. The next example demonstrates this:

$ rabin2 -S /bin/ls

[Sections]


nth paddr size vaddr vsize perm name

―――――――――――――――――――――――――――――――――――――――――――――――――――――

00 0x00000000 0 0x00000000 0 ----

01 0x00000238 28 0x00000238 28 -r-- .interp

02 0x00000254 32 0x00000254 32 -r-- .note.ABI_tag

03 0x00000278 176 0x00000278 176 -r-- .gnu.hash

04 0x00000328 3000 0x00000328 3000 -r-- .dynsym

05 0x00000ee0 1412 0x00000ee0 1412 -r-- .dynstr

06 0x00001464 250 0x00001464 250 -r-- .gnu.version

07 0x00001560 112 0x00001560 112 -r-- .gnu.version_r

08 0x000015d0 4944 0x000015d0 4944 -r-- .rela.dyn

09 0x00002920 2448 0x00002920 2448 -r-- .rela.plt

10 0x000032b0 23 0x000032b0 23 -r-x .init

11 0x000032d0 1648 0x000032d0 1648 -r-x .plt

12 0x00003940 24 0x00003940 24 -r-x .plt.got

13 0x00003960 73931 0x00003960 73931 -r-x .text

14 0x00015a2c 9 0x00015a2c 9 -r-x .fini

15 0x00015a40 20201 0x00015a40 20201 -r-- .rodata

16 0x0001a92c 2164 0x0001a92c 2164 -r-- .eh_frame_hdr

17 0x0001b1a0 11384 0x0001b1a0 11384 -r-- .eh_frame

18 0x0001e390 8 0x0021e390 8 -rw- .init_array

19 0x0001e398 8 0x0021e398 8 -rw- .fini_array

20 0x0001e3a0 2616 0x0021e3a0 2616 -rw- .data.rel.ro

21 0x0001edd8 480 0x0021edd8 480 -rw- .dynamic

22 0x0001efb8 56 0x0021efb8 56 -rw- .got

23 0x0001f000 840 0x0021f000 840 -rw- .got.plt

24 0x0001f360 616 0x0021f360 616 -rw- .data

25 0x0001f5c8 0 0x0021f5e0 4824 -rw- .bss

26 0x0001f5c8 232 0x00000000 232 ---- .shstrtab

With the -Sr option, rabin2 will flag the start/end of every section, and will pass the rest of information as a comment.

$ rabin2 -Sr /bin/ls | head

fs sections

"f section. 1 0x00000000"

"f section..interp 1 0x000002a8"

"f section..note.gnu.build_id 1 0x000002c4"

"f section..note.ABI_tag 1 0x000002e8"

"f section..gnu.hash 1 0x00000308"

"f section..dynsym 1 0x000003b8"

"f section..dynstr 1 0x00000fb8"

"f section..gnu.version 1 0x00001574"

"f section..gnu.version_r 1 0x00001678"

Загрузка...