TGViewer
ReverseEngineering ReverseEngineering @reverseengine · 1.33K subscribers
Post #1846 34
ReverseEngineering Struct Layout و Offset Analysis در Reverse Engineering وقتی Source Code رو داشته باشیم فهمیدن Struct خیلی راحت‌ تره مثلا: struct User { int id; int age; char *name; }; اینجا دقیقا میدونیم هر Field چیه و کجا قرار گرفته. ولی توی Reverse Engineering…
Struct Layout
and Offset Analysis in Reverse Engineering

It is much easier to understand Struct when we have the Source Code

For example:

struct User {
int id;
int age;
char *name;
};

Here we know exactly what each Field is and where it is located.

But in Reverse Engineering, this code is usually not mentioned

The compiler converts Struct into Machine Code and Assembly instructions and what we see may be just this:

mov eax, [rdi+0x4]

mov rax, [rdi+0x8]

Here, the compiler no longer tells us:

+0x04 = age

+0x08 = name

So we have to figure out what Field each Offset probably belongs to based on how Memory is used

This is one of the important parts of reconstructing unknown structures

What exactly is Offset?

Suppose the starting address of an Object is:

0x1000

Now in Assembly we have:

mov eax, [rdi+0x4]

If RDI is 0x1000, the CPU goes to:

0x1000 + 0x4 = 0x1004

That is:

Object Base
|
v
0x1000
+0x00
+0x04 <-- accessed
+0x08
+0x10

That +0x4 is the Offset

So when you see in RE:

[Register + Offset]

One of the first questions is:

Where does this Register point to?

What Field does this Offset indicate?

In many cases, what we are looking for is this:

Base Address + Offset
|
v
Field

Now let's look at a simple Struct

For example:

struct User {
int id;
int age;
char *name;
};

In a typical 64-bit environment where int is four bytes and pointer is eight bytes, the conceptual layout can be like this:

Offset Size Field

+0x00 4 bytes id

+0x04 4 bytes age

+0x08 8 bytes name

So when the Compiler wants to read age:

mov eax, [rdi+0x4]

And to read name:

mov rax, [rdi+0x8]

We can gradually rebuild the Layout Struct based on these Offsets

Of course, this Layout also depends on ABI and Alignment, so we should not always assume a definitive Layout for all Binaries

Distinguish Read and Write

This command:

mov eax, [rdi+0x4]

means the value in Object + 0x4 is read

So:

read field at +0x4

But this:

mov [rdi+0x4], eax

means a new value in Object + 0x4 is written

So:

write field at +0x4

This difference is very important in RE

For example, if we see in several places of the program:

mov eax, [rdi+0x4]

And in another place:

add dword ptr [rdi+0x4], 1

We can guess that +0x4 is probably a numeric value or something with numeric behavior

Why?

Because the program is directly operating on that Memory as a 32-bit value

The size of the Memory Access also gives a clue

For example:

mov eax, [rdi+0x4]

Here we are reading a 4-byte value.

In contrast:

mov rax, [rdi+0x8]

An 8-byte value is read

In a 64-bit binary this value can be a Pointer or a 64-bit value

Now if we see later:

mov rax, [rdi+0x8]

mov rcx, [rax]

Here we have an important clue

The value we read from:

Object + 0x8

was later used as an Address

So it is more likely to be a Pointer:

+0x8 = pointer ?

But keep the question mark for now 😁

In Reverse Engineering, it is better not to draw a definitive conclusion with a quick instruction

Assembly
alone does not tell much, we need to see the Context

Look for duplicate Offsets

One of the very good methods is to check an Offset in several different functions

For example:

Function A:
mov eax, [rdi+0x4]

And:

Function B:
cmp dword ptr [rdi+0x4], 0

And:

Function C:
add dword ptr [rdi+0x4], 1

If RDI in these functions really points to the same Object, there is a high probability that:

+0x4

is a common Field of the same Struct

Now, for example, we see:

mov rax, [rdi+0x8]

And elsewhere:

call [rdi+0x8]

Here we need to check more

Maybe +0x8 is a Pointer Okay

It could be a Function Pointer

Or it could be part of a specific Object Layout

So don't just name it by Offset

Check the behavior of that Field too

Find the Base Pointer

Before we go into Offsets, we need to understand what the Base Register actually points to

For example:

mov eax, [rdi+0x4]

RDI could be pointing to a Struct

But just because it's called RDI, we can't conclude that

We need to follow the value path

For example:

mov rdi, rbx
call process_user
  • ❤ 1
More from @reverseengine
  1. Oct 15, 2026Reverse Engineer Anything v6.5.0 A tool for reverse engineering that allows AI agents to a…
  2. Oct 15, 2026Someone Used AI to Reverse-Engineer PS5 Security in Weeks: What Is REA? https://pub.toward…
  3. Oct 15, 2026How Dangerous Is REA (Reverse Engineer Anything) for Your App? https://21zerixpm.medium.co…
  4. Oct 15, 2026REA Is Impressive. But Reverse Engineering Was Never the New Part https://crizantlai.mediu…
  5. Oct 15, 2026QuarkslaB Dynamic binary Instrumentation https://qbdi.quarkslab.com/introduction @reversee…
  6. Oct 15, 2026angr’s documentation https://docs.angr.io/en/latest/search.html?q=Document&check_keywords=…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →