Question About Pointer Tables

Issue #24 new
MyNameIsASecret created an issue

/ This is the main game state object from which you can get to almost anything else. It can only be safely accessed from within the game thread. A pointer to this object can be found in the thread-local storage of the game thread. Windows stores these in FS:[0x2c]. The current location is: (unlikely to change) CContext *localStorage = FS:[0x2c]; CContext ctx = localStorage[0][1];

    It consists of only pointers to other sub contexts and nulled out space.

    The char context offset can be found by looking at the objects before and after the offset
    where it was before and compare to the CharClient::CContext description.

How do you get to FS:[0x2c] on the local storage memory for gw2?

Comments (6)

  1. MyNameIsASecret reporter

    and once you get to that local storage location, how do you identify the structure changes, for example, I believe 2FCE9E0 is the current value and I found the address with it stored and made a pointer so I can return to it but what do I do now to find the other locations with a knowledgeable approach rather than randomly guessing and hoping I figure something out.

  2. hairys

    We reverse engineer it. We start out on the micro level (e.g., scanning for the location that holds my character's current health) using scan tools like cheat engine, then follow the (assembly) code until we find what points to it. We examine the code that accesses each part to determine what accesses it. We keep "following the code" back up the pointer chain until we get to the macro level, which is usually a global variable of some kind.

    The pointer chain would look something like this for a character's current health:
    (MainContext)(FS:[0x2c]) => (CharContext)(0x48) => (array of Char pointers)(0x34) => (Character struct)(pick any from the array) => (Health struct)(0x204) => (float)(current health)(0x8)

    Once we find the main context, by following everything up to it from my character's health, we'll add a pattern that is not likely to change to gw2lib. In this case, the pattern that accesses the MainContext is: "64 A1 2C 00 00 00 8B 04 88 8B 80 04 00 00 00 C3" (see main.cpp for GetContext).
    btw, TLS = thread-local storage. This means only a specific thread can access the MainContext. The main game thread is the only thread that can access MainContext Trying to access it from any other thread will crash.

  3. MyNameIsASecret reporter

    so the main context to hp pointer would be Scan (MainContext) -> 48 (CharCntx) -> 34 -> Chosen Structure (CharStruct) from array (selected for specific entity by some means) -> 204 (HPstruct -> 8 (all numbers in Hex) which would give the value of the current HP pool of the selected entity, which is how you find the float to draw on a targets hp bar. this is the full path for the normal game not inside gw2 lib? (I have not been able to get home and check yet) Now the question, how do I determine which structure to use? I know there must be a way to figure out which structure is the targets (I guess there is some way to separate by target agent's ID/shard, though I don't know how you would go about such a task.)

    Thanks for your help and sorry for needing advice on such basic stuff!

  4. hairys

    "this is the full path for the normal game not inside gw2 lib?" - Correct.

    There's always some code that's handling every structure in the game and that is what we're interested in - the code. The code will tell us how it's handling the structure (e.g., how it's created, what the different members of the structure are, etc.). That's what it means to reverse engineer; to figure out how something works based on very little information. We do this by observing the game as it is running (setting breakpoints in a debugger and watching memory). We'll eventually figure out how it all works.

    For example, here's a screenshot of the debugger that I use:

    Untitled.png

  5. Log in to comment