16.2.1 Trace analysis

The radare debugger stores information about the executed opcodes in a linked list and allows later to get an execution trace of the code with a list of ranged addresses of the executed code and how many times and in which order these instructions has been executed.

This information is managed with the 'at' command. 'Analyze Traces'.

[0x465D8810]> at?
Usage: at[*] [addr]
   > at?                ; show help message
   > at                 ; list all traced opcode ranges
   > at-                ; reset the tracing information
   > at*                ; list all traced opcode offsets
   > at+ [addr] [times] ; add trace for address N times
   > at [addr]          ; show trace info at address
   > atd                ; show disassembly trace
   > atD                ; show dwarf trace (at*|rsc dwarf-traces $FILE)

Here's a simple usage example:

[0x465D8810]> 10!step
[0x465D8810]> atd
001 001  0x465d8810,   0  mov eax, esp
001 002  0x465d8812    0  call 0x465d8a60
001 003  0x465d8a60,   8_ push ebp
001 004  0x465d8a61    0  mov ebp, esp
001 005  0x465d8a63    8_ push edi
001 006  0x465d8a64,   8_ push esi
001 007  0x465d8a65    8_ push ebx
001 008  0x465d8a66    0  call 0x465ed79b
001 009  0x465ed79b    0  mov ebx, [esp]
001 010  0x465ed79e    0  ret 

The tracing information can be merged by using from address and opcode length to generate ranges of executed memory addresses.

[0x4A13C00E]> at
0x4a13b8c0 - 0x4a13b8c7
0x4a13c000 - 0x4a13c048
0x4a13c050 - 0x4a13c066
0x4a1508cb - 0x4a1508cf

To get a complete list of all the executed addresses use 'at*'. The first column represents the offset and the second one the number of times it has been executed and the third one the last step counter value for this offset.

[0x4A13C00E]> at*
0x4a13b8c0 1 1
0x4a13b8c2 1 2
0x4a13c000 1 3
0x4a13c001 1 4
0x4a13c003 1 5
0x4a13c004 1 6
0x4a13c005 1 7
0x4a13c006 1 8
0x4a13c009 1 9
0x4a1508cb 1 10
0x4a1508ce 1 11
0x4a13c00e 1 12
0x4a13c014 1 13
0x4a13c017 1 14
0x4a13c019 1 15
0x4a13c01f 1 16
0x4a13c025 1 17
0x4a13c02b 1 18
0x4a13c031 1 19
0x4a13c033 1 20
0x4a13c036 1 21
0x4a13c03c 1 22
0x4a13c042 1 23
0x4a13c044 1 24
0x4a13c046 1 25
0x4a13c061 5 54
0x4a13c064 5 55
0x4a13c050 5 56
0x4a13c057 5 57
0x4a13c05a 5 58
0x4a13c05d 5 59
0x4a13c05f 4 53
[0x4A13C00E]> 

With this log we can easily identify the loops, how many times they have been executed and the execution order of them.

You can also get detailed information of a certain offset:

[0x4A13C05A]> !at 0x4a13c064
ffset = 0x4a13c064
opsize = 2
times = 5
count = 55