RWP Hacking Class #4

Welcome to the fourth RWP Hacking Class, thank you for coming.

Last time we learned about bitflags, and applied them to the Stop N Swop cheats in Banjo Kazooie. Today, we're going beyond basic code hacking a little bit, and looking into pointers and size modifiers.

First, we need to learn what a pointer is, then we'll get right into hacking. A pointer is a 32-bit address that "points" to something else in memory.
What does it look like?
For example, a pointer would be 80234567 (32-bits), or 80012B4A. Anything like that, it's just specifying an address.

This address could hold data about the object, could be a pointer to the next or previous object, or many other related things. For example, in Goldeneye, the cut-scene modifier I hacked out is a pointer. The pointer holds which cut-scene is the current one chosen. So in Dam, if for example it held 80000004 (note not real address), it pointed to data from cut-scene 1 If it held 80000014, it pointed to data from cut-scene 2 If we fixed the value to always be 80000014, it would always play cut-scene 2. Also important, you would realize that whatever data IS at 80000004 and 80000014 IS the cut-scene data. So if we went there, we might notice three coordinates, or something telling us about the cut-scene.

When we do any code-search, usually we get bits and pieces of pointers in our results. If you do a 32-bit aligned search, it's easy to just ignore them (they look like 80XXXXXX) But in 8-bit, it takes experience to realize which are pointers and which aren't. If you think it is a pointer, you must ensure you turn on all four codes nearby, or your game will crash. Why? Well if you have a pointer normally 80 12 34 56 in memory. When you hack it, you find that you have found the 12 and 56 in the code results.

If you fix those two, but the game modifies the pointer to 80000000
You notice that your new code will be 80120056, which is invalid, and will crash (we really wanted 80123456) So you will need to generally find which are pointers in your results, and if you think your code is a pointer, put on all of the pointer parts, if not, ignore them. What's important to note for our purposes, is that when you have a pointer, it usually points to related data.

For example, if we wanted a size modifier for a bat in Conker. As far as I know, the bat never changes sizes, however it does move coordinates. We could hack the coordinates out, and then if the size isn't nearby in memory, we can search for pointers, and examine now those areas that it points to. We haven't used it much, but the memory viewer is actually a very useful tool for these kind of analysis. We will use it today a little bit.

OK, time to start hacking.
We're going to hack the Mario 64 size modifier for Mario. First of all, we need to know what type of code it is. In general, size modifiers, coordinates, everything like that are 32-bit signed floating point values. Remember, we used this codetype (floating point) to hack the moonjump (jump speed) and the infinite health code for Goldeneye, so we will again do a signed 32-bit search with Renegade 64.For reference, to make these states, press Ctrl-S and save it. Last time we chose a quick save slot (0), and then pressed F5 to quicksave into it, and F7 to quickload. This is similar, but this time just a file

If you notice, I've taken you to a spot at a thwomp, which can smush you
If you want to hack a size mod, first of all, it's easiest if you find a spot where the actual object changes size. If your object doesn't change size, this method won't work and you can use other methods detailed later.

In this case, we are finding Mario's height. Mario is at his max height when he is normal sized, and when he gets smushed he shrinks.

So what kind of thing should we do?
  • Of course, we will now do an initial dump at normal height, get smushed, LESS THAN
  • Then as you pop up, can do GREATER THAN (not full height), then at full height do GREATER THAN
  • Then try to avoid the thwomp and do EQUAL TOs, etc, get smushed again, LESS THAN, etc
  • If you do need to reload, press ctrl-L and load the save state again.
You should narrow the 32-bit location to 8034BD78. If you have succeeded, you can put on the code: 8134BD78 4000 and see a huge mario, but only while thwomped. I want to make it clear that this method of size modification ONLY affects Mario when he is smushed, this is NOT the global size modifier.
So when you are testing, you would only see your size when you get smushed. This isn't always the case, but here it is.

So now we've got a temporary size modifier for Mario, but it doesn't work all the time! What do we do now? We use the memory editor, and look for pointers to other memory locations nearby this address.
  • Open up the Renegade 64 memory editor
  • Go to 8034BD40
  • Our temporary size mod is at 8034BD78.
  • Look around for any 32-bit value in memory that looks like 80XXXXXX (these are pointers). Do you see any?
  • I noticed one at 800F0860. Go to 800F0860 in the memory viewer.
I will tell you most size modifiers look like 3E800000, 3F800000, 3DCCCCCD, or similar. We are looking for this. Do you see any suspicious? You will need to test a bunch of codes. In the end, the correct spot is 800F0890. So try 810F0890 3F80, Voila!

This impressive code I hacked ages ago, wasn't so hard after all, if you know about pointers. When we get to assembly hacking, I will tell you for real what this pointer stuff really is.

Next week we will hack some even more advanced codes, possibly Banjo Tooie!
%s1 / %s2