| dmhb Display all parsed Double linked list of main_arena's bins instance
| dmhb [bin_num|bin_num:malloc_state] Display parsed double linked list of bins instance from a particular arena
| dmhbg [bin_num] Display double linked list graph of main_arena's bin [Under developemnt]
| dmhc @[chunk_addr] Display malloc_chunk struct for a given malloc chunk
| dmhf Display all parsed fastbins of main_arena's fastbinY instance
| dmhf [fastbin_num|fastbin_num:malloc_state] Display parsed single linked list in fastbinY instance from a particular arena
| dmhg Display heap graph of heap segment
| dmhg [malloc_state] Display heap graph of a particular arena
| dmhi @[malloc_state]Display heap_info structure/structures for a given arena
| dmhm List all elements of struct malloc_state of main thread (main_arena)
| dmhm [malloc_state] List all malloc_state instance of a particular arena
| dmht Display all parsed thead cache bins of main_arena's tcache instance
| dmh? Show map heap help
To print safe-linked lists (glibc >= 2.32) with demangled pointers, the variable dbg.glibc.demangle must be true.
The radare2 debugger allows the user to list and manipulate the file descriptors from the target process.
This is a useful feature, which is not found in other debuggers, the functionality is similar to the lsof command line tool, but have extra subcommands to change the seek, close or duplicate them.
So, at any time in the debugging session you can replace the stdio file descriptors to use network sockets created by r2, or replace a network socket connection to hijack it.
This functionality is also available in r2frida by using the dd command prefixed with a backslash. In r2 you may want to see the output of dd? for proper details.
Radare2 has reverse debugger, that can seek the program counter backward. (e.g. reverse-next, reverse-continue in gdb) Firstly you need to save program state at the point that you want to start recording. The syntax for recording is:
[0x004028a0]> dts+
You can use dts commands for recording and managing program states. After recording the states, you can seek pc back and forth to any points after saved address. So after recording, you can try single step back:
[0x004028a0]> 2dso
[0x004028a0]> dr rip
0x004028ae
[0x004028a0]> dsb
continue until 0x004028a2
hit breakpoint at: 4028a2
[0x004028a0]> dr rip
0x004028a2
When you run dsb, reverse debugger restore previous recorded state and execute program from it until desired point.
Or you can also try continue back:
[0x004028a0]> db 0x004028a2
[0x004028a0]> 10dso
[0x004028a0]> dr rip
0x004028b9
[0x004028a0]> dcb
[0x004028a0]> dr rip
0x004028a2
dcb seeks program counter until hit the latest breakpoint. So once set a breakpoint, you can back to it any time.
You can see current recorded program states using dts:
[0x004028a0]> dts
session: 0 at:0x004028a0 ""
session: 1 at:0x004028c2 ""
NOTE: Program records can be saved at any moments. These are diff style format that save only different memory area from previous. It saves memory space rather than entire dump.
And also can add comment:
[0x004028c2]> dtsC 0 program start
[0x004028c2]> dtsC 1 decryption start
[0x004028c2]> dts
session: 0 at:0x004028a0 "program start"
session: 1 at:0x004028c2 "decryption start"
You can leave notes for each records to keep in your mind. dsb and dcb commands restore the program state from latest record if there are many records.
Program records can exported to file and of course import it. Export/Import records to/from file:
[0x004028c2]> dtst records_for_test
Session saved in records_for_test.session and dump in records_for_test.dump
[0x004028c2]> dtsf records_for_test
session: 0, 0x4028a0 diffs: 0
session: 1, 0x4028c2 diffs: 0
Moreover, you can do reverse debugging in ESIL mode. In ESIL mode, program state can be managed by aets commands.
[0x00404870]> aets+
And step back by aesb:
[0x00404870]> aer rip
0x00404870
[0x00404870]> 5aeso
[0x00404870]> aer rip
0x0040487d
[0x00404870]> aesb
[0x00404870]> aer rip
0x00404879
In addition to the native reverse debugging capabilities in radare2, it's also possible to use gdb's remote protocol to reverse debug a target gdbserver that supports it. =!dsb and =!dcb are available as dsb and dcb replacementments for this purpose, see remote gdb's documentation for more information.
On Windows, you can use dbW while debugging to set a breakpoint for the message handler of a specific window.
Get a list of the current process windows with dW :
[0x7ffe885c1164]> dW
.----------------------------------------------------.
| Handle | PID | TID | Class Name |
)----------------------------------------------------(
| 0x0023038e | 9432 | 22432 | MSCTFIME UI |
| 0x0029049e | 9432 | 22432 | IME |
| 0x002c048a | 9432 | 22432 | Edit |
| 0x000d0474 | 9432 | 22432 | msctls_statusbar32 |
| 0x00070bd6 | 9432 | 22432 | Notepad |
`----------------------------------------------------'
Set the breakpoint with a message type, together with either the window class name or its handle:
[0x7ffe885c1164]> dbW WM_KEYDOWN Edit
Breakpoint set.
Or
[0x7ffe885c1164]> dbW WM_KEYDOWN 0x002c048a
Breakpoint set.
If you aren't sure which window you should put a breakpoint on, use dWi to identify it with your mouse:
[0x7ffe885c1164]> dWi
Move cursor to the window to be identified. Ready? y
Try to get the child? y
.--------------------------------------------.
| Handle | PID | TID | Class Name |
)--------------------------------------------(
| 0x002c048a | 9432 | 22432 | Edit |
`--------------------------------------------'
Radare can be run locally, or it can be started as a server process which is controlled by a local radare2 process. This is possible because everything uses radare's IO subsystem which abstracts access to system(), cmd() and all basic IO operations so to work over a network.
Help for commands useful for remote access to radare:
[0x00405a04]> =?
Usage: =[:!+-=ghH] [...] # connect with other instances of r2
remote commands:
| = list all open connections
| =<[fd] cmd send output of local command to remote fd
| =[fd] cmd exec cmd at remote 'fd' (last open is default one)
| =! cmd run command via r_io_system
| =+ [proto://]host:port connect to remote host:port (*rap://, raps://, tcp://, udp://, http://)
| =-[fd] remove all hosts or host 'fd'
| ==[fd] open remote session with host 'fd', 'q' to quit
| =!= disable remote cmd mode
| !=! enable remote cmd mode
servers:
| .:9000 start the tcp server (echo x|nc ::1 9090 or curl ::1:9090/cmd/x)