Tip Off
© Anco

What you need:

1.      Original game or SPS #1551
2.      A little asm experience
3.      AR3 cart.


In this tutorial we’ll have a look at Tip Off, which is protected with:

1.      encryption  called cobra x-rom system (who finds a name like that?)
2.      two disk checks
3.      20 checksum routines

Start by making a copy of original game. You’ll notice an error on track 2 & 4 of disk 1. 
Then we have a disk based protection.
A good start is always the bootblock, load it into memory; RT 0,70000. And disassemble; D 7000C

At offset 40 something interesting happens. Here is the actual bootloader. It loads $ 29a00 amount of data,
From offset 90600 on disk, into memory address $ 30000.
Then part of bootblock is copied into memory, at $ 59810 and executed.

The part of bootblock copied, is also copy memory from address $ 30000 to $ 7D0. 
Address $ 30000 was where game loaded something into memory, interesting.
After this copy, game jumps to address 27fc0. Lets try replacing this with a loop routine and have a look
at memory. Follow below pic., to insert a loop;

Reboot and wait for game to hang:

If we disassemble memory loaded to address $ 30000 and copied to $ 7D0, we’ll see its nothing but
Nonsense, its encrypted. If we disassemble address $ 27FC0 (original jump address), we’ll see part
Of the decrypting routine.
Ok, no need to make things more difficult than needed. Why not let game decrypt itself and then we grab 
decrypted code. Decrypted code will most likely start at address $ 7D0, why else copy data here..
Execute original jump with G 27FC0, wait 2 secs, and enter AR again

Ok, lets check for any calls to address $ 7D0; FA 7D0, and yes, we get a JMP 7D0 at $ 291DE.
This must be end of the decrypter, calling decrypted code. Replace the JMP 7D0 with JMP 291DE, and 
Exit AR. This will cause a loop when game is decrypted. Wait about 10 secs and re-enter AR. Press D+enter,
You should now be stuck in a loop. Replace the loop, back to JMP 7D0.
Mainfile is now sitting fully decrypted in memory, just waiting for you to grab it J
File starts at $ 7D0 but where does it end ? We know bootloader fetched $ 29A00 amount of data, so
$ 7D0+29A00=2A1D0. Insert a blank disk (called crack disk now)and save memory; SM a,7d0 2a1d0

Goodie, now to get it back to disk. 
We still have encrypted code in memory, starting at address $ 30000. See the first opcodes; M 30000,
See above picture. With these, we can find start of encrypted mainfile on disk and replace it with decrypted one.
Insert copy of disk 1, and read out a big chump; RT 50 50 10000.

Search for opcodes; F 97 c4 23 af,10000. AR returns address 32600. Now, insert your crack disk and
Load decrypted file to address $ 32600; LM a,32600. Insert copy of disk 1 and write back; 
WT 50 50 10000. Decrypted file is now on disk.
Problem is, that bootblock ended up by calling the decrypter, now it must execute game right away.
Read boot into memory; RT 0 1 70000 and disassemble; D 7000c;

Replace the original jump with jump 7d0 and write back, see above.
Now we can look at the actual protection..
Boot game. Disk loading hangs when this screen appears:

This is the diskchecks kicking in. Enter AR and disassemble memory:

Around $ da8 is a routine checking for a value. If it fails, it keeps going to address $ d98, running the routine
Over and over again. If we remove the checks, routine continues. Try NOP them out;

Exit AR. And.. Game continues to load a little and then hangs again… hehe
Re-enter AR, and yes, another disk check;

Again, NOP them out. This time you can actually start game! So far so good.
Ok, take note of the opcodes for the disk check, so we can crack it in our crack file. M 12EC, see below.

Insert crackdisk and load file into memory at address $ 10000; LM a,10000. Search for the opcodes:
F 9c 45,10000. AR returns address $ 106d6 & $ 10b1c. NOP out the checks:

Then save file back to disk; SM a,10000 39a00.
That was encryption & disk checks, now only 20 checksums left..
If you write file back now, you can start game now, but short after start, Amiga resets.
I was a little puzzled about this, and really couldn’t figure out what was wrong. I was suspecting a checksum,
But couldn’t find any to start with. I did it the hard way, and started disassembling the crack file from start.
With crack file in memory, starting at address $ 10000, I fell over this pretty suspect code around $ 12874:

First thing that jumps the eye is address $ 1286E, checking reg. D1 for a specific value. 
Notice that regs. are saved at $ 12856. If the check at $ 1286E fails, it branches to $ 12876, WITHOUT
Restoring regs, which will cause a crash. To check for further checksums of this type, I searched for
The opcodes for the “ CMP.L “ ; F b2 bc,10000 “

This resulted in 8 results, see above picture. They all do the same, if they fail, regs. are not restored, causing
A crash. To crack them, simply change the BEQ to a BRA, by changing the opcode from 67 to 60;

Ok, I was afraid of  more checksums, so I looked at 2 the checksums already found, to see for other

Both (and the six others) clear D1 with a moveq #0,d1. Try search for this instruction; F 72 00,10000.
AR returns a shit laod of addresses. Take the first one and disassemble;

Notice around address $ 111B2, subtracts a value from D1, if it fails address $ 11b6a is called, which 
RTS WITHOUT restoring regs. If it passes, it continues to address 111ba and restore regs.
Lets see the opcodes for address $ 111ac, as these might only occur in this type of checksums;
M 111sc; D2 02. Search for them: F d2 02,10000. AR will return 7 addresses, where the last one
Is odd, this can be excluded.

But the other six looks interesting. Again, they all do the same. To kill this type of checksum, we have 
To remove the BNE, NOP out  all 6, by inserting 4e 71 4e 71;

I tried searching for other similarities, to find other checksum, but no luck. I struck me, that they all started
By saving regs., so I searched for the first opcodes;

This returned a real real big load of results. What are you waiting for ? start disassembling!!
I’ll spare you..
At $ 11276 something interesting appeared. See the check at $ 11292, if its ok, then regs. are restored,
Looks familiar ?
If check fails, game jumps to crap code with JMP (A2)

Oki, this jmp (a2) seems special for this type of checksum, search for the opcodes; F 4e d2 4c,10000.
AR returns 6 addresses, see above.

Again, we have 6 checksums, all doing the same. To kill these, the BEQ must be changed to a BRA.
From opcode 67 to 60;

Then what ? I could not find any more checksums, so lets save crack file back to crack disk; 
SM a,10000 39a00.
Next and last step, is writing the crack file back to copy of disk 1. 

Insert copy of disk 1 and read into memory (like earlier); RT 50 50 10000.
Insert crack disk and load file into memory at $ 32600 (like earlier); lm a,32600.
Insert copy of disk 1 and write back; WT 50 50 10000.
Reboot and, well do what ever you want.


Publication author

offline 7 hours


Comments: 1160Publics: 2778Registration: 06-03-2017

Notify of

Inline Feedbacks
View all comments
14 years ago

Thanks Rob, another one bites the dust 😀 !!!

14 years ago

Thx dudes!

14 years ago

God bless lazy coders for making the checksum routines so easy to find! Another good tut Rob, nice job.

aLpHa oNe
14 years ago

Another great and well explained Tutorial. Good Rob Job, aeh Job Rob ! 😉


This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Password generation

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Would love your thoughts, please comment.x