Hello there!
In this post, you’ll learn how to get pointers by reading the assembly code that accesses the variable.
Requirements:
- Debugger (for example: Cheat Engine, x64dbg, etc)
- IDA Pro with Hex-Rays Decompiler (makes it a little bit easier, can just read the interpreted assembly)
Assembly knowledge is also good to understand what’s going on.
This method is not pointer scanning and also not the one where you keep looking for this:
The pointer scan is easy however a lengthy process.
The one looking for where the address probably points to is also easy however really tedious and most of the time you’ll pick the wrong path.
So a harder, however, more reliable and faster way is by reading the assembly and checking how it is accessing our wanted variable.
At first, I was making a mistake that took me around 30 minutes to figure out, at the end of the post I’ll say what it was.
To start off, we are going to find our wanted variable.
Next, we look at what accesses this address:
I’ll pick the first one but it doesn’t really matter in this case, however, look for your results and see which one should be easier to read.
Now make it show in the disassembler and this is the code that’s accessing our variable:
We can already see an offset! Which is 0x1AF0, as it is dereferencing eax+OFFSET.
Now we gotta see where that eax comes from, and it is right above this line, it is putting the value of ebp-0xC1C into the eax, it might seem strange that it is accessing from a negative offset right?
Well, a stackoverflow answer says that this sometimes happens when a function accesses its base/super class’ members.
So as we can see this doesn’t say much about the rest of the offsets and base address.
Let’s take a look in IDA(I already have the binary analyzed), for that you go to the disassembly view and press G to go to an address, paste that address then press F5 to pseudo decompile:
Now we need to find how it gets v189 so let’s highlight that and scroll up:
So we need to find the function that is calling this one to get the this pointer.
Copy the function address and go to that address in the disassembly view:
Sweet! Let’s see how this function sets up the this pointer by double-clicking on the CODE XREF address then F5 it to pseudo decompile:
Another offset 0x71C, Hooray! But we still need to know where that v79 comes from.
Tip: Keep a notepad open to write down the offsets to avoid having to re-do stuff, as well as a calculator in programmer mode in case you happen to need hexadecimal calculations
Ok… Another this pointer, so let’s see what calls this function!
Again, let’s see how it is getting the v12… Hold on a second! This does not have an offset, which means that v12 should hold the base address.(or not because of +0 offsets but that’s not the case)
Yet another this pointer, sigh. Same thing as we did before, see how it is being called.
Finally! We got the base address, well not yet, we need to see how that sub_4D6DF0 gets that base address.
There we go, 0x11B7028, as you see in the return, is the base address since this game binary doesn’t have ASLR, we don’t need to rebase IDA or use the game’s module handle to get the address.
And this is where I did my mistake the first time, I looked for the address that 0x11B7028 was pointing to instead of simply using that address, sigh.
So we end up with the pointer: base=0x11B7028 offsets={ 0x71c, 0x1af0 }(FIFO)
If this binary had ASLR we would need to do the following:
Edit->Segments->Rebase Program
So in our code, the base address would be:
base=0x11B7028-IDA Base+GetModuleHandle(0)
Where the GetModuleHandle returns the address of the game’s module.
You can also just rebase IDA to 0 and simply:
base=0xDB7028+GetModuleHandle(0)
That’s it!