This is a commonly asked question!
How do I find the end address of a multi level pointer using C++?
How to use a pointer in C++?
How to calculate pointers with offsets?
Perfer video tutorials? This code is covered in this video:
Background
A pointer itself points to only one address. But when you have a list of offsets you can walk that pointer chain to find the end address.
When you find a pointer in Cheat Engine, what you're finding is a path from one address to another using pointers and relative offsets. This is how computers locate and act on data stored in memory. It's not magic! The logic behind this is based on 2 important features of modern object oriented programming:
The baseAddress or first pointer in the pointer chain is generally one that exists in static memory, meaning it's always located at the same address or can be accessed using a relative offset from the base address of a module.
Imagine this code:
Class:
Health is offset 0x0, armor is offset 0x4 and name is offset 0x8, because int is a 4 byte variable in this example(32bit x86)
First line:
PlayerClass is the name of the class, the "*" tells the compiler that this is a pointer to an object of type PlayerClass and it's identifier is "localPlayer". In this example it is not initialized. Meaning, no memory has been allocated for it.
Second line:
When the player starts a game, the localPlayer object is allocated a spot in memory on the heap and the pointer is assigned the address of the object.
The address of the localPlayer object wouldn't be consistent and you would need to find a pointer to it. If you used Cheat Engine's "Find What Accesses this Address" or the pointer scanner you would find a pointer with the BaseAddress of the localPlayer pointer and offset 0x8.
It simply uses the same logic that the computer does to find the address of the variable. In the source code of this application if you wanted to get the value of name variable you would use the "->" (the structure dereference operator) like this: "localPlayer->name".
When the compiler compiles this code into assembly the logic that the code follows is this:
We can manually do it for every pointer by doing something similar to:
But you don't want to waste your time doing that for every pointer, instead you make a function that does it for you:
We want to emulate that exact logic in our function and make it able to handle the de-referencing of multiple offsets.
Here's a function that does that for x86 and x64, it's a hybrid of code from Fleep, Rake & IXSO
External:
To get the Current Weapon Ammo address you would do it like this:
Internal:
Need to learn how to find multilevel pointers?
START HERE Beginners Guide to Learning Game Hacking - Guided Hacking
Still confused about what a Multilevel pointer actually is?
WTF are Multi Level Pointers Tutorial - Guided Hacking
How do I find the end address of a multi level pointer using C++?
How to use a pointer in C++?
How to calculate pointers with offsets?
Perfer video tutorials? This code is covered in this video:
Background
A pointer itself points to only one address. But when you have a list of offsets you can walk that pointer chain to find the end address.
When you find a pointer in Cheat Engine, what you're finding is a path from one address to another using pointers and relative offsets. This is how computers locate and act on data stored in memory. It's not magic! The logic behind this is based on 2 important features of modern object oriented programming:
- Applications are made memory efficient by dynamically allocating memory objects only when needed and assigning pointers to point at them only when needed.
- Classes can contain member variables that are pointers, specifically pointers to other objects in memory.
The baseAddress or first pointer in the pointer chain is generally one that exists in static memory, meaning it's always located at the same address or can be accessed using a relative offset from the base address of a module.
Imagine this code:
C++:
class PlayerClass
{
public:
int health;
int armor;
char* name;
}
PlayerClass* localPlayer;
localPlayer = new PlayerClass();
Health is offset 0x0, armor is offset 0x4 and name is offset 0x8, because int is a 4 byte variable in this example(32bit x86)
First line:
PlayerClass is the name of the class, the "*" tells the compiler that this is a pointer to an object of type PlayerClass and it's identifier is "localPlayer". In this example it is not initialized. Meaning, no memory has been allocated for it.
Second line:
When the player starts a game, the localPlayer object is allocated a spot in memory on the heap and the pointer is assigned the address of the object.
The address of the localPlayer object wouldn't be consistent and you would need to find a pointer to it. If you used Cheat Engine's "Find What Accesses this Address" or the pointer scanner you would find a pointer with the BaseAddress of the localPlayer pointer and offset 0x8.
It simply uses the same logic that the computer does to find the address of the variable. In the source code of this application if you wanted to get the value of name variable you would use the "->" (the structure dereference operator) like this: "localPlayer->name".
When the compiler compiles this code into assembly the logic that the code follows is this:
- Dereference the localPlayer pointer to get the dynamic address of the object
- Add offset 0x8 to get to the name pointer
- Dereference the name pointer to get the dynamic address of the name value
We can manually do it for every pointer by doing something similar to:
C++:
ReadProcessMemory(handle, (LPVOID)pointeraddress, &newpointeraddress, sizeof(newpointeraddress), NULL);
ReadProcessMemory(handle, (LPVOID)(newpointeraddress+ offset[0]), &newpointeraddress, sizeof(newpointeraddress), NULL);
ReadProcessMemory(handle, (LPVOID)(newpointeraddress + offset[1]), &newpointeraddress, sizeof(newpointeraddress), NULL);
ReadProcessMemory(handle, (LPVOID)(newpointeraddress + offset[2]), &newpointeraddress, sizeof(newpointeraddress), NULL);
We want to emulate that exact logic in our function and make it able to handle the de-referencing of multiple offsets.
Here's a function that does that for x86 and x64, it's a hybrid of code from Fleep, Rake & IXSO
External:
C++:
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size(); ++i)
{
ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
addr += offsets[i];
}
return addr;
}
C++:
uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, { 0x374, 0x14, 0x0 });
C++:
uintptr_t FindDMAAddy(uintptr_t ptr, std::vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size() ; ++i)
{
addr = *(uintptr_t*)addr;
addr += offsets[i];
}
return addr;
}
START HERE Beginners Guide to Learning Game Hacking - Guided Hacking
Still confused about what a Multilevel pointer actually is?
WTF are Multi Level Pointers Tutorial - Guided Hacking
Last edited: