Go back

PART 2 - Conventional Hacking Techniques

By now, you should have an idea of how simple machine code works. Now we're going to look at the usual techniques of hacking. There are five techniques, which are called Forwards Trace, Backwards Trace, Stack Trace and Interrupt Trace, in that order of difficulty. Of these, Forwards Trace and Backwards trace are the only techniques you can use without a Multiface, and are the most reliable methods. You should only really have to use the others in exceptional circumstances, which are, on the whole, games which don't have a lives system or a GAME OVER message. Very few games use unusual routines, since it's just a hindrance to the programmer.

We'll start with Forwards Trace. You've already had a go at this from the last part, so hopefully it won't be too hard to understand. Then we'll look at the backwards trace, followed by some practical examples.

FORWARDS TRACE:

For the forwards trace, you start with the lives initialisation routine, and then work forwards from there.

The first thing you need to do is to find where the number of lives are defined. We've already seen how numbers are put into memory locations, and this is exactly what happens in most games.

(From now on, all the machine code programs discussed here will be written as hexadecimal bytes, and as mnemonics.)

3E XX         LD A,XX (where XX is the number of lives)
32 XX XX      LD (XXXX),A (where XXXX is a memory location, which we will refer to as the "lives store".)

You have already come across these instructions, but just to resume, the number of lives is put in the A register, which in turn is put in the lives store, the overall result being the number of lives being put in the lives store.

To find this, use the search function on your disassembler (QUEST 16384 on STK), and search for 3E <number of lives>. So if you had five lives, you'd search for 3E 05. You may find that this instruction occurs a few times, but you will probably find that only one actually puts the value of A in a memory location straight away. If there appear to be two occurrences where the number of lives is put into a memory location, then you may have to test all of them. You can, in general, rule out memory locations in which the number of lives is put in twice.

If you want to confirm you've found the lives store, you need a Multiface. Load the game up, and while playing the game, alter the value in what you think is the lives store. If the number of lives varies, you've found the lives store. If not, try another possible location. If you can't find any memory location which looks like a lives store, you won't be able to forwards trace, I'm afraid, in which case you should try the backwards trace instead.

Once you've found the lives store, you'll have to search for occurrences of it. You are basically looking for code which takes the value out of the lives store and puts it in a register (normally the A register), decreases the number by one, and puts the new result back in the lives store. To get infinite lives, you have to overwrite the decrement instruction with a blank instruction so that the number of lives is left intact. The code you want normally takes one of two formats:

1st type:
3A XX XX     LD A,(XXXX) where XXXX is the lives store
3D           DEC A (we want to remove this)
32 XX XX     LD (XXXX),A (putting the new value in the lives store)
2nd type:
21 XX XX     LD HL,XXXX where XXXX is the lives store
35           DEC (HL)   We want to remove this

You may find that there are other instructions between these. Don't worry about what they mean, just ignore them.

In order to remove the decrement instruction, we have to do one of two things. The most common is to replace the DEC A or DEC (HL) with a NOP (code 00). If this gives you only one life, replace the DEC A with OR A (code B7), or replace the DEC (HL) with OR (HL) (code B6). Don't worry why!

BACKWARDS TRACE:

Also known as "backtracking", a backwards trace starts from the GAME OVER message, and goes back from there to the lives routine. It is normally used when a forwards trace does not work or is unsuitable (eg: when finding infinite energy), the easiest alternative is to use a backwards trace.

The first thing you need to do is to find out what message is printed on the screen when you die. Nine times out of ten it's "GAME OVER", but there are exceptions.

For GAME OVER you have to search for the following bytes : 47 41 4D 45 32 4F 56 45 52. This is GAME OVER in ASCII (look up the codes in Appendix A of the Spectrum manual if you like). Sometimes, you may not find it, in which case just search for 47 41 4D 45 (GAME in ASCII). If that search fails, then the GAME OVER text is not in an ASCII format (this is rare, because printing routines are considerably smaller when ASCII is used), and you can't do a backwards trace.

Once you've found the GAME OVER message, you need to find out which part of the program refers to it. Normally, a print routine will load a register with the address of the GAME OVER routine, then print it. One possible register is HL (as we have met before), but also two other registers called BC and DE. Normally, all of these three registers are referred to as "register pairs", because they are two registers, each the same size as the A register, working together, so they can address all of the memory. You want to look for the following:

01 XX XX     LD BC,XXXX (where XXXX is the address of the GAME OVER MESSAGE)

11 XX XX     LD DE,XXXX (as above)

21 XX XX     LD HL,XXXX (as above)

(Remember that XXXX will be written "backwards" in the game's machine code!)

You should only find one occurrence of any of the above instructions. If you can't find any, repeat the search but take one away from the address the GAME OVER text is. (This is because sometimes there are Spectrum ASCII control codes such as 16 XX for PAPER XX before the actual text, and these are referred to as the start of the message). If that doesn't work, repeat the search taking one away again. Keep doing this and you'll soon find one of the above instructions.

When you've found the instruction, note down where it occurs. The part of the code you are now in is part of the GAME OVER printing routine. What you now need to do is go back through the code until you find either the code C3 XX XX (which is JP XXXX), or C9 (which is RET, which behaves exactly the same way as RETURN in BASIC.) Alternatively, you may find a blank area of memory (00 00 00 00 00 00 etc.) The address after one of these instructions is the START of the GAME OVER routine.

When you've found the start of the GAME OVER routine, you can find out which part of the code calls it. Then, to get a cheat, you can remove all parts of the code which branch to the GAME OVER routine. Search for the address of the start of the routine. You will probably find some of the following:

CD XX XX   CALL XXXX
CC XX XX   CALL Z, XXXX
C4 XX XX   CALL NZ, XXXX
C3 XX XX   JP XXXX
CA XX XX   JP Z,XXXX
C2 XX XX   JP NZ,XXXX

...where XXXX is the start of the game over routine. JP is similar to GOTO in BASIC, while CALL is similar to GOSUB (so that a RET instruction will return to the instruction after the call - except in some protection systems, but more about that later).To cheat, simply poke all three bytes of the instruction you find with 00 (so as to disable the CALL or JP). And there you have it!

Using the techniques of forwards trace and backwards trace, you should be able to hack most old, unprotected games!



[ Valid HTML4.01 ]
Free Web Hosting