TL;DR
We will find the player's coordinates and also find the camera's position. This should help us to create a proper fly hack!
Introduction
I want to be able to fly around in the Pwn Adventure 3 especially because my first attempt at flying was not so great. I was only able to jumping high and float down slowly, or I could also somewhat freeze myself in mid-air, but it was very glitchy because of gravity. Hence it wasn't a great experience like you would imagine flying to be. So let's try this again on Windows.
Finding height
To fly around we need to find where the position of the player is stored in memory. To do that we need to use the incremental scanning option provided by Cheat Engine to find the address. But we don't know exactly what we are looking for.
- We don't know how the x, y & z coordinates are stored.
- Also, we don't know much about the orientation of the coordinate system to see if walking in a specific direction will increase or decrease the coordinate values.
It's absolutely fine to do some trial and error with assumptions, but then I was watching a guided hacking video, and they were scanning for the height position - and that makes perfect sense because it's very likely that when you are higher or lower, the value would increase or decrease.
So let's start our value scan with a first scan set to an unknown initial value, and we find about 168 million. Now we want to increase the height coordinate value, so we switch back into the game and walk up to a higher elevation and rescan. Now we have ~800k left. For good measure, we can scan for an unchanged value, and we have moved down to about ~400k possible addresses.
Hopefully, we can bring the number of possible addresses further down with the process we have already been doing a few times. Eventually, we reach a point where we have a lot of similar values that seem to be connected to the position.
To filter out the last few dozens or hundred of addresses, we can try to freeze the address' values. This will be an indicator for us to see if we have the correct value. Freezing all the suspected values will not let us jump properly, and that's exactly what we are looking for. You can freeze the values with the checkbox in the table, or pressing [space].
We can select only half of them, so that we can do a binary search for the value that froze our position. When we freeze a value, Cheat Engine will continuously set the value to the original one, and this should kinda freeze the player's height. Now based on the results of the first half, we continue making binary search decisions.
In my case, the first half did not work, so I selected the other half of the remaining addresses, and when I tried to jump, I was immediately pulled back to our current position this means that one of these addresses control the character's position. So I deleted the addresses that I didn't select and repeated this process. Eventually we get it down to just a few addresses in the list and find the real value.
So to quickly test this, let's see what happens when we modify the value by setting it 2000
.
And we teleport! A little bit into the air, and felling back down.
Find other Coordinates
Now that we have a way to modify the position of the character along the up/down axis, it's time for us to find the other coordinates. But how?
Well, typically, we store a coordinate or a position value in a simple struct or array like (x,y,z), which means the other values should be right next to each other. So to find out the adjacent values, let's open up the memory view and observe. When we look around in the game, we see multiple values being updated. So these values seem to relate to the camera view direction. And when we don't change the camera's position but simply walk around, we see three packs of three values being updated. They could be X, Y, and Z.
The height value that we could modify is right next to the other coordinates! Now let's add these addresses to the list and try modifying them. Let's set X it to 0
. We teleported to somewhere under the map! We are actually below Blocky's Revenge challenge room.
While playing around with the teleportation, the game crashed, which means all the values we had before are useless now. We have to do it all over again. As you can see, it can be tedious from time to time.
Pointer Scan
After finding the values by doing it all over again, it's time to do some pointer scans so that we don't lose the correct values. For finding the pointer, I want to do something special for the base address. We set the From and To range like shown below.
Cheat Engine supports strings as the address of a module. From last video we already found pointers based on this module, so I assume this could be a good reliable start for pointers. After the scan, we find about 99 different pointers from the base address. Our original offset from last video for the selected skill was at 0x0097e48
- let's see if we find that in the list.
So let's add a few of those to the address list, and then we kill the game, restart it, login, select a character and attach the Cheat Engine to the new Pwn Adventure process. Now if we look at the list, it points to some actual values. This looks good.
If we check out the pointer scan results from earlier, we see that some of them point to the correct values, but also many don't. But now that we have the right value, we can rescan the pointer list for only valid chains.
After the scan we have about 18 left and all of these should work. As you can see, they are just some kind of variation from another. This gives us confidence that the pointer path we found is reliable.
The Interesting Address
When I was doing all of this, to look for the player's position, I found another address that has an interesting behavior. It doesn't teleport the player but instead teleports the camera.
If we change the value of this address, we teleport, but we stay in mid-air. Gravity doesn't seem to apply to this change - because it's the player's camera, not the player. However, as soon as we move the camera it gets updated and we are back down.
Looking around the vicinity of the address, we can find the other coordinates as we did before and we can see it update when we move around. Also, we can find some other values that seem to be connected to the view direction, and when changing them, we also seem to control the camera tilt.
When I saw that I had an idea. I always wanted to fly around properly but the gravity in-game was always a problem. But it looks like we can fly freely without being affected by the gravity if we used the camera instead of the player.
We need to find a way not to update the camera view once the real character is moved. To do that first we can, of course, check what updates this variable or what writes to this memory location. We can use that cool Cheat Engine feature "Find out what writes to this address - F6" and then we go into the game, move the camera and we see the instruction in the assembly that writes to that address. We can override this assembly instruction with nops (No Operation) - doing this will simply do nothing anymore.
Now if we go into the game and move the mouse, nothing happens.
We can also freeze the position of the camera by doing the same thing. We find out which instructions write to the variable and replace the instruction with nops. Now we can't move at all, but we can update the values from Cheat Engine, and it updates in the game. This means we should be able to create a "game hack" that allows us to fly around the map as we like. However, that's for the next blog post, stay tuned!