2

I'm familiar with finding a player base pointer as-well as other values in games, and finding offsets and such. And I have applied that to some of my own code in the past.

But does this practice apply to instances of any class?

Here's an example program.

using namespace std;

class A {
public:
    int i = 0;
    virtual void doThing() {
        i++;
        cout << i << endl;
    }

};

int main()
{
    A* a = new A();
    while (1)
    {
        a->doThing();
        Sleep(6000);
    }
    system("pause");
    return 0;
}

I used Cheat engine to find the address of the variable i in A::doThing. Then I used the option to find what writes to that address. From there I found what appeared to be an offset, did a pointer scan and found that example.exe+0x001A2EC was a static pointer and the value held by i was at offset 0x4.

Would example.exe+0x001A2EC be considered the pointer to the instance of class A?

What I'm trying to do is basically make a copy of the target program's pointer to the instance of class A, then access it's V-Table in my own code which is to be injected into the process.

This is how I was trying to achieve this.

DWORD Base = (DWORD)GetModuleHandle(0);
A* a = (A*)(Base + 0x1A2EC);
void** vtable = *(void***)a;

If there's something wrong with my understanding or methodology please do point out what i am doing wrong, or suggest some other way which I can get a copy of the pointer.

2

I'll start with a few minor corrections and clarifications, just to make sure we're using the right terms and exact definitions.

I used Cheat engine to find the address of the variable i in A::doThing

First of all, i is not a variable of method A::doThing. It is a member of the A class.

Then I used the option to find what writes to that address

Doing this gives you the address of method A::doThing is located. Specifically, the address at which A::i is modified within that method.

from there I found what appeared to be an offset, did a pointer scan

I would assume you found the offset of A at which i is located, but I'm not 100% I understand what you mean by "did a pointer scan". I assume you subtracted the offset of i from the address found at the first stage ("I used Cheat engine to find the address of the variable i") to get the address of the object itself, then searched for pointers to that address.

Would "example.exe"+0001A2EC be considered the pointer to the instance of A class?

To be more accurate, example.exe+0x001A2EC would be an address of a variable of type A * (or pointer to an A instance), and it's value will be the value returned by new A();, i.e. an instance of class A, as you expect. Reading it's value will point you to where that instance of A is currently in memory.

However several assumptions you have may change between releases or even for different compiled versions of the same code base.

The most obvious one in your example code, is the fact you're using the exetuable's image base to access the main thread's stack. This is likely to break depending on how/where the stack is allocated for your process, and is likely to be unreliable even if executed several times in succession, depending on OS and configuration.

Even if you somehow address that, there are multiple other potential complications and slight changes that could make your life harder. To name a few:

  1. Even if you were using the process's stack offset instead of the image base, the offset in memory where the A pointer variable, a, is located is likely to change. even just between different executions of an identical binary. For example, in your case a is stored on the stack, and if the function defining a could be called in several different flows, the stack depth at which the stack frame of the function creating a may differ. if a function a_creator may be called in either one of two flows main/a_creator and main/game_load/a_creator depending on circumstances (e.g. if you're loading a save), the offset at which a_craetor's stack frame will start will be different.
  2. The offset at which i is located in the A class's internal structure, may be changed because new members were added in the code. Although normally maintain the order members are defined at, optimizations may shift them around for better alignment. Different padding configuration settings may also change the location a member is actually at.
  3. Different optimization configurations may even completely eliminate the variable a, only storing it in a non-volatile register. This is very likely in the example implementation you provided, for example.
  4. A new version of the program can easily create move variables and make code changes so locations will be completely off.
  5. Inheritance and casting of a could lead you to different VTables than the ones you were looking for, as well as other complications.

I hope this did not discourage you from pursuing your goal, but encouraged you to gain a better understanding of the internals and intricate world of dynamic patching.

As a side note I'll include a warning about anti-cheat detection tools in a lot of games could make these endeavors quite expensive (account bans, etc).

  • Is there some other way to get the pointer to the A instance? Maybe by signature scanning? Also, i don't quite understand how this differs from finding a static pointer to a player class in games as I've done before. (Just to clarify also i don't intend on getting accounts banned anytime soon, anything I've done with games has just been for the purpose of learning, and done using insecure servers.) – Michael Strobel Aug 23 '18 at 3:45
  • 1
    Static variables (pointers or not) reside in a fixed location relative to the executable's image base. the stack does not. As for suggestions for a better solution, I think you should start another question and describe your specific scenario (instead of an example program), although most of it will probably be derived from what I said here. – NirIzr Aug 23 '18 at 5:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.