I spent almost 12 hours yesterday plowing through the game memory, trying to figure out specifically how the Town data was encoded. It ended up being quite an archetypal example of how the game hacking is done. I will try to explain a bit about it.
First the tools of the trade. I use:
Cheat Engine is a super powerful memory editing tool that can access any process running on your PC.
Google sheets is used for two reasons: (i) calculator and (ii) database. Since you need to switch between Decimal and Hexadecimal like a madman, and perform various calculations on those values, a calculator is of course essential. A spreadsheet is a very powerful calculator. Whenever you find out something useful, you also need to jot it down and this is where the database comes in. It is basically a table of useful locations in the game that you can quickly access.
Visual Studio is only needed to create the final software program.
Why visual studio?
Well mostly because it exposes the Windows API in a convenient way. I tend to code in VB.net.
Why VB.net and not C#?
Well many reasons. It is my native programming language and I am rather nostalgic about BASIC. I developed quite some experience in EXCEL programs in VB6. And why not?
The process of hacking the game starts with Cheat Engine. You simply attach the process from the drop down list and then start searching the process memory. There are two basic ways to search either (i) known value or (ii) unknown value.
Known value is the simplest. You may know your Hero has 3 Intelligence. You may also know that when you next level up it will go to 4 Intelligence. You can then simply do a new scan for a byte that is = “3” (and you will get so many thousand hits since there are a lot of things equal to 3 throughout the entire game). However, when you level up and the Intelligence changes to 4 you can simply scan next for something equal to 4 and if you are lucky you get 1 hit. You can then browse to that memory location and change it to 99 (= 63h).
Unknown value requires more patience. Take a look at your movement bar on your hero. Well it might be “full” but you have no idea what “full” is numerically. All you know is that when you move it gets lower. You can then search for something with an “unknown initial value” and then search over and over again for lower values each time you move. When you start a new day you can search for a value that is higher. This takes much more time because by coincidence there might be several hundred other things going up and down in the same pattern.
The nice thing about HOMM3 is that you can also search for “strings” rather than “bytes”. You can simply search for “Solmyr” and you get 3 hits. One of them is “Solmyr” Hero data. Again you can browse the memory at that location.
But what do all those numbers mean?
It is a bit like Matrix code on first glance. But pretty soon you start to notice patterns. Going back to the example of intelligence that we found and set to 99 earlier. You may notice that the 3 adjacent bytes next to the “Intelligence Byte” are equal to 0, 0 and 2 respectively. A quick check of the game tells you that your Attack, Defense and Power are equal to 0, 0 and 2 respectively. You change the 2 to 99 and your Power increase to 99. You have found all your Stat’s by association.
The developers of any game has a logic in regard to how it is structured. It makes sense to group values together in memory as they are grouped together in the game. This makes it much easier for the developers to track and plan the game architecture.
Small numbers are usually safe to toggle randomly. If you find a “5” you can toggle it to a “6” and see what changes in the game. You might inadvertently alter your Hero class, your Hero’s specialty or your movement bar.
Since all the heroes are sequential in memory you can arrange the memory map so you can see both heroes simultaneously and compare values for both to try to figure out to what the bytes correspond. This goes equally for Player and Town data too.
So basically you play “spot the difference” whilst trying to make some logical intuitive changes to the games memory.
Every once and a while the game will crash because you corrupted the memory, but mostly (fortunately) the game does not object to the manipulation.
Sadly for every scenario or campaign you start the value will be moved slightly in memory. So you cannot return to the same location in memory again by absolute address. You need another way to find it.
What you need is a “marker”
A “marker” is a value that is always present, always unique and always has a specific offset to that specific value. A marker makes it it easy to find that value again. With Hero data this is simple, since they are listed by Name and they always follow the same sequence. You can simply scan for Solmyr and for each hit look 1169 (the size of the Hero data slot) bytes further down for the value “Cyra”. When you have this, you know you have found Solmyr’s Hero data.
With the towns this is trickier. All the Town data contain the string “<x”, but there are thousands of “<x” in memory. Evidently it is a common developers block flag. The useful thing about Town data, similar to Hero data is that it is sequential in memory. Each Town data block is 360 bytes. Just like each Hero data block is 1169 bytes. You can calculate this by subtracting the addresses of the first letter of the Hero names for Hero data or subtracting the addresses of the occurrence of “<” from “<x” for the Town data.
Its like a jigsaw puzzle. You need to find the edges first and then fill in the centre.
So when you find “<x” in memory and then 360 bytes later there is another “<x” you have found the town data. Once you have the relative address of the marker. You can apply the absolute offsets and find all the values you already discovered waiting for you.
Happy hunting!