Game Hacking · Programming · Reverse Engineering

What are Multi-Level Pointers

You hop into game hacking, and one of the very first things you’re facing is pointers.

Many people know how to find multi-level pointers, but few of them actually know what they look like at the high(C/C++) and low(ASM) levels.

Personally, this happened to me, before someone on GuidedHacking taught me.

That’s why I decided to write this small post, to show you what you’ve been playing with.

Small Recap: What are Pointers of 1 Level in the high level (C/C++)

If you come from a programming background, you know that a pointer is a variable that points to another variable by having its memory address.

Let’s take this code(x86) as an example:

int abc = 1337;
int* ptr = &abc; // declare an int pointer and assign the address of abc

printf("Address of abc: %p\n", &abc); // %p is used to show the address
printf("Address of ptr: %p\n", &ptr);

getchar(); // avoid exiting

Now if we hop into cheat engine we can check the value behind ptr.


As you can see, ptr simply contains the address of abc.

Now that you understand a level 1 pointer, it’s time for the real the deal: Multi-Level Pointers.

Level 2 Pointers Example

One instance where these are used is for classes member variables.

Let’s take a look at this example:


class Player
    int health = 100;
    int power = 50;

Player* p = new Player;

int main()
        printf("Player x is: %i\n", p->power);

Note: I didn’t put the variable inside main to avoid it being referenced by ebp, so we can see its real address.

I made it so when you press ENTER the health changes to ease finding the pointer.

Now onto CE:


What I did: Searched for 51, found 5 addresses, pressed ENTER and searched for 52, then I right-clicked->”Find out what writes to this address” and press ENTER again.

Now to find the multi-level pointer you could do pointer scan, manually going through the each “what writes to the address” or just read the assembly as I explained in this post.

I’m always about the later so let’s head over to the “Show disassembler”.


Note: Your assembly might be different, no worries, that depends on the compiler you’re using.

Since this example is pretty simple we can already see that our multi-level pointer(called 2-level pointer) is:

Base - BaseModule + 0x1B2E0
1st Offset - 0x4

But why is that?

So, if you look at the code, you have a pointer to an instance of Player:

Player* p = new Player;

Which shouldn’t be anything new to you, however, the first offset is there due to the structure of our class.

class Player
    int health = 100;
    int power = 50;

We know that the int data type takes 4 bytes. (that’s also why we searched for a 4-byte value in cheat engine)

So by adding 0x4 to the address of Player, we head over to the power member variable.

Oh and this is what the disassembly would look like if we used the health variable instead of power:


As expected, since health is the first member variable, we don’t need to add anything to the address of Player.

Level 3 Pointer Example

Now, we saw level 1 and 2, let’s take a look at a 4th:

class Weapon
    int weaponID = 1337;
    int damage = 25;

class Player
    int health = 100;
    Weapon weapon;

Player* p = new Player;

    printf("Player's weapon damage is: %i\n", p->weapon.damage);

I’ll be skipping the steps to get here since you already know.

If we now check the assembly:


Strange isn’t it? Well, let’s take a look at the structure since we know the address.

By pressing CTRL+D or going to:


Now we can either grab the dereferenced address or the actual “instruction”:


Then paste that into the Group address and define a new structure:


Press ok to everything(seriously, it doesn’t matter) and as you can see:


The class Weapon merged into the Player one, that’s why it is 0x8, it’s 0x4 to get to the weaponID and another 0x4 for the damage.

So we still get the 2-level pointer yet if we change the weapon variable inside the Player class to a pointer, we get a 3-level pointer.

Changes made:

class Player
    int health = 100;
    Weapon* weapon = new Weapon;

    printf("Player's weapon damage is: %i\n", p->weapon->damage);

Checking in cheat engine’s disassembly view(again, same steps):


Now we can see that our multi-level pointer is:

Base: BaseModule + 0x1C2DC
1st offset: 0x4
2nd offset: 0x4

Meaning it is a level 3 pointer.

The first offset is to get the address of the Weapon instance and the second offset is to get the damage member variable.

This is one example where multi-level pointers are used, another example is of course when you actually make a multi-level pointer in the code:

int abc = 1337;
int* onePtr = &abc;
int** twoPtr = &onePtr;

    printf("abc is: %i\n", **twoPtr);

There’s nothing special here, just a pointer that points to a pointer, no offset here either.

We could make another class inside Weapon and have another pointer and we would have a 4 level pointer, there’s no difference except there would be another dereference.

That’s it!

I hope that this has helped you understand exactly what multi-level pointers are and how they’re used.

If you feel like there’s something missing or a part hard to understand, feel free to contact me.

One thought on “What are Multi-Level Pointers

  1. I’d like to thank you for the efforts you’ve put in writing this blog.
    I am hoping to check out the same high-grade blog posts
    from you later on as well. In fact, your creative writing abilities has motivated me to get my own, personal
    website now 😉


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s