Can radare2 print local variables by name?

devneal17 picture devneal17 · Dec 29, 2016 · Viewed 10k times · Source

When radare2 analyzes a function, it gives local variables names such as local_4h for ebp - 0x4. It also offers the ability to give these variables more meaningful names when their purpose becomes clear. However, after the variables are renamed it becomes more difficult to print them. When I see an instruction such as mov eax, dword [ebp - i] I have to

  1. Look at the top of the disassembly to find the line var int i @ ebp-0xc
  2. Type pxw @ebp-0xc
  3. Read off the value of i from the first of 16(!) lines of output
  4. Find my place again in the disassembly after it was shifted from the last command

It's not a lot of work, but when when I'm looking through lots of assembly with many variables it becomes tedious quite quickly.

As a follow-up question, is it possible to print a variable/location each time execution stops at a breakpoint, like with GDB's display command?

Answer

Liblor picture Liblor · Sep 25, 2017

Instead of pxw @ local_4h, there is afvd (analyze function variables display), which lists every or a particular variable:

[0x00400526]> afvd
var local_14h = 0x7fff2eab16ac  0x2eab17a000000001   ........
var local_20h = 0x7fff2eab16a0  0x00007fff2eab17a8   ........ @rsp rsi stack R W 0x7fff2eab21ec --> stack R W 0x74756f2e612f2e (./a.out) --> ascii
var local_8h = 0x7fff2eab16b8  0x0000000000000041   A....... ascii
var local_4h = 0x7fff2eab16bc  0x0040057000000000   ....p.@.

[0x00400526]> .afvd local_14h   # note the dot
var local_14h = 0x7fff2eab16ac  0x2eab17a000000001   ........

afvd name returns the r2 command to display the variable 'name'. The dot at the beginning executes the command.
Remember that you can always use the ? command to get help:

[0x00400526]> afv?
|Usage: afv[rbs]
| afvr[?]                     manipulate register based arguments
| afvb[?]                     manipulate bp based arguments/locals
| afvs[?]                     manipulate sp based arguments/locals
| afvR [varname]              list addresses where vars are accessed
| afvW [varname]              list addresses where vars are accessed
| afva                        analyze function arguments/locals
| afvd name                   output r2 command for displaying the value of args/locals in the debugger
| afvn [old_name] [new_name]  rename argument/local
| afvt [name] [new_type]      change type for given argument/local
| afv-([name])                remove all or given var

Actually there is also the possibility to use (almost) the same syntax like in your question. However the variable names have to be added as flags beforehand and this has to be done every time you enter a function.

[0x00400526]> .afv*
[0x00400526]> pxw @ fcnvar.local_14h 
0x7fff2eab16ac  0x00000001 0x2eab17a0 [omitted]