[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
Message
Author
User avatar
Administrator
Site Admin
Posts: 5306
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.
doublepointer.png
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.
dpexample.png

User avatar
Administrator
Site Admin
Posts: 5306
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.
diagram.png

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.
player_hp_to_zone.png
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.
zone_to_pzone.png
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.
ptr_chain.png
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.
Attachments
ptrexample.zip
(40.04 KiB) Downloaded 711 times

beastmanjoe
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?

Thanks!

User avatar
Administrator
Site Admin
Posts: 5306
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?

andreoel
Posts: 3
Joined: Sat Aug 04, 2018 6:39 am

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

#5 Post by andreoel » Sat Aug 04, 2018 6:59 am

I did what you said in the post, but it seems the CE always give me the same address everytime i scan hex first address. I tried different pointers, but it always the same address that appears. I always found the green address tho. Help me please?

Oh yeah, the value wont change.. when i freeze and change it to 500, it will go back to 63.. ( it would blink from 63 to 500 to 63 so on, but the real output in game was 63)

Game : seal online

Gameguard : nProtect
Last edited by andreoel on Sat Aug 04, 2018 1:48 pm, edited 1 time in total.

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

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

#6 Post by Administrator » Sat Aug 04, 2018 10:21 am

Sorry, I'm not sure I fully understand. You're trying to find a pointer chain to some information, and in the end you're reaching a green (static) address? That should be exactly what you want.

In some games, the display for things can be off because a copy of the data will be used in multiple different locations, one being the real address and others used for various calculations or display purposes. Lets use HP for example. You might only have one real HP variable, but your searches might turn up 10+ results that always have the same data. One of these might be used during the handling of an HP bar; changing this will not affect your actual HP and instead only the display. Likewise, another instance might change a value used in some hidden way and not be shown to you on your HP bar and will not actually affect your characters health.

That whole discussion aside, what does this value (the 63/500) refer to? Since this is an online game, it's quite possible that whatever you're trying to modify cannot be set on the client side. Most basic information (HP/MP, stat points, damage values, etc.) cannot be simply modified in this way because the server is the one doing all the processing and what you see in the client is only for the visuals. Some information (like character position) can be messed with within reason as it can be computationally expensive to calculate world physics for thousands of players and so some trust is imparted on the clients. Keep in mind that even in things like this, there are still server-side checks (which is why you experience rubber-banding when you're lagging), but if you are able to keep things within those checks you can accomplish useful things; you could increase your movement speed slightly and go by undetected but don't go trying to be running at the speed of light or you're going to get banned, or you can teleport short distances (say, into walls, behind locked doors, up cliffs, use your imagination) while teleporting across the world gets you caught.

andreoel
Posts: 3
Joined: Sat Aug 04, 2018 6:39 am

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

#7 Post by andreoel » Sat Aug 04, 2018 2:16 pm

Yup i've got the green address (after use Find what access this address) like you mention it, but whenever i add it with +1C00 (offset) it will be the same like first address from Damage value that i searched first.
Ex :
First address = 06026C6C5
Pointer address(after addup offset) = P->06026C65

Does it mean that it is the static address?

Now after your reply, i can understand why it can't be changed.

But the things are, i saw a lot of player change the value that i cannot change, like attack speed, Movement speed, no delay skills, etc,. Do these mean that they were hacking to the game's server?

Thankyou very much for replying!

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

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

#8 Post by Administrator » Sat Aug 04, 2018 3:39 pm

Does it mean that it is the static address?
If I'm understanding correctly, you're doing it right. Your static address is 0x06026C6C5, and offset is 0x1C00.

The way it works is that you take your address and add the offset to get 0x6026E2C5. 0x6026E2C5 is just another address, but it's value contains another address (that's what it points to). If you tried to read 0x6026E2C5 as a 4-byte integer, I assume you would get 0x06026C65 or 1613161157, and reading from that address would give you the actual value you're after.

Whether you're getting there by a pointer or by the non-static address, it doesn't matter. If you are seeing the correct value there and changing it doesn't help, then you're doing everything right (to get to where you are at, anyways), just not modifying the correct data. Aside from what I wrote in my last post, there can be other reasons your changes don't work the way you expect. Lets consider attack speed, for example.

In some games, a weapon might have an attack speed associated with it, lets pretend it's 35. You may find the correct address for it and even modify it such that your client now says that the weapon is twice as fast as before (70). When equipping it, your character's attack speed might also improve (100 before the change, 135 now). However, you don't actually attack faster -- why? Because the act of equipping it triggers the server to sending you a full update of your character stats, which then are set in your client, and the attacking animation might not actually be dependent on your attack speed stat, but rather some hidden value - maybe attacks per second or something like that (might be something like 1.0). In these cases, it's often helpful to try using an unknown value search and swapping between weapons, then using increased/decreased/changed searchers. You also can't make assumptions; equipping a faster weapon might mean your speed (and attacks-per-second) goes up, but perhaps the game doesn't use that logic and instead works by delay between attacks which means faster attacks have a lower value not higher. Obviously, you might need to try a variety of different value types: different sized integers, float, double.

Even then, changing something like that client side may not be helpful. If the client isn't telling the server when he/she is swinging the weapon, but rather the server informs the client, you might not be able to accomplish improving your attack speed by changing some stats around. Instead, you might opt to trick the server into accepting wrong values. In World of Warcraft private servers, you could modify packets to accomplish this task, and not by trying to tell the server to attack faster (strangely enough). Instead, you would collect a few equip-able items that would increase your attack speed. The trick begins when you analyze the "hey server, I want to equip this item" packet: it also includes the location of *where* you want to equip it, and the servers (at least years ago when I did this) did not check to make sure this item actually fit in that slot. So, you could do things like equip a speed-boosting shield to your ring slots, or maybe throw some gloves on your head, whatever! Just stack on the attack speed and attack really fast.

Another glitch that could have been abused was in the skill points, but again not by modifying how many points were allocated on the client. You could have a skill that lets you put up to 5 points into it that would each boost your attack speed by 2% for each point; if you screw with the client in such a way that the client lets you keep clicking on the "put a point in to this skill" button, you could put way more than 5 points into that skill. The way this was done in WoW is by putting points into the skill, then swapping the skill ID of that button to trick the client into thinking it was another skill, which means you could then continue putting points into it.

For damage values, something similar could be accomplished in WoW private servers by a abusing a glitch known as an integer underflow. You can research signed verse unsigned integers if you want to learn more. Here's the thing, though: whether an integer is signed or unsigned, it looks the same in memory. Both signed and unsigned, a value of 0 is 0. 1 is still 1. But what happens if you go to -1? Signed, it's still -1 of course. Unsigned integers kind of "wrap around" though, where -1 is the same as 0xFFFFFFFF or 4294967295, -2 is 0xFFFFFFFE, and so on. Whether the program interprets 0xFFFFFFFF as the really big number or -1 was determined upon whether or not the code expected the number to be signed or unsigned. Why is this relevant? Well, if you have a strength value of 10 and are able to in some way get your strength down to -1.... you've tricked the server into accepting that your strength is actually 4294967295. Boom, you can now 1-hit every boss in the game.


Are these kinds of glitches going to work in your specific game? Maybe. Probably not though. Every game is unique, and you just have to kind of experiment and be creative with how you attack your problem.

andreoel
Posts: 3
Joined: Sat Aug 04, 2018 6:39 am

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

#9 Post by andreoel » Sat Aug 04, 2018 4:30 pm

Woaw, what an explanation.. i understand now about the concept.

I checked the unknown value, got the address, but still can't manage to change the value.

So maybe it's time to learn someting about packets

I shall begin my research

Thank you !!

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests