[Tutorial]Pointers and offsets part 2 - Double pointers (CE)

You can find tutorials and ask questions about memory editing here. You may also post any game-specific information you find (ie. cheat tables or addresses).
Post Reply
User avatar
Site Admin
Posts: 4850
Joined: Sat Jan 05, 2008 4:21 pm

[Tutorial]Pointers and offsets part 2 - Double pointers (CE)

#1 Post by Administrator » Fri Dec 11, 2009 6:46 pm

Since this is a frequently asked about topic, I decided to make a short tutorial. If you haven't already, you must first read part 1 that thoroughly explains the method that will be used again here. There are other methods around, but it is quickest, easiest, and almost always works.

First, let me explain what a double pointer is. It is a pointer that points to a pointer that points to a value. Sounds confusing, doesn't it? To simplify, you just need to repeat the process you've already done to get a pointer to what you've already found. That's it.
In this example, we have found the player's HP (which is currently 125) and resides at the address 0x3F408C68. After looking up the pointer to it (as per tutorial part 1 shows), we find that 0x20248844 + 0x8 points to 0x3F408C68. When we found the pointer (0x20248844), you probably noticed it was not showing as green in Cheat Engine - meaning it is not static.

Restarting the game, changing maps, or any other assortment of things could cause our pointer (0x20248844 + 0x8) to become invalid and point to something other than our player's HP. To get around this, we need to make a static pointer chain. This is simple enough. First, manually add 0x20248844 to Cheat Engine's address list (by clicking the button just above and to the right of the address list at the bottom of the window). Next, you'll find what points to it by following exactly the same method that tutorial 1 outlined.

Now, we should find the offset 0x4 and address (which is static!) 0x0040201C. That's all there is to it. Now, whenever we restart the game/change maps/etc., 0x0040201C + 0x4 will always point to <some changing address>, and <some changing address> + 0x8 points to our HP.

The below example is taken from Runes of Magic. The static pointer in this case is 0x00901990 + 0x58C, which points to 0x0424E58C. 0x0424E58C + 2CC points to 0x15712ACC. 0x15712ACC contains our player's HP: 305.

User avatar
Site Admin
Posts: 4850
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Tutorial]Pointers and offsets part 2 - Double pointers

#2 Post by Administrator » Fri Apr 17, 2015 5:15 pm

To expand on this, I've written up a real example that you can step through yourself. I have created a sample program that implements a pointer chain to access a player's HP. Download a copy of it at the bottom of this post (ptrexample.zip). The program contains a pointer to the zone struct, and the zone contains a pointer to the player. The player struct itself contains the player's HP. See the below diagram.

Upon opening the program, it will display the various pointers and addresses. Obviously your real target program won't show all of this info to you, but it is only for an example so that you can understand how it fits together and ensure that you are on the right track. The below is an example only and your exact addresses may change, but the methodology should stay the same.

Code: Select all

pZone is located at 0x00419008 and points to 0x005C78F8
Zone is located at 0x005C78F8 and points to 0x006F00C4
player is located at 0x005C78F8 + 0x400 = 0x005C7CF8
Player HP is 1234 and located at 0x006F2A98 + 0xC = (0x006F2AA4)

If you want, you can manually search for the player's HP, or simply add the address (0x6F2AA4 in this example) manually.
We right-click the address and select "Find what accesses this address." Go back to the sample program and press a key to change the player's HP. Notice that our offset is 0xC.
Double-click the instructions to bring open the 'Extra info' window, which tells us which address to search.
Search for the address.
So far we have found that the player struct is at address 0x6FA98, and offset 0xC gives us the player's HP. In the program's output, we can see that player address (0x6FA98) + 0xC is the address of our HP, so everything is adding up nicely so far.

In the search results, you'll notice that there is two results: 0x28FEF8 and 0x5C7CF8. It is not uncommon to have more than one result, but in this example we're going to ignore the first result as we know the second is the correct one. Why is it correct? Pretend we investigated the first and found it to be inconsistent; the real reason is that 0x5C7CF8 is awfully close to the zone's address that is displayed on the top line in the program, and we know that something in zone points to our character (again, see the first diagram).

So how close is 0x5C7CF8 (our found address) to 0x5C78F8 (our zone address displayed by the program)? If you subtract them, you get 0x400... which just so happens to be the exactly what we expected from the first diagram! I bet we'll be seeing these two numbers again soon.

Add the address (0x5C7CF8 in our example) to the bottom list by selecting it and using the red arrow at the bottom-right of the search list. It is displayed in black because it is non-static, which means we need to find a pointer to it. That means we start the whole process over with the only real difference being that we're using our new address instead.
We checked the address for what accesses it,
Notice it uses offset 0x400,
Plugged the next address given by our Extra Info window into the search,
and end up with a static (green) address! We have all the information we need now.

0x419008 points to zone. zone + 0x400 points to player. player + 0xC is the address of the player's HP.
Try adding a pointer manually with the static (green) address you found, the zone offset, and then the HP offset.
If pZone was not a static (green) pointer, that would mean that there is another level to look for, and so we would instead continue to reiterate over these steps until we find the root address.
(40.04 KiB) Downloaded 164 times

Posts: 1
Joined: Thu Jun 28, 2018 10:17 pm

Re: [Tutorial]Pointers and offsets part 2 - Double pointers (CE)

#3 Post by beastmanjoe » Thu Jun 28, 2018 10:39 pm

Hey there, first off thanks for the tutorial, I found it very helpful

I am running into a problem though after finding values and their pointers and the pointers to the pointers I'm eventually given a green address in CE

Copy pasting the green address in CE gives me game.ddl+46d8 for example, however upon loading a new level all the old values are cleaned up as garbage and new pointers are used

To recap I'm:

Finding an address by value
Finding opcodes for the address + offset
Adding addresses as a pointer with the offset + type
Next I'm finding out what accesses that address and here's where maybe I'm getting lost

With CE 6.7 it asks if you want opcodes that are accessing the pointer or the pointer's address

Finding opcodes that access the pointer I get a new hexcode to search but there's no offset
Searching it I get two addresses, one green, one non-green

These values work for a little bit, but eventually they stop working -- any ideas on what I'm doing?
I know lots of people talk about tools like pointerscan and things like that, should I be using that? How can I use that?


User avatar
Site Admin
Posts: 4850
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Tutorial]Pointers and offsets part 2 - Double pointers (CE)

#4 Post by Administrator » Fri Jun 29, 2018 7:19 pm

So you've gotten to a green (static) address, but the pointer chain breaks after loading a new level?

When you then reapply the same method from the start, do you then return back to the same green/static address, or is it different every time? Have you perhaps checked to see if anything is pointing at the static address?

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest