The registers are part of the user area stored in the context structure used by the scheduler. This structure can be manipulated to get and set values for those registers, and on intel for example, is possible to directly manipulate the DRx hardware registers to setup hardware breakpoints and watchpoints.
There are different commands to get values of the registers. For the General Purpose ones use:
[0x4A13B8C0]> !regs
eax 0x00000000 esi 0x00000000 eip 0x4a13b8c0
ebx 0x00000000 edi 0x00000000 oeax 0x0000000b
ecx 0x00000000 esp 0xbfac9bd0 eflags 0x200286
edx 0x00000000 ebp 0x00000000 cPazStIdor0 (PSI)
The !reg command can be used in different ways:
[0x4A13B8C0]> !reg eip ; get value of 'eip'
0x4a13b8c0
[0x4A13B8C0]> !reg eip = esp ; set 'eip' as esp
The interaction between the plugin and the core is done by commands returning radare instructions. This is used for example to set some flags in the core to set the values of the registers.
[0x4A13B8C0]> !reg* ; Appending '*' will show radare commands
fs regs
f oeax @ 0xb
f eax @ 0x0
f ebx @ 0x0
f ecx @ 0x0
f edx @ 0x0
f ebp @ 0x0
f esi @ 0x0
f edi @ 0x0
f oeip @ 0x0
f eip @ 0x4a13b8c0
f oesp @ 0x0
f esp @ 0xbfac9bd0
[0x4A13B8C0]> .!reg* ; '.!' interprets the output of this command
Note that the 'oeax' stores the original eax value before executing a syscall. This is used by '!contsc' to identify the call, similar to 'strace'.
An old copy of the registers is stored all the time to keep track of the changes done during the execution of the program. This old copy can be accessed with '!oregs'.
[0x4A13B8C0]> !oregs
Mon, 01 Sep 2008 00:22:32 GMT
eax 0x00000000 esi 0x00000000 eip 0x4a13b8c0
ebx 0x00000000 edi 0x00000000 oeax 0x0000000b
ecx 0x00000000 esp 0xbfac9bd0 eflags 0x200386
edx 0x00000000 ebp 0x00000000 cPazSTIdor0 (PSTI)
[0x4A13B8C0]> !regs
eax 0xbfac9bd0 esi 0x00000000 eip 0x4a13b8c2
ebx 0x00000000 edi 0x00000000 oeax 0xffffffff
ecx 0x00000000 esp 0xbfac9bd0 eflags 0x200386
edx 0x00000000 ebp 0x00000000 cPazSTIdor0 (PSTI)
The values in eax, oeax and eip has changed. And this is noted when enabling scr.color.
To store and restore the register values you can just dump the output of '!reg*' command to disk and then re-interpret it again:
; save registers
[0x4A13B8C0]> !reg* > regs.saved
; restore
[0x4A13B8C0]> . regs.saved
In the same way the eflags can be altered by the characters given in this way. Setting to '1' the selected flags:
[0x4A13B8C0]> !reg eflags = pst
[0x4A13B8C0]> !reg eflags = azsti
You can easily get a string representing the last changes in the registers using the 'dregs' command (diff registers):
[0x4A13B8C0]> !dregs
eax = 0xbfac9bd0 (0x00000000)
eip register is ignored and oeax is not handled for obvious reasons :)
There's an eval variable called 'trace.cmtregs' that adds a comment after each executed instruction giving information about the changes in the registers. Here's an example
[0x4A13C000]> !step 5
[0x4A13C000]> pd 5
; 10 esp = 0xbfac9bc8 (0xbfac9bd0)
0x4A13C000, 55 push ebp
; 12 ebp = 0xbfac9bc8 (0x00000000) esp = 0xbfac9bc8 (0xbfac9bcc)
0x4A13C001 89e5 mov ebp, esp
; 14 ebp = 0xbfac9bc8 (0x00000000) esp = 0xbfac9bc4 (0xbfac9bc8)
0x4A13C003 57 push edi
; 16 esp = 0xbfac9bc0 (0xbfac9bc8)
0x4A13C004, 56 push esi
; 18 esp = 0xbfac9bbc (0xbfac9bc4)
0x4A13C005 oeip: 53 push ebx
[0x4A13C000]>
You can align these comments with 'eval asm.cmtmargin'.
The extended or floating point registers are accessed with the '!fpregs' command. (See floating point registers for more information)