Source Code FindDMAAddy - C++ Multilevel Pointer Function

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
11,574
78,998
2,317
HOW TO POINTER C++?!?!
( need a C# version? )
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:
  • 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();
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:
  1. Dereference the localPlayer pointer to get the dynamic address of the object
  2. Add offset 0x8 to get to the name pointer
  3. 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);
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:
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;
}
To get the Current Weapon Ammo address you would do it like this:
C++:
uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, { 0x374, 0x14, 0x0 });
Internal:
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;
}
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
 
Last edited:

Rake

Cesspool Admin
Administrator
Jan 21, 2014
11,574
78,998
2,317
Make A youtube video on this plz
Everyone struggles with understanding pointers, you just have to keep at it and eventually it will click in your mind and you will understand it.

The absolute most important thing is you need to LEARN C++ first. Use our code, get it to work and then step through it with the Visual Studio debugger until you understand it. If you run into trouble, ask a question
 
Last edited:
  • Like
Reactions: ATrashyProgrammer

ATrashyProgrammer

Full Member
Jun 26, 2018
8
4
0
Everyone struggles with understanding pointers, you just have to keep at it and eventually it will click in your mind and you will understand it.

The absolute most important thing is you need to LEARN C++ first
I'm Pretty decent at C++ I take courses at Udemy so I don't think that's a problem. It might be that this is just the first time I'm trying to create a game hack
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
11,574
78,998
2,317
Well pointers are just variables that contain addresses, they are an integral part of c++. If you understand c++ well, understanding pointers is not a problem.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
11,574
78,998
2,317
Someone was just needing an internal version of this so here you go, does not include any error checking, just for PoC
C++:
uintptr_t FindDMAAddy(uintptr_t ptr, uintptr_t offsets[], unsigned int numOffsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < numOffsets; ++i)
    {
        addr = *(uintptr_t*)addr;
        addr += offsets[i];
    }
    return addr;
}
 

coltonon

Newbie
Full Member
Dec 18, 2017
6
298
1
Someone was just needing an internal version of this so here you go, does not include any error checking, just for PoC
C++:
uintptr_t FindDMAAddy(uintptr_t ptr, uintptr_t offsets[], unsigned int numOffsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < numOffsets; ++i)
    {
        addr = *(uintptr_t*)addr;
        addr += offsets[i];
    }
    return addr;
}
Howdy, my first post over here, coming from UC.

If you've already got the classes mapped out, just declare an instance and deref normally. This is also great because you don't directly work with offsets anymore.

Externally you want to stay as close to that as you can.

C++:
template <class C>
C read(DWORD_PTR(Address)) {
    C c;
    ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(Address), &c, sizeof(c), nullptr);
    return c;
}

C++:
//internal
Offsets::ClientGameContext* pStaticGameContext = (Offsets::ClientGameContext*)OFFSET_GAMECONTEXT;
//access player manager
pStaticGameContext->GameContext->PlayerManager

//external
Offsets::ClientGameContext pStaticGameContext = mem.read<Offsets::ClientGameContext>(OFFSET_GAMECONTEXT);
Offsets::GameContext pGameContext = mem.read<Offsets::GameContext>(pStaticGameContext.GameContext);
//accessing player manager
Offsets::PlayerManager pPlayerManager = mem.read<Offsets::PlayerManager>(pGameContext.PlayerManager);
The philosophy is to keep internals and externals as similar as possible when it comes to reading/writing. Only difference is you have to call RPM every time you need to dereference, otherwise you can use the same reclass output after changing every pointer to something like a DWORD_PTR.
 
  • Like
Reactions: Rake

hage_fale

I`m gay
Dank Tier Donator
Dec 21, 2015
1
264
0
Is it possible to Make that it automatic detects how many stages(level) the Pointner have? Its just a theoretically question.
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,279
37,938
268
Is it possible to Make that it automatic detects how many stages(level) the Pointner have? Its just a theoretically question.
use an stl container that would have a size property
 

sayewivifi

Full Member
Feb 2, 2019
39
228
0
  1. Dereference the localPlayer pointer to get the dynamic address of the object
  2. Add offset 0x8 to get to the name pointer
  3. Dereference the name pointer to get the dynamic address of the name value


———

When you deterrence name pointer to get address of name value, can you explain this part?

Isn’t name pointer pointing to the name property’s address?

If you deference the name pointer that’s pointing to the name property, aren’ttly accessing the name ? Why is it getting dynamic address of the name value instead?

I don’t get it, pls correct me, thank you
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
11,574
78,998
2,317
When you deterrence name pointer to get address of name value, can you explain this part?
Isn’t name pointer pointing to the name property’s address?
If you deference the name pointer that’s pointing to the name property, aren’ttly accessing the name ? Why is it getting dynamic address of the name value instead?
When we say dereference during reverse engineering, we are talking addresses. In C++ if the pointer has type char array, dereferencing it gives you that address represented by a null terminated char array.

Don't be confused by this, a pointer is just an address that contains another address. Any "typing" of the address is only understood as a construct for the compiler.
 
  • Like
Reactions: Amir

myspring

Dank Tier Donator
Jul 9, 2018
39
448
0
_wcsicmp compares strings and returns comparing result as an integer. But what is the meaning of this "!_wcsicmp(procEntry.szExeFile, procName)" if it's not a boolean?
Does the "!_wcsicmp" mean "if equals to"?


Relevant snippet of code:

C++:
if (!_wcsicmp(procEntry.szExeFile, procName)) //приводит строки в ловеркейс и сравнивает их
                {
                    procId = procEntry.th32ProcessID;
                    break;
                }
 

myspring

Dank Tier Donator
Jul 9, 2018
39
448
0
_wcsicmp compares strings and returns comparing result as an integer. But what is the meaning of this "!_wcsicmp(procEntry.szExeFile, procName)" if it's not a boolean?
Does the "!_wcsicmp" mean "if equals to"?


Relevant snippet of code:

C++:
if (!_wcsicmp(procEntry.szExeFile, procName)) 
                {
                    procId = procEntry.th32ProcessID;
                    break;
                }
What i found is that: if (c) is the same as if (c != 0). And if (!c) is the same as if (c == 0).
That's make clear why it works.
 
  • Like
Reactions: Zanzo420
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods League of Legends Accounts