Skip to content

Instantly share code, notes, and snippets.

@yarjor
Last active November 8, 2024 02:29
Show Gist options
  • Save yarjor/608b532602eb953a2a6d4473c82bc305 to your computer and use it in GitHub Desktop.
Save yarjor/608b532602eb953a2a6d4473c82bc305 to your computer and use it in GitHub Desktop.
[Data Structures in radare2] #r2 #radare2 #C #structures

The most useful feature in r2 for working with data structures is pf commands, which prints formatted data. You can use this command to print data in certain address according to a defined format, and moreover - define specific formats, for repeating structure. The command is used as pf [types] [member1] [member2] [...]. To see all the type code, pf??, and pf??? for some usage examples. To define a type, use pf.[type] [..]. Example:

[0x08048e26]> pf.node ii*? value index (node)next
[0x08048e26]> pf.node @@ obj.node*
 value : 0x0804b230 = 432
 index : 0x0804b234 = 6
  next : (*0x0) NULL
 value : 0x0804b254 = 301
 index : 0x0804b258 = 3
  next : (*0x804b248)
                struct<node>
       value : 0x0804b248 = 997
       index : 0x0804b24c = 4
        next : (*0x804b23c)
        <snip>

You can also parse a header file with radare to add the structure to the saved types, and then generate a pf command for it. to [file] is used to load and parse a file, and ts is used to print all loaded tructures. You can make the following header file:

typedef struct Node {
        int value;
        int index;
        struct Node *next;
} node;

and load it using to. You can then use t Node to generate automatically a pf command for the structure. The command in this example is pf ddp value index next:

[0x0804b260]> pf ddp value index next
 value : 0x0804b260 = 725
 index : 0x0804b264 = 2
  next : 0x0804b268 = 0x0804b254

As you can see, it is less accurate than defining pf yourself, but can be quicker if you've alreay got a header file / need it for sthg else / more comfortable with the syntax.

Some more things worth noting:
  • ts* Node can be used to generate a pf command to define this type (for future pfs)
  • You can also define a struct inline and not in a file using td (td struct foo {char* a; int b;})
  • tl can be used to to permenantly link an address with a chosen type.
  • tas [offset] & ta [struct.member] can be used to convert an offset in assembly to an offset inside a struct:
     [0x000052f0]> pd 1
     0x000052f0      mov rax, qword [rsi + 8]    ; [0x8:8]=0
     [0x000052f0]> "td struct ms { char b[8]; int member1; int member2; };"
     [0x000052f0]> "td struct ms1 { uint64_t a; int member1; };"
     [0x000052f0]> "td struct ms2 { uint16_t a; int64_t b; int member1; };"
     [0x000052f0]> tas 8
     ms.member1
     ms1.member1
     [0x000052f0]> ta ms1.member1
     [0x000052f0]> pd 1
     0x000052f0      488b4608       mov rax, qword [rsi + ms1.member1]    ; [0x8:8]=0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment