Archer Maclean Pool ? Archer Maclean 1992
Original game
An Amiga or WINUAE
Action Replay or ROM image
Pencil and paper
One blank disk – find it in your local Amiga store
ARIV
During this txt, a lot of addresses and values are shown. It?s probably a good idea to take note of them during reading, as it will makes it easier to do the final patch.
This game is very similar to Jimmy White?s Whirlwind Snooker, both in game play and protection.
This one has just been optimised both in game functions and the protection is also at a higher level.
As for Jimmy White?s Whirlwind Snooker, this game also has checksum routines which causes the Amiga to crash if it fails (reset). Checksums seems to be more sensitive in this one, taking better ? care ? of the novella. I still can?t locate the routines, so we bypass them by restoring all values we alter, back to original state.
Copylock is way more tricky, as it?s NOT enough to wire copylock key into the encrypted code. Copylock key are moved to address 60 after the key calculation routine and different values are moved into memory. If these are not simulated, game will crash.
Let?s begin.
Start by backing up original game disk, so we have something to work with. If a copy of game is used, the screen will be filled with the txt ? FAIL ?.
We start by getting the copylock key. Execute ARIV, insert original game and reboot. Enter ARIV just after boot, using RMB. Disable exceptions and exit: ? ALLEXC ?.
This disable ARIV from popping up, when an exception is reached.

When the Presentation screen appears, game has been decrunched and copylock has run. Enable the RNC decrypter, so we can have a look at the copylock inside: ? ROBD ?. Copylocks start with the instruction ? PEA xxxxx(PC) ?.
Search for the opcodes: ? F 48 7A ?. You will receive address 32A0E & 32A1E. Disassemble the first address and stop when you reach end of the key calc. routine:

Address 32EF6 look very interesting, as it moves the final calculated key into address 60. Take a look at address 60, to get key: ? M 60 ?.
More ? not so normal ? stuff happens in here. When I was stepping through the code, I fell over these two addresses:

When inserting key into the encrypted code and branching past the disk access stuff, the above are skipped.
This is very BAD?
If we don?t emulate address 32F66 & 33198, game will crash. Let? have a look at where to wire key in.
Disassemble address 32E14 and hit enter a few times:

The disk accessing part and key calculations of copylock key are done within the code from address 32E14 ? 32E5A.
Registers are saved by the code at address 32E14. Address 32E28 is a good place to wire key in, as no disk routines has been called yet. We wire key into D0, clear D1 and then branch to address 32E5A. This should give the best result.
Disassemble a bit further:

Address 32E58 moves key from D6 to D0 (we skip this part) and registers are restored at 32E5A, our branch address.
Address 32E5E branches to second part of copylock which fills registers with different values, based on D0.
Take note of original opcodes in copylock and their addresses, marked with green above.
Assemble 32E28 and insert the code you see above. After that, take note of the new opcodes and their address.
We have to restore opcodes in copylock after it has run, to avoid problems with checksums. We can do this by inserting a call after the copylock, to a patch, which restore opcodes. Have a look at code after copylock:

Copylock ends at address 3330A. This is a good place to insert a call to patch, which restores original opcodes in copylock. See the original opcodes for the code at address 3330A, assemble and insert a ? JSR 12C.S ?.
Then see opcodes for new code. Every step is shown in the picture above.
There is still the annoying novella left. Boot original game and bring up the protection screen.
Type in the word ? DAMM ?.

Enter AR and search for the word: ? FS DAMM ?. AR returns address 16AFA.

We are interested in what game might do with address 16AFA. Before we check this, see registers: ? R ?.
A1 points to address 16AFA. Set A1 to #0, to avoid getting false references. ? R A1 0 ?.
Then type ? FA 16AFA ?. AR returns address 16ED6. Let?s look at the code around this address:

The protection check is done at address 16EB8. This address subtracts 14+what A0 pints to from D3.
If the result is #0, address 16B10 is cleared and game starts. If it fails, protection just restarts.
Take note of address 16B10 getting cleared, as we shall use this info later on.
We?ll crack it by clearing D3, just as if the protection had passed. This can be inserted at address 16EB8.
To make addresses add up, three NOP?s is also needed. Just as with the copylock, we need to restore novella to it?s original state when it has run. Take note of the original opcodes, see picture above. Assemble 16EB8 and insert code marked with yellow. When done, see new opcodes:

Next question is where to take over novella? I tried patching it just after running the copylock, but this caused a crash. It seems like a checksum is run after the copylock. We then have to patch novella, AFTER this checksum has run. As I don?t know where the checksums are, I just tried taking over different addresses after copylock had run.
Address 5DDC seems to be very suitable. Have a look at it:

We can alter address 5DDC to ? JSR 176.S ?, after copylock has run, without getting troubles with checksums.
Address 176 can then wire new opcodes into the novella. See original opcodes for address 5DDC, insert a ? JSR 176.S ? and see new opcodes. See picture above.
After the novella has run, it?s probably best to restore original opcodes. This means that we need to find the code after it has run.
Remember that novella cleared address 16B10?
It does this, so it knows if the protection has been run. See what else happens with address 16B10: ? FA 16B10 ?.

AR returns three addresses. Have a look at the code around the first one:

Address 16B8A checks if address 16B10 is #0. If it is, the novella call at 16B94 is skipped. When novella has run, it returns to address 16B98. We?ll insert a ? JSR 1AA.S ? here, and restore original opcodes in novella, from a patch at 1AA. See original opcodes for 16B98 & 16B9C, insert a ? JSR 1AA.S & NOP ? and then see new opcodes.
Original opcodes are shown with green and new ones with red.
You should now be armed with a bunch of opcodes and addresses.
We now need to find a way to take over the decrunched game, before it?s executed, and make it call our crack patch.
Read boot block into memory, starting at address 70000: ? RT 0 1 70000 ?
Disassemble start and look out for jumps into loaded code:

Line 7009A makes a jump to the address A3 points to; beginning of the crunched game. Change this to a loop routine and write track back. Follow the above steps.
Reboot game and enter AR when it stops loading. We now need to find the jump into the decrunched data and take over this jump. Find start of loaded data, by looking at A3:

Address 59E8 is start address. Disassemble and look out for jumps. Address 5C48 makes a ? JMP (A7) ?, which executes decrunched game. We need to replace this with a ? JSR 100.S ?. The new code inserted is larger than original, so we have to insert at a little lower address. Address 5C40 is suitable. Take note at the code on address 5C40 & 5C42, as code has to be restored again. The opcodes for ? JSR 100.S ? is 4E B8 01 00. We move these opcodes into address 5C40. There is a little problem though, as A3 points to start of data, the start address is relative. It can be calculated where to insert the JSR by subtracting the address we wish to alter, with start address: ? ?5C40-59E8 = 258 ?.
All needed info to make a crack patch should now be in place. Only thing left, is a copy routine to move patch from disk and into address 100. Both patch and copy routine can be located on boot block, as there is free space from offset 100.
Read boot block into memory, starting at address 70000, change loop to ? BRA 70100 ?, to call copy routine upon boot.
See picture:

Assemble 70100 and code copy routine: 70100; LEA 100,A0; destination address 100 70106; LEA 70200(PC),A1; copy from offset $200 on disk 7010A; MOVE.W #D8,D7; copy $ D8 (size of crack patch) 7010E; MOVE.B (A1)+,(A0)+; copy 70110; DBF D7,7010E; copy 70114; MOVE.L #4EB80100,258(A3); call patch with a ? JSR 100.S ?, when game is decrunched 7011C; JMP (A3); jump we took over Assemble 70200 and code the crack patch: 70200; MOVE.L A0,D0; restore code from end of decruncher 70202; SUB.L A6,D0 restore code from end of decruncher 70204, MOVE.L #6B87AF4E,32E28; wire new opcodes into copylock 7020E; MOVE.L #F6EBDD4E,32E2C; wire new opcodes into copylock 70218; MOVE.W #96C3,32E30; wire new opcodes into copylock 70220; MOVE.L #4EB8012C,3330A; call patch after copylock has run 7022A; RTS; return to decruncher 7022C; EORI.W #BD50,D0; run code we removed at 3330A 70230; MOVE.L #2ABB9D8C,32E28; wire original opcodes into copylock 7023A; MOVE.L #4DB5ED8D,32E2C; wire original opcodes into copylock 70244; MOVE.W #2CB5,32E30; wire original opcodes into copylock 7024C; MOVE.L #33CABD50,60.S; return copylock key at address 60 70254; MOVE.W #9290,37994; emulate code we skip inside copylock 7025C; MOVE.W #A9D0,3E8.S; emulate code we skip inside copylock 70262; MOVE.L #A40BD50,3330A; restore code at address 3330A 7026C; MOVE.L #4EB80176,5DDC.S; call patch, to crack novella 70274; RTS; return to game 70276; MOVE.W #535E.S,D0; run code we removed at 5DDC 7027A; MOVE.L #3038535E,5DDC.S; restore at address 5DDC 70282; MOVE.L #42434E71,16EB8; crack novella 7028C; MOVE.L #4E714E71,16EBC; crack novella 70296; MOVE.L #4EF801AA,16B98; call patch after novella has run 702A0; MOVE.W #4E71,16B9C; call patch after novella has run 702A8; RTS; return to game 702AA; LEA 12464,A0; run code we removed at 16B98 702B0; MOVE.L #41F90001,16B98; restore code at address 16B98 702BA; MOVE.W #2464,16B9C; restore code at address 16B98 702C2; MOVE.L #96680014,16EB8; wire original opcodes into novella 702CC; MOVE.L #66000008,16EBC; wire original opcodes into novella 702D6; RTS; return to game When patch is first called, it will wire new opcodes into copylock and a call back to patch, after copylock has run.
When it returns original opcodes are returned in copylock, code we skip inside copylock is emulated and a call back to patch is inserted at 5DDC. When game reaches the call at 5DDC, patch will wire new opcodes into novella and insert a call back to patch at address 16B98. When patch is called for the last time, original opcodes are wired into novella and it returns to game. This should ensure that all values are original, to fool the checksums at the correct stages.
Correct boot checksum: ? BOOTCHK 70000 ?

Write track: ? WT 0 1 70000 ?.

When novella appears, just press Enter.
There have been done lot of testing with this one, and no faults were found. If you any, please let me know. By faults, I mean actual errors you find, like the game is crashing at a certain point. I don’t care about what you ” suppose, think, assume “, hard facts please.
Many greets to DLFRSILVER for testing!
Rob