Creating a cheat table - Money Hack
This page is a sub page of: Creating a cheat table - Full guide
Now after a restart, this is what my table looks like.
So let's start with finding the money address. Now as I said in the intro to this tutorial, I have plenty of coins to pick up to find the address, but we just need some coins to help find it.
Now it's good to note that games will store values in some interesting ways for a verity of reasons. Say if we had "$50.75" in some game, you may think "well that's a float", but it may very well be stored as an integer and then get divided by 100 in the running game. Or the stored value could get divided by 2 then subtracted by 1 (this is actually a standard in many games).
In my clean play though I don't remember any multiplier perks for money. And there is no real point to fractional coins without multiplier perks for money. And my thinking is that with the health being an integer I'm willing to bet the coins will be too. So with this game lets just start with an integer and I'll bet it's stored just as we see it in game.
But I leave you to find it.
OK I found my address in 3 scans (but the second one was an unchanged scan that didn't do much so I think 2 would have found it). So to start lets' just set the value then pickup some more coins to see if it sticks.
And mine works but we can see that the coins are not directly within the player structure.
I'll bet there is an Inventory object in the player or actor class when the game or engine was written. I partly base this on the menu inventory and that coins seem to shift depending on what was the first thing I picked up at the start, coins or the sword.
If you have followed along then you may have seen what I just found and that is that my coins did go up in the game, I can even buy things that were to expensive, but the address I found now has a value of 0.
So this may be part of that inventory but for now let's just find the 1 address and not change the value, but see what accesses the address, here I will be testing it just standing, then picking up some coins, then spending coins to find every thing I can, plus going in and out of any menus.
NOTE: I will also be restarting the game to try and help keep the game form shifting it around, the engine may have a security feature against hacking or maybe the compiler or OS could be trying to stop numeric overflow problems. So while the value changes it gets shifted to stop it from happening again.
So after a restart and finding the address again here is what I found.
The red is fired when entering the player menu (not pause menu), when looking at coins, when picking up coins, when entering the store menu, and when exiting the store menu.
The green is fired when picking up coins.
The blue is fired when spending coins.
And the purple is fired when exiting the store menu. This one looks like a inventory lookup to me.
So lets start with the code fire when spending coins to see if any this else gets accessed.
Well I decreased money, bullets, arrows, spring razors, grenades, and runes. So it looks like this is for coins and runes being decreased. Let's look at the memory view form.
Here we see there is a SUB used, so let's just NOP that with a script. But let's set this one up to have the best chance of working even if the game is updated.
So here is the script I wrote.
Here is the AOB:
And on testing this seemed to work.
Now let's work on a money multiplier hack, so let's look at the money increase instruction and see what addresses it accesses. I found only coins were accessed and didn't have any ammo to pickup to test, but if this is an ammo multiplier too then cool.
If you look at the next line of instruction we see a JMP so let's avoid that and inject one line up, this will give us our 5 bytes needed for a JMP and an address.
But just for fun let's pretend that we can't inject there, say there is a JMP strait to the "add [ecx+04],eax" line so this would jump in at part way in our address for the injection jump and crash. So let's go with the "add [ecx+04],eax" line. And again let's set this up as robust as we can, so no hard coded addresses in our script.
So here is the start of my script
If we look at the "jmp 00C0B45F" this will not work for being robust, it may not even work after a load screen or restart. So let's fix that first.
Looking at the memory viewer we can see that the jump is not to far from our injection point and that here the code jump is just 2 bytes, and what it's saying it to jump to, this byte position +46 (hex) bytes.
Where we want to jump to is at address "00C0B45F" on my computer right now, and the injection point is at address "00C0B414". And since "00C0B45F - 00C0B414 = 4B" we just need to JMP to +4B of the injection point.
And here is my working script, note that if there was an update the AOB should still find it but the assert will fail if we are no longer using the right registries and offsets. This will allow use and others to easily update the script, and it wouldn't enable telling us right away that the instruction has changed as apposed to a crash and some debugging to find which script is the problem.
So now we have a working Infinite Money/Runes hack and a Money multiplier hack, now we could merge these scripts but I like spending money so I will not be merging these, but we will see this later when we get back to that extended jump for the super jump hack.
Now let's not forget about those Runes we found.