Skip to content

Latest commit

 

History

History
862 lines (638 loc) · 36.7 KB

ch3_basic_commands.md

File metadata and controls

862 lines (638 loc) · 36.7 KB

#Chapter 3: Basic commands

The basic set of commands in radare can be mostly grouped by action, and they should be easy to remember and short. This is why they are grouped with a single character, subcommands or related commands are described with a second character. For example / foo for searching plain strings or /x 90 90 to look for hexpair strings.

The format of the commands (as explained in 'Command format' chapter) looks something like that:

[[.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...

> 3s +1024    ; seeks three times 1024 from the current seek

If the command starts with ! the string is passed to the plugin hadling the current IO (the debugger for example), if no one handles it calls to posix_system() which is a shell escape, you can prefix the command with two !!.

> !help       ; handled by the debugger or shell
> !!ls        ; runs ls in the shell

The [arg] argument depends on the command, but most of them take a number as argument to specify the number of bytes to work on instead of block size. Other commands accept math expressions, or strings.

> px 0x17     ; show 0x17 bytes in hexa at current seek
> s base+0x33 ; seeks to flag 'base' plus 0x33
> / lib       ; search for 'lib' string.

The @ is used to specify a temporal seek where the command is executed. This is quite useful to not seeking all the time.

> p8 10 @ 0x4010  ; show 10 bytes at offset 0x4010
> f patata @ 0x10 ; set 'patata' flag at offset 0x10

Using @@ you can execute a single command on a list of flags matching the glob:

> s 0
> / lib             ; search 'lib' string
> p8 20 @@ hit0_*   ; show 20 hexpairs at each search hit

The > is used to pipe the output of the command to a file (truncating to 0 if exist)

> pr > dump.bin   ; dump 'raw' bytes of current block to 'dump.bin' file
> f  > flags.txt  ; dump flag list to 'flags.txt'

The | pipe is used to dump the output of the command to another program.

[0x4A13B8C0]> f | grep section | grep text
0x0805f3b0 512 section._text
0x080d24b0 512 section._text_end

Using the ; chars you can concatenate multiple commands in a single line:

> px ; dr

##3.1 Seeking

The command s is used to seek. It accepts a math expression as argument that can be composed by shift operations, basic math ones and memory access.

[0x00000000]> s?
Usage: s[+-] [addr]
s                 print current address
s 0x320           seek to this address
s-                undo seek
s+                redo seek
s*                list undo seek history
s++               seek blocksize bytes forward
s--               seek blocksize bytes backward
s+ 512            seek 512 bytes forward
s- 512            seek 512 bytes backward
sg/sG             seek begin (sg) or end (sG) of section or file
s.hexoff          Seek honoring a base from core->offset
sa [[+-]a] [asz]  seek asz (or bsize) aligned to addr
sn/sp             seek next/prev scr.nkey
s/ DATA           search for next occurrence of 'DATA'
s/x 9091          search for next occurrence of \x90\x91
sb                seek aligned to bb start
so [num]          seek to N next opcode(s)
sf                seek to next function (f->addr+f->size)
sC str            seek to comment matching given string
sr pc             seek to register

> 3s++        ; 3 times block-seeking
> s 10+0x80   ; seek at 0x80+10

To 'query' the math expression you can evaluate them using the ? command and giving the math operation as argument. And getting the result in hexa, decimal, octal and binary.

> ? 0x100+200
0x1C8 ; 456d ; 710o ; 1100 1000  

In visual mode just press u or U to undo or redo inside the seek history.

##3.2 Block size

The block size is the default view size for radare. All commands will work with this constraint, but you can always temporally change the block size just giving a numeric argument to the print commands for example (px 20)

[0xB7F9D810]> b?
Usage: b[f] [arg]
b         display current block size
b+3       increase blocksize by 3
b-16      decrement blocksize by 3
b 33      set block size to 33
b eip+4   numeric argument can be an expression
bf foo    set block size to flag size
bm 1M     set max block size

The b command is used to change the block size:

[0x00000000]> b 0x100   ; block size = 0x100
[0x00000000]> b +16     ;  ... = 0x110
[0x00000000]> b -32     ;  ... = 0xf0

The bf command is used to change the block size to the one specified by a flag. For example in symbols, the block size of the flag represents the size of the function.

[0x00000000]> bf sym.main    ; block size = sizeof(sym.main)
[0x00000000]> pd @ sym.main  ; disassemble sym.main
...

You can perform these two operations in a single one (pdf):

 [0x00000000]> pdf @ sym.main

##3.3 Sections

It is usually on firmware images, bootloaders and binary files to find sections that are loaded in memory at different addresses than the one in the disk.

To solve this issue, radare implements S.

Here's the help message:

[0xB7EE8810]> S?
Usage: S[?-.*=adlr] [...]
S               ; list sections
S.              ; show current section name
S?              ; show this help message
S*              ; list sections (in radare commands)
S=              ; list sections (in nice ascii-art bars)
Sa[-] [arch] [bits] [[off]] ; Specify arch and bits for given section
Sd [file]       ; dump current section to a file (see dmd)
Sl [file]       ; load contents of file into current section (see dml)
Sr [name]       ; rename section on current seek
S [off] [vaddr] [sz] [vsz] [name] [rwx] ; add new section
S-[id|0xoff|*]  ; remove this section definition

We can specify a section in a single line in this way:

S [off] [vaddr] [sz] [vsz] [name] [rwx] ; add new section

For example:

[0x00404888]> S 0x00000100 0x00400000 0x0001ae08 0001ae08 test rwx

Displaying the sections information:

[0x00404888]> S ; list sections

[00] . 0x00000238 r-- va=0x00400238 sz=0x0000001c vsz=0000001c .interp
[01] . 0x00000254 r-- va=0x00400254 sz=0x00000020 vsz=00000020 .note.ABI_tag
[02] . 0x00000274 r-- va=0x00400274 sz=0x00000024 vsz=00000024 .note.gnu.build_id
[03] . 0x00000298 r-- va=0x00400298 sz=0x00000068 vsz=00000068 .gnu.hash
[04] . 0x00000300 r-- va=0x00400300 sz=0x00000c18 vsz=00000c18 .dynsym


[0xB7EEA810]> S= ; list sections (in nice ascii-art bars)

...
25  0x0001a600 |-----------------------------#| 0x0001a608 --- .gnu_debuglink
26  0x0001a608 |-----------------------------#| 0x0001a706 --- .shstrtab
27* 0x00000000 |##############################| 0x0001ae08 rwx ehdr
=>  0x00004888 |-----^------------------------| 0x00004988

The first three lines are sections and the last one => is the current seek representation based on the proportions over them.

To remove a section definition just prefix the name of the section with -:

[0xB7EE8810]> S -.dynsym

##3.4 Mapping files

Radare IO allows to virtually map contents of files in the same IO space at random offsets. This is useful to open multiple files in a single view or just to 'emulate' an static environment like if it was in the debugger with the program and all its libraries mapped there.

Using the Sections command you'll be able to define different base address for each library loaded at different offsets.

Mapping files is done with the o (open) command. Let's read the help:

[0x00000000]> o?
Usage: o[com- ] [file] ([offset])
o                  list opened files
oc [file]          open core file, like relaunching r2
oo                 reopen current file (kill+fork in debugger)
oo+                reopen current file in read-write
o 4                priorize io on fd 4 (bring to front)
o-1                close file index 1
o /bin/ls          open /bin/ls file in read-only
o+/bin/ls          open /bin/ls file in read-write mode
o /bin/ls 0x4000   map file at 0x4000
on /bin/ls 0x4000  map raw file at 0x4000 (no r_bin involved)
om[?]              create, list, remove IO maps

Let's prepare a simple layout:

$ rabin2 -l /bin/ls
    [Linked libraries]
    libselinux.so.1
    librt.so.1
    libacl.so.1
    libc.so.6
    
    4 libraries

Map a file:

[0x00001190]> o /bin/zsh 0x499999

Listing mapped files:

[0x00000000]> o
- 6 /bin/ls @ 0x0 ; r
- 10 /lib/ld-linux.so.2 @ 0x100000000 ; r
- 14 /bin/zsh @ 0x499999 ; r

Print some hexadecimal from /bin/zsh

[0x00000000]> px @ 0x499999

To unmap these files just use the o- command giving the file descriptor as argument:

[0x00000000]> o-14

##3.5 Print modes

One of the efforts in radare is the way to show the information to the user. This is interpreting the bytes and giving an almost readable output format.

The bytes can be represented as integers, shorts, longs, floats, timestamps, hexpair strings, or things more complex like C structures, disassembly, decompilations, external processors, ..

This is a list of the available print modes listable with p?:

[0x08049AD0]> p?
Usage: p[=68abcdDfiImrstuxz] [arg|len]
p=[bep?] [blks]  show entropy/printable chars/chars bars
p2 [len]         8x8 2bpp-tiles
p6[de] [len]     base64 decode/encode
p8 [len]         8bit hexpair list of bytes
pa[ed] [hex asm] assemble (pa) or disasm (pad) or esil (pae) from hexpairs
p[bB] [len]      bitstream of N bytes
pc[p] [len]      output C (or python) format
p[dD][lf] [l]    disassemble N opcodes/bytes (see pd?)
pf[?|.nam] [fmt] print formatted data (pf.name, pf.name $<expr>) 
p[iI][df] [len]  print N instructions/bytes (f=func) (see pi? and pdi)
pm [magic]       print libmagic data (pm? for more information)
pr [len]         print N raw bytes
p[kK] [len]      print key in randomart (K is for mosaic)
ps[pwz] [len]    print pascal/wide/zero-terminated strings
pt[dn?] [len]    print different timestamps
pu[w] [len]      print N url encoded bytes (w=wide)
pv[jh] [mode]      bar|json|histogram blocks (mode: e?search.in)
p[xX][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)
pz [len]         print zoom view (see pz? for help)
pwd              display current working directory

###3.5.1 Hexadecimal

User-friendly way:

[0x00404888]> px
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00404888  31ed 4989 d15e 4889 e248 83e4 f050 5449  1.I..^H..H...PTI
0x00404898  c7c0 4024 4100 48c7 c1b0 2341 0048 c7c7  ..@$A.H...#A.H..
0x004048a8  d028 4000 e83f dcff fff4 6690 662e 0f1f  .(@..?....f.f...

####Show hexadecimal words dump (32bit)

[0x00404888]> pxw
0x00404888  0x8949ed31 0x89485ed1 0xe48348e2 0x495450f0  1.I..^H..H...PTI
0x00404898  0x2440c0c7 0xc7480041 0x4123b0c1 0xc7c74800  ..@$A.H...#A.H..
0x004048a8  0x004028d0 0xffdc3fe8 0x9066f4ff 0x1f0f2e66  .(@..?....f.f...

[0x00404888]> e cfg.bigendian 
false

[0x00404888]> e cfg.bigendian = true

[0x00404888]> pxw
0x00404888  0x31ed4989 0xd15e4889 0xe24883e4 0xf0505449  1.I..^H..H...PTI
0x00404898  0xc7c04024 0x410048c7 0xc1b02341 0x0048c7c7  ..@$A.H...#A.H..
0x004048a8  0xd0284000 0xe83fdcff 0xfff46690 0x662e0f1f  .(@..?....f.f...

####8bit hexpair list of bytes

[0x00404888]> p8 16
31ed4989d15e4889e24883e4f0505449

####Show hexadecimal quad-words dump (64bit)

[0x08049A80]> pxq
0x00001390  0x65625f6b63617473  0x646e6962006e6967   stack_begin.bind
0x000013a0  0x616d6f6474786574  0x7469727766006e69   textdomain.fwrit
0x000013b0  0x6b636f6c6e755f65  0x6d63727473006465   e_unlocked.strcm
...

###3.5.2 Date formats

The current supported timestamp print modes are:

[0x00404888]> pt?
|Usage: pt[dn?]
| pt      print unix time (32 bit cfg.big_endian)
| ptd     print dos time (32 bit cfg.big_endian)
| ptn     print ntfs time (64 bit !cfg.big_endian)
| pt?     show help message

For example, you can 'view' the current buffer as timestamps in ntfs time:

[0x08048000]> eval cfg.bigendian = false
[0x08048000]> pt 4
29:04:32948 23:12:36 +0000
[0x08048000]> eval cfg.bigendian = true
[0x08048000]> pt 4
20:05:13001 09:29:21 +0000

As you can see, the endianness affects to the print formats. Once printing these filetimes you can grep the results by the year for example:

[0x08048000]> pt | grep 1974 | wc -l
15
[0x08048000]> pt | grep 2022
27:04:2022 16:15:43 +0000

The date format printed can be configured with the cfg.datefmt variable following the strftime(3) format.

Extracted from the strftime(3) manpage:

%a  The abbreviated name of the day of the week according to the current locale.
%A  The full name of the day of the week according to the current locale.
%b  The abbreviated month name according to the current locale.
%B  The full month name according to the current locale.
%c  The preferred date and time representation for the current locale.
%C  The century number (year/100) as a 2-digit integer. (SU)
%d  The day of the month as a decimal number (range 01 to 31).
%D  Equivalent to %m/%d/%y.  (Yecch—for Americans only.  Americans should note that in other countries %d/%m/%y is rather common. This means that in international context this format is ambiguous and should not be used.) (SU)
%e  Like %d, the day of the month as a decimal number, but a leading zero is replaced by a space. (SU)
%E  Modifier: use alternative format, see below. (SU)
%F  Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)
%G  The ISO 8601 week-based year (see NOTES) with century as a decimal number.  The 4-digit year corresponding to the ISO week number (see %V).  This has the same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead. (TZ)
%g  Like %G, but without century, that is, with a 2-digit year (00-99). (TZ)
%h  Equivalent to %b.  (SU)
%H  The hour as a decimal number using a 24-hour clock (range 00 to 23).
%I  The hour as a decimal number using a 12-hour clock (range 01 to 12).
%j  The day of the year as a decimal number (range 001 to 366).
%k  The hour (24-hour clock) as a decimal number (range 0 to 23); single digits are preceded by a blank.  (See also %H.)  (TZ)
%l  The hour (12-hour clock) as a decimal number (range 1 to 12); single digits are preceded by a blank.  (See also %I.)  (TZ)
%m  The month as a decimal number (range 01 to 12).
%M  The minute as a decimal number (range 00 to 59).
%n  A newline character. (SU)
%O  Modifier: use alternative format, see below. (SU)
%p  Either "AM" or "PM" according to the given time value, or the corresponding strings for the current locale.  Noon is treated as "PM" and midnight as "AM".
%P  Like %p but in lowercase: "am" or "pm" or a corresponding string for the current locale. (GNU)
%r  The time in a.m. or p.m. notation.  In the POSIX locale this is equivalent to %I:%M:%S %p.  (SU)
%R  The time in 24-hour notation (%H:%M).  (SU) For a version including the seconds, see %T below.
%s  The number of seconds since the Epoch, 1970-01-01 00:00:00  +0000 (UTC). (TZ)
%S  The second as a decimal number (range 00 to 60).  (The range is up to 60 to allow for occasional leap seconds.)
%t  A tab character. (SU)
%T  The time in 24-hour notation (%H:%M:%S).  (SU)
%u  The day of the week as a decimal, range 1 to 7, Monday being 1.  See also %w.  (SU)
%U  The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01.  See also %V and %W.
%V  The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the new year.  See also %U and %W.(U)
%w  The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.
%W  The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01.
%x  The preferred date representation for the current locale without the time.
%X  The preferred time representation for the current locale without the date.
%y  The year as a decimal number without a century (range 00 to 99).
%Y  The year as a decimal number including the century.
%z  The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)
%Z  The timezone name or abbreviation.
%+  The date and time in date(1) format. (TZ) (Not supported in glibc2.)
%%  A literal '%' character.

###3.5.3 Basic types

All basic types are mapped as print modes. If you are interested in a more complex structure or just type : pf?

Here's the list of the print (pf?) modes for basic types:

Usage: pf[.key[.field[=value]]|[ val]]|[times][format] [arg0 arg1 ...]
Examples:
  pf 10xiz pointer length string
  pf {array_size}b @ array_base
  pf.             # list all formats
  pf.obj xxdz prev next size name
  pf.obj          # run stored format
  pf.obj.name     # show string inside object
  pf.obj.size=33  # set new size
 Format chars:
  e - temporally swap endian
  f - float value (4 bytes)
  c - char (signed byte)
  b - byte (unsigned)
  B - show 10 first bytes of buffer
  i - %i integer value (4 bytes)
  w - word (2 bytes unsigned short in hex)
  q - quadword (8 bytes)
  p - pointer reference (2, 4 or 8 bytes)
  d - 0x%08x hexadecimal value (4 bytes)
  D - disassemble one opcode
  x - 0x%08x hexadecimal value and flag (fd @ addr)
  z - \0 terminated string
  Z - \0 terminated wide string
  s - 32bit pointer to string (4 bytes)
  S - 64bit pointer to string (8 bytes)
  * - next char is pointer (honors asm.bits)
  + - toggle show flags for each offset
  : - skip 4 bytes
  . - skip 1 byte

Let's see some examples:

[0x4A13B8C0]> pf i
0x00404888 = 837634441

[0x4A13B8C0]> pf
0x00404888 = 837634432.000000

###3.5.4 Source (asm, C)

Valid print code formats are: JSON, C, Python, Cstring (pcj, pc, pcp, pcs) pc C pcs string pcj json pcJ javascript pcp python pcw words (4 byte) pcd dwords (8 byte)

[0xB7F8E810]> pc 32
#define _BUFFER_SIZE 32
unsigned char buffer[_BUFFER_SIZE] = {
0x89, 0xe0, 0xe8, 0x49, 0x02, 0x00, 0x00, 0x89, 0xc7, 0xe8, 0xe2, 0xff, 0xff, 0xff, 0x81, 0xc3, 0xd6, 0xa7, 0x01, 0x00, 0x8b, 0x83, 0x00, 0xff, 0xff, 0xff, 0x5a, 0x8d, 0x24, 0x84, 0x29, 0xc2 };


[0x7fcd6a891630]> pcs
"\x48\x89\xe7\xe8\x68\x39\x00\x00\x49\x89\xc4\x8b\x05\xef\x16\x22\x00\x5a\x48\x8d\x24\xc4\x29\xc2\x52\x48\x89\xd6\x49\x89\xe5\x48\x83\xe4\xf0\x48\x8b\x3d\x06\x1a

###3.5.5 Strings

Strings are probably one of the most important entrypoints while starting to reverse engineer a program because they are usually referencing information about the functions actions ( asserts, debug or info messages, ...).

So it is important for radare to be able to print strings in multiple ways:

[0x00404888]> ps?
|Usage: ps[zpw] [N]
| ps  = print string
| psb = print strings in current block
| psx = show string with scaped chars
| psz = print zero terminated string
| psp = print pascal string
| psw = print wide string

Most common strings will be just zero-terminated ones. Here's an example by using the debugger to continue the execution of the program until it executes the 'open' syscall. When we recover the control over the process, we get the arguments passed to the syscall, pointed by %ebx. Which is obviously a zero terminated string.

[0x4A13B8C0]> dcs open
0x4a14fc24 syscall(5) open ( 0x4a151c91 0x00000000 0x00000000 ) = 0xffffffda
[0x4A13B8C0]> dr
  eax  0xffffffda    esi  0xffffffff    eip    0x4a14fc24
  ebx  0x4a151c91    edi  0x4a151be1    oeax   0x00000005
  ecx  0x00000000    esp  0xbfbedb1c    eflags 0x200246  
  edx  0x00000000    ebp  0xbfbedbb0    cPaZstIdor0 (PZI)
[0x4A13B8C0]> 
[0x4A13B8C0]> psz @ 0x4a151c91
/etc/ld.so.cache

###3.5.6 Print memory

It is also possible to print various packed data types in a single line using the pf command.

[0xB7F08810]> pf xxS @ rsp
0x7fff0d29da30 = 0x00000001 
0x7fff0d29da34 = 0x00000000 
0x7fff0d29da38 = 0x7fff0d29da38 -> 0x0d29f7ee /bin/ls

This is sometimes useful for looking at the arguments passed to a function, by just giving the 'format memory string' as argument and temporally changing the current seek with the @ token.

It is also possible to define arrays of structures with pf. Just prefix the format string with a numeric value.

You can also define a name for each field of the structure by giving them as optional arguments after the format string splitted by spaces.

[0x4A13B8C0]> pf 2*xw pointer type @ esp
0x00404888 [0] {
   pointer : 
(*0xffffffff8949ed31)      type : 0x00404888 = 0x8949ed31 
   0x00404890 = 0x48e2 
}
0x00404892 [1] {
(*0x50f0e483)    pointer : 0x00404892 = 0x50f0e483 
     type : 0x0040489a = 0x2440 
}

A practical example for using pf on a binary GStreamer plugin:

$ radare ~/.gstreamer-0.10/plugins/libgstflumms.so
[0x000028A0]> seek sym.gst_plugin_desc
[0x000185E0]> pf iissxsssss major minor name desc _init version \
 license source package origin
     major : 0x000185e0 = 0
     minor : 0x000185e4 = 10
      name : 0x000185e8 = 0x000185e8 flumms 
      desc : 0x000185ec = 0x000185ec Fluendo MMS source 
     _init : 0x000185f0 = 0x00002940 
   version : 0x000185f4 = 0x000185f4 0.10.15.1 
   license : 0x000185f8 = 0x000185f8 unknown 
    source : 0x000185fc = 0x000185fc gst-fluendo-mms 
   package : 0x00018600 = 0x00018600 Fluendo MMS source 
    origin : 0x00018604 = 0x00018604 http://www.fluendo.com 

###3.5.7 Disassembly

The pd command is the one used to disassemble code, it accepts a numeric value to specify how many opcodes are wanted to be disassembled. The pD one acts in the same way, but using a number-of-bytes instead of counting instructions.

 d : disassembly N opcodes   count of opcodes
 D : asm.arch disassembler   bsize bytes


 [0x00404888]> pd 1
            ;-- entry0:
            0x00404888    31ed         xor ebp, ebp

###3.5.8 Selecting the architecture

The architecture flavour for the disassembly is defined by the asm.arch eval variable. You can use e asm.arch = ? to list all available architectures.

[0xB7F08810]> e asm.arch = ?

_d  16         8051        PD      8051 Intel CPU
_d  16 32      arc         GPL3    Argonaut RISC Core
ad  16 32 64   arm         GPL3    Acorn RISC Machine CPU
_d  16 32 64   arm.cs      BSD     Capstone ARM disassembler
_d  16 32      arm.winedbg LGPL2   WineDBG's ARM disassembler
_d  16 32      avr         GPL     AVR Atmel
ad  32         bf          LGPL3   Brainfuck
_d  16         cr16        LGPL3   cr16 disassembly plugin
_d  16         csr         PD      Cambridge Silicon Radio (CSR)
ad  32 64      dalvik      LGPL3   AndroidVM Dalvik
ad  16         dcpu16      PD      Mojang's DCPU-16
_d  32 64      ebc         LGPL3   EFI Bytecode
_d  8          gb          LGPL3   GameBoy(TM) (z80-like)
_d  16         h8300       LGPL3   H8/300 disassembly plugin
_d  8          i8080       BSD     Intel 8080 CPU
ad  32         java        Apache  Java bytecode
_d  16 32      m68k        BSD     Motorola 68000
_d  32         malbolge    LGPL3   Malbolge Ternary VM
ad  32 64      mips        GPL3    MIPS CPU
_d  16 32 64   mips.cs     BSD     Capstone MIPS disassembler
_d  16 32 64   msil        PD      .NET Microsoft Intermediate Language
_d  32         nios2       GPL3    NIOS II Embedded Processor
_d  32 64      ppc         GPL3    PowerPC
_d  32 64      ppc.cs      BSD     Capstone PowerPC disassembler
ad             rar         LGPL3   RAR VM
_d  32         sh          GPL3    SuperH-4 CPU
_d  32 64      sparc       GPL3    Scalable Processor Architecture
_d  32         tms320      LGPLv3  TMS320 DSP family
_d  32         ws          LGPL3   Whitespace esotheric VM
_d  16 32 64   x86         BSD     udis86 x86-16,32,64
_d  16 32 64   x86.cs      BSD     Capstone X86 disassembler
a_  32 64      x86.nz      LGPL3   x86 handmade assembler
ad  32         x86.olly    GPL2    OllyDBG X86 disassembler
ad  8          z80         NC-GPL2 Zilog Z80

###3.5.9 Configuring the disassembler

There are multiple options that can be used to configure the output of the disassembly, all these options are described using e? asm.

              asm.os: Select operating system (kernel) (linux, darwin, w32,..)
           asm.bytes: Display the bytes of each instruction
      asm.cmtflgrefs: Show comment flags associated to branch referece
        asm.cmtright: Show comments at right of disassembly if they fit in screen
        asm.comments: Show comments in disassembly view
          asm.decode: Use code analysis as a disassembler
           asm.dwarf: Show dwarf comment at disassembly
            asm.esil: Show ESIL instead of mnemonic
          asm.filter: Replace numbers in disassembly using flags containing a dot in the name in disassembly
           asm.flags: Show flags
          asm.lbytes: Align disasm bytes to left
           asm.lines: If enabled show ascii-art lines at disassembly
       asm.linescall: Enable call lines
        asm.linesout: If enabled show out of block lines
      asm.linesright: If enabled show lines before opcode instead of offset
      asm.linesstyle: If enabled iterate the jump list backwards
       asm.lineswide: If enabled put an space between lines
          asm.middle: Allow disassembling jumps in the middle of an instruction
          asm.offset: Show offsets at disassembly
          asm.pseudo: Enable pseudo syntax
            asm.size: Show size of opcodes in disassembly (pd)
        asm.stackptr: Show stack pointer at disassembly
          asm.cycles: Show cpu-cycles taken by instruction at disassembly
            asm.tabs: Use tabs in disassembly
           asm.trace: Show execution traces for each opcode
           asm.ucase: Use uppercase syntax at disassembly
          asm.varsub: Substitute variables in disassembly
            asm.arch: Set the arch to be usedd by asm
          asm.parser: Set the asm parser to use
          asm.segoff: Show segmented address in prompt (x86-16)
             asm.cpu: Set the kind of asm.arch cpu
         asm.profile: configure disassembler (default, simple, gas, smart, debug, full)
           asm.xrefs: Show xrefs in disassembly
       asm.functions: Show functions in disassembly
          asm.syntax: Select assembly syntax
          asm.nbytes: Number of bytes for each opcode at disassembly
       asm.bytespace: Separate hex bytes with a whitespace
            asm.bits: Word size in bits at assembler
      asm.lineswidth: Number of columns for program flow arrows

###3.5.10 Disassembly syntax

The syntax is the flavour of disassembly syntax prefered to be used by the disasm engine.

e asm.syntax = intel
e asm.syntax = att

You can also check asm.pseudo which is an experimental pseudocode view and asm.esil, ESIL stands for 'Evaluable Strings Intermedate Language'. It aims to describe a human readable representation for every opcode. Those representations can be evaluated in order to emulate code.

##3.7 Flags

The flags are bookmarks at a certain offset in the file that can be stored inside 'flag spaces'. A flag space is something like a namespace for flags. They are used to group flags with similar characteristics or of a certain type. Some example of flagspaces could be sections, registers, symbols.

To create a flag just type:

 [0x4A13B8C0]> f flag_name @ offset

You can remove this flag adding - at the begginging of the command. Most commands accept - as argument-prefix as a way to delete.

 [0x4A13B8C0]> f -flag_name 

To switch/create between flagspaces use the fs command:

 [0x4A13B8C0]> fs   ; list flag spaces

 00   symbols
 01   imports
 02   sections
 03   strings
 04   regs
 05   maps
 
 [0x4A13B8C0]> fs symbols ; select only flags in symbols flagspace
 [0x4A13B8C0]> f          ; list only flags in symbols flagspace

 [0x4A13B8C0]> fs *      ; select all flagspaces

You can rename flags with fr.

##3.8 Write

Radare can manipulate the file in multiple ways. You can resize the file, move bytes, copy/paste them, insert mode (shifting data to the end of the block or file) or just overwrite some bytes with an address, the contents of a file, a widestring or inline assembling an opcode.

To resize. Use the r command which accepts a numeric argument. Possitive valule sets the new size to the file. A negative one will strip N bytes from the current seek down-sizing the file.

r 1024      ; resize the file to 1024 bytes
r -10 @ 33  ; strip 10 bytes at offset 33

To write bytes just use the w command. It accepts multiple input formats like inline assembling, endian-friendly dwords, files, hexpair files, wide strings:

[0x00404888]> w?
|Usage: w[x] [str] [<file] [<<EOF] [@addr]
| w foobar     write string 'foobar'
| wh r2        whereis/which shell command
| wr 10        write 10 random bytes
| ww foobar    write wide string 'f\x00o\x00o\x00b\x00a\x00r\x00'
| wa push ebp  write opcode, separated by ';' (use '"' around the command)
| waf file     assemble file and write bytes
| wA r 0       alter/modify opcode at current seek (see wA?)
| wb 010203    fill current block with cyclic hexpairs
| wc[ir*?]     write cache undo/commit/reset/list (io.cache)
| wx 9090      write two intel nops
| wv eip+34    write 32-64 bit value
| wo? hex      write in block with operation. 'wo?' fmi
| wm f0ff      set binary mask hexpair to be used as cyclic write mask
| ws pstring   write 1 byte for length and then the string
| wf -|file    write contents of file at current offset
| wF -|file    write contents of hexpairs file here
| wp -|file    apply radare patch file. See wp? fmi
| wt file [sz] write to file (from current seek, blocksize or sz bytes)

Some examples:

 [0x00000000]> wx 123456 @ 0x8048300
 [0x00000000]> wv 0x8048123 @ 0x8049100
 [0x00000000]> wa jmp 0x8048320

###3.8.1 Write over with operation

The wo write command accepts multiple kinds of operations that can be applied on the curren block. This is for example a XOR, ADD, SUB, ...

[0x4A13B8C0]> wo?
|Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]
|Example:
|  wox 0x90   ; xor cur block with 0x90
|  wox 90     ; xor cur block with 0x90
|  wox 0x0203 ; xor cur block with 0203
|  woa 02 03  ; add [0203][0203][...] to curblk
|  woe 02 03  
|Supported operations:
|  wow  ==  write looped value (alias for 'wb')
|  woa  +=  addition
|  wos  -=  substraction
|  wom  *=  multiply
|  wod  /=  divide
|  wox  ^=  xor
|  woo  |=  or
|  woA  &=  and
|  woR  random bytes (alias for 'wr $b'
|  wor  >>= shift right
|  wol  <<= shift left
|  wo2  2=  2 byte endian swap
|  wo4  4=  4 byte endian swap

This way it is possible to implement ciphering algorithms using radare core primitives.

A sample session doing a xor(90) + addition(01 02)

[0x7fcd6a891630]> px
- offset -       0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x7fcd6a891630  4889 e7e8 6839 0000 4989 c48b 05ef 1622  H...h9..I......"
0x7fcd6a891640  005a 488d 24c4 29c2 5248 89d6 4989 e548  .ZH.$.).RH..I..H
0x7fcd6a891650  83e4 f048 8b3d 061a 2200 498d 4cd5 1049  ...H.=..".I.L..I
0x7fcd6a891660  8d55 0831 ede8 06e2 0000 488d 15cf e600  .U.1......H.....


[0x7fcd6a891630]> wox 90
[0x7fcd6a891630]> px
- offset -       0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x7fcd6a891630  d819 7778 d919 541b 90ca d81d c2d8 1946  ..wx..T........F
0x7fcd6a891640  1374 60d8 b290 d91d 1dc5 98a1 9090 d81d  .t`.............
0x7fcd6a891650  90dc 197c 9f8f 1490 d81d 95d9 9f8f 1490  ...|............
0x7fcd6a891660  13d7 9491 9f8f 1490 13ff 9491 9f8f 1490  ................


[0x7fcd6a891630]> woa 01 02
[0x7fcd6a891630]> px
- offset -       0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x7fcd6a891630  d91b 787a 91cc d91f 1476 61da 1ec7 99a3  ..xz.....va.....
0x7fcd6a891640  91de 1a7e d91f 96db 14d9 9593 1401 9593  ...~............
0x7fcd6a891650  c4da 1a6d e89a d959 9192 9159 1cb1 d959  ...m...Y...Y...Y
0x7fcd6a891660  9192 79cb 81da 1652 81da 1456 a252 7c77  ..y....R...V.R|w

##3.9 Yank/Paste

You can yank/paste bytes in visual mode using the y and Y key bindings that are alias for the y and yy commands of the shell. There is an internal buffer that stores N bytes from the current seek. You can write-back to another seek using the yy one.

[0x00000000]> y?
|Usage: y[ptxy] [len] [[@]addr]
| y                show yank buffer information (srcoff len bytes)
| y 16             copy 16 bytes into clipboard
| y 16 0x200       copy 16 bytes into clipboard from 0x200
| y 16 @ 0x200     copy 16 bytes into clipboard from 0x200
| yp               print contents of clipboard
| yx               print contents of clipboard in hexadecimal
| yt 64 0x200      copy 64 bytes from current seek to 0x200
| yf 64 0x200 file copy 64 bytes from 0x200 from file (opens w/ io), use -1 for all bytes
| yfa file copy    copy all bytes from from file (opens w/ io)
| yy 0x3344        paste clipboard

Sample session:

[0x00000000]> s 0x100    ; seek at 0x100
[0x00000100]> y 100      ; yanks 100 bytes from here
[0x00000200]> s 0x200    ; seek 0x200
[0x00000200]> yy         ; pastes 100 bytes

You can perform a yank and paste in a single line by just using the yt command (yank-to). The syntax is the following:

[0x4A13B8C0]> x
   offset   0 1  2 3  4 5  6 7  8 9  A B  0123456789AB
0x4A13B8C0, 89e0 e839 0700 0089 c7e8 e2ff ...9........
0x4A13B8CC, ffff 81c3 eea6 0100 8b83 08ff ............
0x4A13B8D8, ffff 5a8d 2484 29c2           ..Z.$.).    

[0x4A13B8C0]> yt 8 0x4A13B8CC @ 0x4A13B8C0

[0x4A13B8C0]> x
   offset   0 1  2 3  4 5  6 7  8 9  A B  0123456789AB
0x4A13B8C0, 89e0 e839 0700 0089 c7e8 e2ff ...9........
0x4A13B8CC, 89e0 e839 0700 0089 8b83 08ff ...9........
0x4A13B8D8, ffff 5a8d 2484 29c2           ..Z.$.).    

###3.10 Comparing bytes

You can compare data using the c command that accepts different input formats and compares the input against the bytes in the current seek.

[0x00404888]> c?
|Usage: c[?dfx] [argument]
| c  [string]    Compares a plain with escaped chars string
| cc [at] [(at)] Compares in two hexdump columns of block size
| c4 [value]     Compare a doubleword from a math expression
| c8 [value]     Compare a quadword from a math expression
| cx [hexpair]   Compare hexpair string
| cX [addr]      Like 'cc' but using hexdiff output
| cf [file]      Compare contents of file at current seek
| cg[o] [file]   Graphdiff current file and [file]
| cu [addr] @at  Compare memory hexdumps of $$ and dst in unified diff
| cw[us?] [...]  Compare memory watchers
| cat  [file]    Show contents of file (see pwd, ls)
| cl|cls|clear   Clear screen, (clear0 to goto 0, 0 only)

An example of memory comparision:

[0x08048000]> p8 4
7f 45 4c 46 

[0x08048000]> cx 7f 45 90 46
Compare 3/4 equal bytes
0x00000002 (byte=03)   90 ' '  ->  4c 'L'
[0x08048000]> 

Another subcommand of c (compare) command is the cc which stands for 'compare code'.

[0x4A13B8C0]> cc 0x39e8e089 @ 0x4A13B8C0

[0x08049A80]> cc sym.main2 @ sym.main

c8 Compare a quadword from the current seek (0x00000000) from a math expression

[0x00000000]> c8 4

Compare 1/8 equal bytes (0%)
0x00000000 (byte=01)   7f ' '  ->  04 ' '
0x00000001 (byte=02)   45 'E'  ->  00 ' '
0x00000002 (byte=03)   4c 'L'  ->  00 ' '

This number can be an math expressions using flag names and so:

[0x00000000]> cx 7f469046

Compare 2/4 equal bytes
0x00000001 (byte=02)   45 'E'  ->  46 'F'
0x00000002 (byte=03)   4c 'L'  ->  90 ' '

We can use the compare command against a file previously dumped to disk from the contents of the current block.

r2 /bin/true
[0x08049A80]> s 0
[0x08048000]> cf /bin/true
Compare 512/512 equal bytes