Thursday, June 10, 2021

Obtain struct offsets with Clang's memory layout

 One of the most interesting things to do when instrumenting binaries with FRIDA is the ability to read structs because these are used by multiple syscalls in different systems, some examples of this usage can be found in the stat API or in Window’s GetSystemInfo API: https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/ns-sysinfoapi-system_info

The hard part of parsing structs with FRIDA is that it is required to manually calculate their offsets which requires taking into account the architecture of the process, datatypes and size of pointers.

To make this job easier, clang’s memory layout feature is very helpful in documented cases. For a quick example we will take MSDN’s __stat API defined as:

int _stat(

   const char *path,

   struct _stat *buffer

);

With clang, we can get the record layout with two steps:

clang -E [-I] test.c > ptest.c

Which will generate a file that can be later used with the -cc1 parameter:

clang -cc1 -fdump-record-layouts ptest.c

And generate us the offsets for each struct member: 


In some cases, it is required to add an extra parameter -fms-extensions to enable suppor for __declspec attributes:

clang -cc1 -fdump-record-layouts -fmx-extensions ptest.c

With this information, given this layout we can guess that the member st_size should be in the offset 20 with a 64bit clang.

Hopefully, this is helpful for someone who is trying to calculate structs and is not interesting in manually doing it.

This post kudos to this post and clang for being this handy :)

2023

Every year I start writing about a wrap-up of my year but I never end up finishing it. Hope this year is different. I'm starting with th...