Many people feel discouraged or overwhelmed to use radare2 due to its complexity (understandably so). They often use gdb with the downright amazing PEDA extension for their debugging needs and IDA Pro for disassembly (or Hopper/Binary Ninja if the price of IDA is too prohibitive).
But you can do both static and dynamic analysis using radare2, with comparable features to gdb-peda on the dynamic front. In this post, I’m going to illustrate this better; perhaps then r2 won’t seem so daunting to use.
Debugger mode
To open a binary in debug mode, either specify the -d
option in the command line,
$ r2 -d /path/to/binary
Or, if you’ve already performed some analysis, you can reopen it in debug mode using ood
or doo
; all custom flags will still be there.
Diassemble
PEDA
gdb-peda$ pdis main
Dump of assembler code for function main:
-----------------------------SNIP------------------------------
0x08048557 <+121>: push eax
0x08048558 <+122>: call 0x804846b <func>
0x0804855d <+127>: add esp,0x8
0x08048560 <+130>: test eax,eax
0x08048562 <+132>: jne 0x8048574 <main+150>
0x08048564 <+134>: sub esp,0xc
0x08048567 <+137>: push 0x8048620
0x0804856c <+142>: call 0x8048340 <puts@plt>
0x08048571 <+147>: add esp,0x10
0x08048574 <+150>: mov eax,0x0
0x08048579 <+155>: mov edx,DWORD PTR [ebp-0xc]
0x0804857c <+158>: xor edx,DWORD PTR gs:0x14
0x08048583 <+165>: je 0x804858a <main+172>
0x08048585 <+167>: call 0x8048330 <__stack_chk_fail@plt>
0x0804858a <+172>: mov ecx,DWORD PTR [ebp-0x4]
0x0804858d <+175>: leave
0x0804858e <+176>: lea esp,[ecx-0x4]
0x08048591 <+179>: ret
radare2
[0x08048558]> pdf @ main
-------------------------------------------SNIP--------------------------------------------
│ 0x08048557 50 push eax
│ 0x08048558 e80effffff call sym.func
│ 0x0804855d 83c408 add esp, 8
│ 0x08048560 85c0 test eax, eax
│ ┌─< 0x08048562 7510 jne 0x8048574
│ │ 0x08048564 83ec0c sub esp, 0xc
│ │ 0x08048567 6820860408 push str.Okay ; str.Okay ; "Okay" @ 0x8048620
│ │ 0x0804856c e8cffdffff call sym.imp.puts
│ │ 0x08048571 83c410 add esp, 0x10
│ └─> 0x08048574 b800000000 mov eax, 0
│ 0x08048579 8b55f4 mov edx, dword [ebp - local_ch]
│ 0x0804857c 653315140000. xor edx, dword gs:[0x14]
│ ┌─< 0x08048583 7405 je 0x804858a
│ │ 0x08048585 e8a6fdffff call sym.imp.__stack_chk_fail
│ └─> 0x0804858a 8b4dfc mov ecx, dword [ebp - local_4h_2]
│ 0x0804858d c9 leave
│ 0x0804858e 8d61fc lea esp, [ecx - 4]
└ 0x08048591 c3 ret
Checking DEP/PIC and other things
PEDA
In peda, you have the checksec
command, which gives varying information about the security fortification of the debugged binary.
gdb-peda$ checksec
CANARY : ENABLED
FORTIFY : ENABLED
NX : ENABLED
PIE : disabled
RELRO : Partial
radare2
In radare2, you can view a lot of information about the loaded binary using i
.
[0x7f5082528cc0]> i
type EXEC (Executable file)
file /bin/ls
referer dbg:///bin/ls
fd 25226
iorw true
blksz 0x0
mode -rwx
block 0x100
format elf64
havecode true
pic false
canary true
nx true
crypto false
va true
intrp /lib64/ld-linux-x86-64.so.2
bintype elf
class ELF64
lang c
arch x86
bits 64
machine AMD x86-64 architecture
os linux
minopsz 1
maxopsz 16
pcalign 0
subsys linux
endian little
stripped true
static false
linenum false
lsyms false
relocs false
rpath NONE
binsz 124726
We can filter out any information that’s irrelevant to us using the internal grep operator (~
)
[0x7f5082528cc0]> i~pic,canary,nx,crypto,stripped,static,relocs
pic false
canary true
nx true
crypto false
stripped true
static false
relocs false
(Un)setting ASLR
PEDA
In peda, you can check/disable ASLR using aslr
gdb-peda$ aslr
ASLR is ON
gdb-peda$ aslr off
gdb-peda$ aslr
ASLR is OFF
radare2
You can use rarun2
to run a binary with a custom environment. Again, use radare2
to debug.
$ r2 -d rarun2 program=/bin/ls aslr=no
The problem with rarun2
is that it tries to write to /proc/sys/kernel/randomize_va_space
; you need to be root to do that. I’m not sure how gdb disables ASLR at a user level.
Function argument detection
PEDA
PEDA does some neat argument guessing whenever a call <function>
instruction is reached:
[-------------------------------------code-------------------------------------]
0x8048553 <main+117>: push eax
0x8048554 <main+118>: lea eax,[ebp-0x2c]
0x8048557 <main+121>: push eax
=> 0x8048558 <main+122>: call 0x804846b <func>
0x804855d <main+127>: add esp,0x8
0x8048560 <main+130>: test eax,eax
0x8048562 <main+132>: jne 0x8048574 <main+150>
0x8048564 <main+134>: sub esp,0xc
Guessed arguments:
arg[0]: 0xff81a4cc ("This is arg1")
arg[1]: 0xff81a4da ("And this is arg2")
radare2
It’s pretty close to doing this automatically. You still have to look for them on the stack and registers; see how to dereference below.
ROP gadgets
PEDA
In PEDA, you can use dumprop
to dump all ROP gadgets within a memory range and with a specific maximum depth.
radare2
You can customize a few options for gadget hunting within radare2.
[0x00402a00]> e?rop
rop.comments: Display comments in rop search output
rop.conditional: Include conditional jump, calls and returns in ropsearch
rop.db: Store rop search results in sdb
rop.len: Maximum ROP gadget length
rop.nx: Include NX/XN/XD sections in ropsearch
rop.subchains: Display every length gadget from rop.len=X to 2 in /Rl
You can search for gadgets using either /R
or /Rl
(display in linear fashion, just like dumprop
). There are also the /R/
and /Rl/
variants which allow the use of regular expressions in your search.
[0x080482f0]> e rop.len=2
[0x080482f0]> "/Rl add esp;ret"
0x0807ecb9: add esp, 4; ret;
0x08089a67: add esp, dword [ebx + eax*4]; ret;
0x0808f570: add esp, 0x3c; ret;
0x080dbd37: add esp, dword [esi + 0xa]; ret;
0x080df4cf: add esp, dword [edx + 0xa]; ret;
0x080df667: add esp, dword [eax + 0xa]; ret;
0x080df815: add esp, dword [ebp + 0xa]; ret;
0x080dfd5b: add esp, dword [esi + 0xa]; ret;
[0x080482f0]> "/Rl mov dword;ret"
0x08048c12: mov dword [edx + 0x18], eax; ret;
-------------------[SNIP]---------------------
Searching for specific instructions
PEDA
Note: needs nasm
to be installed.
gdb-peda$ asmsearch "pop ?;ret" 0x08048000 0x08049000
Searching for ASM code: 'pop ?;ret' in range: 0x8048000 - 0x8049000
0x08048311 : (5bc3) pop ebx; ret
0x080485fb : (5dc3) pop ebp; ret
0x08048616 : (5bc3) pop ebx; ret
gdb-peda$ asmsearch "inc ?;pop ?" 0x08048000 0x08049000
Searching for ASM code: 'inc ?;pop ?' in range: 0x8048000 - 0x8049000
0x08048281 : (435f) inc ebx; pop edi
0x0804828b : (435f) inc ebx; pop edi
radare2
[0x080484de]> "/c pop;ret"
0x08048312 # 2: pop ebx; ret
0x080485fc # 2: pop ebp; ret
0x08048617 # 2: pop ebx; ret
[0x080484de]> "/c inc;pop"
0x08048282 # 2: inc ebx; pop edi
0x0804828c # 2: inc ebx; pop edi
ELF header information
PEDA
gdb-peda$ elfheader
.interp = 0x8048154
.note.ABI-tag = 0x8048168
.note.gnu.build-id = 0x8048188
.gnu.hash = 0x80481ac
.dynsym = 0x80481cc
.dynstr = 0x804822c
.gnu.version = 0x8048292
.gnu.version_r = 0x80482a0
.rel.dyn = 0x80482d0
.rel.plt = 0x80482d8
.init = 0x80482f0
.plt = 0x8048320
.plt.got = 0x8048360
.text = 0x8048370
.fini = 0x8048604
.rodata = 0x8048618
.eh_frame_hdr = 0x8048648
.eh_frame = 0x804867c
.init_array = 0x8049f08
.fini_array = 0x8049f0c
.jcr = 0x8049f10
.dynamic = 0x8049f14
.got = 0x8049ffc
.got.plt = 0x804a000
.data = 0x804a018
.bss = 0x804a020
radare2
[0x080484de]> iS~ehdr
idx=40 vaddr=0x08048000 paddr=0x00000000 sz=52 vsz=52 perm=m-rw- name=ehdr
[0x080484de]> s 0x08048000
[0x08048000]> pfo elf32 # Load ELF header format
[0x08048000]> pf.elf_header # Print formatted as ELF header struct
ident : 0x08048000 = .ELF...
type : 0x08048010 = type (enum elf_type) = 0x2 ; ET_EXEC
machine : 0x08048012 = machine (enum elf_machine) = 0x3 ; EM_386
version : 0x08048014 = 0x00000001
entry : 0x08048018 = 0x08048370
phoff : 0x0804801c = 0x00000034
shoff : 0x08048020 = 0x0000181c
flags : 0x08048024 = 0x00000000
ehsize : 0x08048028 = 0x0034
phentsize : 0x0804802a = 0x0020
phnum : 0x0804802c = 0x0009
shentsize : 0x0804802e = 0x0028
shnum : 0x08048030 = 0x001f
shstrndx : 0x08048032 = 0x001c
[0x08048000]> pf.elf_phdr @ 0x08048034
type : 0x08048034 = type (enum elf_p_type) = 0x6 ; PT_PHDR
offset : 0x08048038 = 0x00000034
vaddr : 0x0804803c = 0x08048034
paddr : 0x08048040 = 0x08048034
filesz : 0x08048044 = 0x00000120
memsz : 0x08048048 = 0x00000120
flags : 0x0804804c = flags (enum elf_p_flags) = 0x5 ; PF_Read_Exec
align : 0x08048050 = 0x00000004
What about section information?
[0x08048000]> iS
[Sections]
idx=00 vaddr=0x00000000 paddr=0x00000000 sz=0 vsz=0 perm=----- name=
idx=01 vaddr=0x08048154 paddr=0x00000154 sz=19 vsz=19 perm=--r-- name=.interp
idx=02 vaddr=0x08048168 paddr=0x00000168 sz=32 vsz=32 perm=--r-- name=.note.ABI_tag
idx=03 vaddr=0x08048188 paddr=0x00000188 sz=36 vsz=36 perm=--r-- name=.note.gnu.build_id
idx=04 vaddr=0x080481ac paddr=0x000001ac sz=32 vsz=32 perm=--r-- name=.gnu.hash
idx=05 vaddr=0x080481cc paddr=0x000001cc sz=96 vsz=96 perm=--r-- name=.dynsym
idx=06 vaddr=0x0804822c paddr=0x0000022c sz=101 vsz=101 perm=--r-- name=.dynstr
idx=07 vaddr=0x08048292 paddr=0x00000292 sz=12 vsz=12 perm=--r-- name=.gnu.version
idx=08 vaddr=0x080482a0 paddr=0x000002a0 sz=48 vsz=48 perm=--r-- name=.gnu.version_r
idx=09 vaddr=0x080482d0 paddr=0x000002d0 sz=8 vsz=8 perm=--r-- name=.rel.dyn
idx=10 vaddr=0x080482d8 paddr=0x000002d8 sz=24 vsz=24 perm=--r-- name=.rel.plt
idx=11 vaddr=0x080482f0 paddr=0x000002f0 sz=35 vsz=35 perm=--r-x name=.init
idx=12 vaddr=0x08048320 paddr=0x00000320 sz=64 vsz=64 perm=--r-x name=.plt
idx=13 vaddr=0x08048360 paddr=0x00000360 sz=8 vsz=8 perm=--r-x name=.plt.got
idx=14 vaddr=0x08048370 paddr=0x00000370 sz=658 vsz=658 perm=--r-x name=.text
idx=15 vaddr=0x08048604 paddr=0x00000604 sz=20 vsz=20 perm=--r-x name=.fini
idx=16 vaddr=0x08048618 paddr=0x00000618 sz=45 vsz=45 perm=--r-- name=.rodata
idx=17 vaddr=0x08048648 paddr=0x00000648 sz=52 vsz=52 perm=--r-- name=.eh_frame_hdr
idx=18 vaddr=0x0804867c paddr=0x0000067c sz=236 vsz=236 perm=--r-- name=.eh_frame
idx=19 vaddr=0x08049f08 paddr=0x00000f08 sz=4 vsz=4 perm=--rw- name=.init_array
idx=20 vaddr=0x08049f0c paddr=0x00000f0c sz=4 vsz=4 perm=--rw- name=.fini_array
idx=21 vaddr=0x08049f10 paddr=0x00000f10 sz=4 vsz=4 perm=--rw- name=.jcr
idx=22 vaddr=0x08049f14 paddr=0x00000f14 sz=232 vsz=232 perm=--rw- name=.dynamic
idx=23 vaddr=0x08049ffc paddr=0x00000ffc sz=4 vsz=4 perm=--rw- name=.got
idx=24 vaddr=0x0804a000 paddr=0x00001000 sz=24 vsz=24 perm=--rw- name=.got.plt
idx=25 vaddr=0x0804a018 paddr=0x00001018 sz=8 vsz=8 perm=--rw- name=.data
idx=26 vaddr=0x0804a020 paddr=0x00001020 sz=4 vsz=4 perm=--rw- name=.bss
idx=27 vaddr=0x00000000 paddr=0x00001020 sz=52 vsz=52 perm=----- name=.comment
idx=28 vaddr=0x00000000 paddr=0x00001712 sz=266 vsz=266 perm=----- name=.shstrtab
idx=29 vaddr=0x00000000 paddr=0x00001054 sz=1136 vsz=1136 perm=----- name=.symtab
idx=30 vaddr=0x00000000 paddr=0x000014c4 sz=590 vsz=590 perm=----- name=.strtab
idx=31 vaddr=0x08048034 paddr=0x00000034 sz=288 vsz=288 perm=m-r-x name=PHDR
idx=32 vaddr=0x08048154 paddr=0x00000154 sz=19 vsz=19 perm=m-r-- name=INTERP
idx=33 vaddr=0x08048000 paddr=0x00000000 sz=1896 vsz=1896 perm=m-r-x name=LOAD0
idx=34 vaddr=0x08049f08 paddr=0x00000f08 sz=280 vsz=284 perm=m-rw- name=LOAD1
idx=35 vaddr=0x08049f14 paddr=0x00000f14 sz=232 vsz=232 perm=m-rw- name=DYNAMIC
idx=36 vaddr=0x08048168 paddr=0x00000168 sz=68 vsz=68 perm=m-r-- name=NOTE
idx=37 vaddr=0x08048648 paddr=0x00000648 sz=52 vsz=52 perm=m-r-- name=GNU_EH_FRAME
idx=38 vaddr=0x00000000 paddr=0x00000000 sz=0 vsz=0 perm=m-rw- name=GNU_STACK
idx=39 vaddr=0x08049f08 paddr=0x00000f08 sz=248 vsz=248 perm=m-r-- name=GNU_RELRO
idx=40 vaddr=0x08048000 paddr=0x00000000 sz=52 vsz=52 perm=m-rw- name=ehdr
41 sections
Cross-references
This is a very useful feature to find out who calls/references what, whether it be an interesting function or string.
PEDA
gdb-peda$ xrefs func
All references to 'func':
0x8048558 <main+122>: call 0x804846b <func>
radare2
[0x080484e2]> axt sym.func
call 0x8048558 call sym.func in sym.main
This can also be done in visual mode using x
on a specific symbol.
Patching code/memory
PEDA
gdb-peda$ patch 0x402a00 0x90
Written 1 bytes to 0x402a00
radare2
If opening in read-only mode, you should enable cache-writing via e io.cache = true
. Otherwise, you can use the -w
option when loading the file: r2 -d -w ./binary
.
$ r2 /bin/ls
[0x004049a0]> e io.cache = true
[0x004049a0]> pi 1 @ main
push r15
[0x004049a0]> wx 90 @ main
[0x004049a0]> pi 1 @ main
nop
De Bruijn patterns
PEDA
gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ patto AAEA
AAEA found at offset: 34
radare2
In r2, you need to specify the address at which you wish to write the pattern. AFAIK, there is no way to write the pattern to stdout
for copy-pasting it. Also, the offset doesn’t work with string values; must be hex.
[0x00402a00]> wop?
|Usage: wop[DO] len @ addr | value
| wopD len [@ addr] Write a De Bruijn Pattern of length 'len' at address 'addr'
| wopO value Finds the given value into a De Bruijn Pattern at current offset
[0x00402a00]> wopD 100 @ rsi
[0x00402a00]> ps @ rsi!100
AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAh
[0x00402a00]> wopO 0x414b4141
28
Searching in memory
PEDA
gdb-peda$ phelp searchmem
Search for a pattern in memory; support regex search
Usage:
searchmem pattern start end
searchmem pattern mapname
radare2
[0x004049a0]> /?
|Usage: /[amx/] [arg]Search stuff (see 'e??search' for options)
| / foo\x00 search for string 'foo\0'
| /j foo\x00 search for string 'foo\0' (json output)
| /! ff search for first occurrence not matching
| /+ /bin/sh construct the string with chunks
| /!x 00 inverse hexa search (find first byte != 0x00)
| // repeat last search
| /h[t] [hash] [len] find block matching this hash. See /#?
| /a jmp eax assemble opcode and search its bytes
| /A jmp find analyzed instructions of this type (/A? for help)
| /b search backwards
| /B search recognized RBin headers
| /c jmp [esp] search for asm code
| /C[ar] search for crypto materials
| /d 101112 search for a deltified sequence of bytes
| /e /E.F/i match regular expression
| /E esil-expr offset matching given esil expressions %%= here
| /i foo search for string 'foo' ignoring case
| /m magicfile search for matching magic file (use blocksize)
| /p patternsize search for pattern of given size
| /P show offset of previous instruction
| /r sym.printf analyze opcode reference an offset
| /R [grepopcode] search for matching ROP gadgets, semicolon-separated
| /v[1248] value look for an `asm.bigendian` 32bit value
| /V[1248] min max look for an `asm.bigendian` 32bit value in range
| /w foo search for wide string 'f\0o\0o\0'
| /wi foo search for wide string ignoring case 'f\0o\0o\0'
| /x ff..33 search for hex string ignoring some nibbles
| /x ff0033 search for hex string
| /x ff43 ffd0 search for hexpair with mask
| /z min max search for strings of given size
Shellcoding
PEDA
gdb-peda$ shellcode
Error: missing argument
Generate or download common shellcodes.
Usage:
shellcode generate [arch/]platform type [port] [host]
shellcode search keyword (use % for any character wildcard)
shellcode display shellcodeId (shellcodeId as appears in search results)
shellcode zsc [generate customize shellcode]
For generate option:
default port for bindport shellcode: 16706 (0x4142)
default host/port for connect back shellcode: 127.127.127.127/16706
supported arch: x86
gdb-peda$ shellcode generate
Available shellcodes:
x86/linux exec
x86/linux connect
x86/linux bindport
x86/bsd exec
x86/bsd connect
x86/bsd bindport
gdb-peda$ shellcode generate x86/linux exec
# x86/linux/exec: 24 bytes
shellcode = (
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31"
"\xc9\x89\xca\x6a\x0b\x58\xcd\x80"
)
radare2
[0x004049a0]> g?
|Usage: g[wcilper] [arg]Go compile shellcodes
| g foo.r Compile r_egg source file
| gw Compile and write
| gc cmd=/bin/ls Set config option for shellcodes and encoders
| gc List all config options
| gl List plugins (shellcodes, encoders)
| gs name args Compile syscall name(args)
| gi exec Compile shellcode. like ragg2 -i
| gp padding Define padding for command
| ge xor Specify an encoder
| gr Reset r_egg
| EVAL VARS: asm.arch, asm.bits, asm.os
[0x004049a0]> gl
shc exec : execute cmd=/bin/sh suid=false
enc xor : xor encoder for shellcode
[0x00000000]> gi exec
[0x00000000]> g
31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05
[0x00000000]>
[0x00000000]> wx `g`
[0x00000000]> pi 13
xor eax, eax
movabs rbx, 0xff978cd091969dd1
neg rbx
push rbx
push rsp
pop rdi
cdq
push rdx
push rdi
push rsp
pop rsi
mov al, 0x3b
syscall
You can write your own shellcode for future use and compile it. Also, you can write the shellcode anywhere by using the @
address specifier.
Tracing
PEDA
tracecall
and traceinst
are very useful in a number of situations.
radare2
Sadly broken at the moment.
Virtual memory mapping
Using vmm
in peda? In r2, it’s dm
.
Dereferencing stack and registers (telescoping)
PEDA
gdb-peda$ telescope 10
0000| 0x7fff1225eed8 --> 0x7fb93f6b9830 (<__libc_start_main+240>: mov edi,eax)
0008| 0x7fff1225eee0 --> 0x0
0016| 0x7fff1225eee8 --> 0x7fff1225efb8 --> 0x7fff122611fd --> 0x736c2f6e69622f ('/bin/ls')
0024| 0x7fff1225eef0 --> 0x100000000
0032| 0x7fff1225eef8 --> 0x402a00 (push r15)
0040| 0x7fff1225ef00 --> 0x0
0048| 0x7fff1225ef08 --> 0xdeca45a1d59f8b89
0056| 0x7fff1225ef10 --> 0x4049a0 (xor ebp,ebp)
0064| 0x7fff1225ef18 --> 0x7fff1225efb0 --> 0x1
0072| 0x7fff1225ef20 --> 0x0
gdb-peda$ context reg
[----------------------------------registers-----------------------------------]
RAX: 0x402a00 (push r15)
RBX: 0x0
RCX: 0x0
RDX: 0x7fff1225efc8 --> 0x7fff12261205 ("LC_PAPER=ro_RO.UTF-8")
RSI: 0x7fff1225efb8 --> 0x7fff122611fd --> 0x736c2f6e69622f ('/bin/ls')
RDI: 0x1
RBP: 0x413be0 (push r15)
RSP: 0x7fff1225eed8 --> 0x7fb93f6b9830 (<__libc_start_main+240>: mov edi,eax)
RIP: 0x402a00 (push r15)
R8 : 0x413c50 (repz ret)
R9 : 0x7fb93fc948e0 (<_dl_fini>: push rbp)
R10: 0x846
R11: 0x7fb93f6b9740 (<__libc_start_main>: push r14)
R12: 0x4049a0 (xor ebp,ebp)
R13: 0x7fff1225efb0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
radare2
[0x00402a00]> pxr @ rsp!80
0x7ffe4ea90fb8 0x00007fc0a5275830 0X'..... (/lib/x86_64-linux-gnu/libc-2.23.so) library R X 'mov edi, eax' 'libc-2.23.so'
0x7ffe4ea90fc0 0x0000000000000000 ........ r15
0x7ffe4ea90fc8 0x00007ffe4ea91098 ...N.... rsi stack R W 0x7ffe4ea931a0 --> stack R W 0x736c2f6e69622f (/bin/ls) --> ascii
0x7ffe4ea90fd0 0x0000000100000000 ........
0x7ffe4ea90fd8 0x0000000000402a00 .*@..... (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
0x7ffe4ea90fe0 0x0000000000000000 ........ r15
0x7ffe4ea90fe8 0xd73cce5c2543d7a1 ..C%\.<.
0x7ffe4ea90ff0 0x00000000004049a0 .I@..... (.text) (/bin/ls) r12 program R X 'xor ebp, ebp' 'ls'
0x7ffe4ea90ff8 0x00007ffe4ea91090 ...N.... r13 stack R W 0x1 --> (.gnu_debuglink) rdi
0x7ffe4ea91000 0x0000000000000000 ........ r15
[0x00402a00]> drr
orax 0xffffffffffffffff orax
rax 0x0000000000402a00 (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
rbx 0x0000000000000000 r15
rcx 0x0000000000000000 r15
rdx 0x00007ffe4ea910a8 rdx stack R W 0x7ffe4ea931a8 --> stack R W 0x524e54565f474458 (XDG_VTNR=7) --> ascii
r8 0x0000000000413c50 (.text) (/bin/ls) r8 program ascii R X 'ret' 'ls'
r9 0x00007fc0a58508e0 (/lib/x86_64-linux-gnu/ld-2.23.so) r9 library R X 'push rbp' 'ld-2.23.so'
r10 0x0000000000000846 r10
r11 0x00007fc0a5275740 (/lib/x86_64-linux-gnu/libc-2.23.so) r11 library R X 'push r14' 'libc-2.23.so'
r12 0x00000000004049a0 (.text) (/bin/ls) r12 program R X 'xor ebp, ebp' 'ls'
r13 0x00007ffe4ea91090 r13 stack R W 0x1 --> (.gnu_debuglink) rdi
r14 0x0000000000000000 r15
r15 0x0000000000000000 r15
rsi 0x00007ffe4ea91098 rsi stack R W 0x7ffe4ea931a0 --> stack R W 0x736c2f6e69622f (/bin/ls) --> ascii
rdi 0x0000000000000001 (.gnu_debuglink) rdi
rsp 0x00007ffe4ea90fb8 rsp stack R W 0x7fc0a5275830 --> (/lib/x86_64-linux-gnu/libc-2.23.so) library R X 'mov edi, eax' 'libc-2.23.so'
rbp 0x0000000000413be0 (.text) (/bin/ls) rbp program R X 'push r15' 'ls'
rip 0x0000000000402a00 (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
rflags 0x0000000000000246 rflags
Breakpoint commands
PEDA
gdb-peda$ commands 1
gdb-peda$ commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>set $rax=0xdeadbeef
>set $rbx=0xdeadc0de
>end
gdb-peda$ i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000402a00
breakpoint already hit 1 time
set $rax=0xdeadbeef
set $rbx=0xdeadc0de
radare2
Warning: some commands may not work properly with dbc
.
[0x7fcd2c7a2cc0]> "dbc main pi 10;pxr@rsp!8;ps @ 0x0041a5f6"
[0x7fcd2c7a2cc0]> dc
= attach 5283 1
hit breakpoint at: 402a00
mov rdi, rsp
call 0x7fcd2c7a6c00
mov r12, rax
mov eax, dword [rip + 0x224fa7]
pop rdx
lea rsp, [rsp + rax*8]
sub edx, eax
push rdx
mov rsi, rdx
mov r13, rsp
0x7ffffe8da290 0x0000000000000001 ........ (.gnu_debuglink)
CHARSETALIASDIR
Closing remarks
Radare2 also has numerous features which PEDA lacks, such as CFG, heap analysis, renaming variables and arguments in the disassembly and many more. One thing which r2 is missing is a nice pwntools integration (although I think this can be easily done on the fly by attaching r2 to the running process. r2pipe + pwntools, however, would be a different story).
Still feel like missing something? Drop me a line or ask on #radare on freenode.