Category Archives: radare2

Base Conversion and Rax2 (Radare2 Framework)

As a reverse engineer, we are often face various number in various base and then the need to do conversion rise. We need a handy and simple calculator and converter tool to convert numbers from different bases, change the endianness, etc. Our shell and linux might ship this capability but not as flexible as we want.

Fortunately ‘rax2′ utility comes with Radare2 Framework for a good use. Rax aims to be a minimalistic expression evaluator for the shell and can be used for making base conversions easily between floating point values, hexadecimal representations, hexpair strings to ascii, octal to integer, etc.

In this article we will discuss about some of Rax2 capability.

Invocation

rax2 is a single utility program. We can invoke it directly in our terminal. If no arguments given, rax2 can run on interactive mode.

Let’s see the help.

rax2 -h

And what we see in out screen:

Usage: rax2 [options] [expr ...]
  =[base]                 ;  rax2 =10 0x46 -> output in base 10
  int   ->  hex           ;  rax2 10
  hex   ->  int           ;  rax2 0xa
  -int  ->  hex           ;  rax2 -77
  -hex  ->  int           ;  rax2 0xffffffb3
  int   ->  bin           ;  rax2 b30
  int   ->  ternary       ;  rax2 t42
  bin   ->  int           ;  rax2 1010d
  float ->  hex           ;  rax2 3.33f
  hex   ->  float         ;  rax2 Fx40551ed8
  oct   ->  hex           ;  rax2 35o
  hex   ->  oct           ;  rax2 Ox12 (O is a letter)
  bin   ->  hex           ;  rax2 1100011b
  hex   ->  bin           ;  rax2 Bx63
  hex   ->  ternary       ;  rax2 Tx23
  raw   ->  hex           ;  rax2 -S < /binfile
  hex   ->  raw           ;  rax2 -s 414141
  -b    binstr -> bin     ;  rax2 -b 01000101 01110110
  -B    keep base         ;  rax2 -B 33+3 -> 36
  -d    force integer     ;  rax2 -d 3 -> 3 instead of 0x3
  -e    swap endianness   ;  rax2 -e 0x33
  -f    floating point    ;  rax2 -f 6.3+2.1
  -F    stdin slurp C hex ;  rax2 -F < shellcode.c
  -h    help              ;  rax2 -h
  -k    randomart         ;  rax2 -k 0x34 1020304050
  -n    binary number     ;  rax2 -n 0x1234 # 34120000
  -N    binary number     ;  rax2 -N 0x1234 # x34x12x00x00
  -s    hexstr -> raw     ;  rax2 -s 43 4a 50
  -S    raw -> hexstr     ;  rax2 -S < /bin/ls > ls.hex
  -t    tstamp -> str     ;  rax2 -t 1234567890
  -x    hash string       ;  rax2 -x linux osx
  -u    units             ;  rax2 -u 389289238 # 317.0M
  -v    version           ;  rax2 -V

Compact yet informative.

Number Representations

Mathematical constants are simply fixed values we write, such as: 1, 135, 182, 666, etc. It can be represented in various format / base. Some common representations (in computer science) are: binary, octal, decimal, hexadecimal.

Let’s see some example.

$ rax2 0x345
837
$ rax2 837
0x345
$ rax2 44.44f
Fx8fc23142 
$ rax2 0xfffffffd
-3
$ rax2 -3
0xfffffffd 
$ rax2 -s "41 42 43 44"
ABCD

Decimal number are written as is. The hexadecimal number has 0x prefix on them. We also see 44.44f which is a decimal floating point number (suffix f) and then converted to the hexadecimal representation Fx8fc23142 (with prefix Fx). As you can see, prefix and suffix give important meaning to the conversion. List of all prefix and suffix can be seen on rax2 usage.

Endianness

Endianness (Big Endian and Little Endian) define interpretation of the bytes making up a data word when those bytes stored in computer memory.

Suppose we have value 0x12345678. This is 8 byte value (32-bit) and if we split it into byte, we have 4 bytes. Thus we have 4 bytes: 12, 34, 56, 78 where each byte requires 2 hex digits. The number will be stored differently in Big Endian system and Little Endian system.

Data are written in memory location, using the smallest unit available: byte. Computer are a big array of chunks, addressable by memory address. Memory address is like another number and range from low address to high address.

In Big Endian, you store the most significant byte in the smallest address. In our case, 0x12345678 will be seen as this:

hex1

In Little Endian, things will be different. You store the least significant byte in the smallest address. Here’s how the same value represented:

hex2

Notice that Little Endian is in the reverse order compared to Big Endian.

The good news is, in addition to convert base rax2 can also convert value from one endianness to another endianness. It’s as easy as invoking rax2 with -e argument. For example:

$ rax2 0x12345678
305419896

$ rax2 -e 0x12345678
2018915346