Skip to content

Latest commit

 

History

History
400 lines (319 loc) · 18.9 KB

print_modes.md

File metadata and controls

400 lines (319 loc) · 18.9 KB

##3.5 Print modes

One of the key features of radare is displaying information in various formats. The goal is to offer a selection of displaying choices to best interpret binary data.

Binary data can be represented as integers, shorts, longs, floats, timestamps, hexpair strings, or more complex formats like C structures, disassembly, decompilations, external processors, ..

Here's a list of the available print modes listable using 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 effect on the print formats. Once you have printed a timestamp 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 default date format can be configured using the cfg.datefmt variable. The field definitions follow the well known strftime(3) format.

Excerpt 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

There are print modes available for all basic types. 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:

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 when starting to reverse engineer a program because they are usually referencing information about the functions actions (asserts, debug or info messages, ...).

Therefore radare supports various string formats:

[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 strings will be zero-terminated. 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. In the case of the 'open' call, this parameter is a zero terminated string which we can inspect using psz.

[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 using the pf command.

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

This can for instance be used to look at the arguments passed to a function. To achive this, simply pass a 'format memory string' as an argument to pf and temporally change the current seek position / offset using @.

It is also possible to define arrays of structures with pf. To do this, prefix the format string with a numeric value.

You can also define a name for each field of the structure by appending them as a space-separated argument list.

[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 of a 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 used to disassemble code. It accepts a numeric value to specify how many opcodes should be disassembled. The pD command is similar but instead of a number of instructions it decompiles a given number of bytes.

 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 disassembler, 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 variable is used to influence the flavor of assembly syntax the disassembler engine outputs.

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

You can also check asm.pseudo which is an experimental pseudocode view and asm.esil which outputs ESIL ('Evaluable Strings Intermedate Language'). It aims to output a human readable representation of every opcode. Those representations can be evaluated in order to emulate the code.