THE ATARI 6502 DISASSEMBLER
Using SPY Disks
When you disassemble a boot disk (BOOTGAME.ATR for example), sometimes, you will see that only a small part of the code is readable and the rest is crypted. Usually the readable part contains a loop to modify the rest of the code. It is used to prevent people from disassembling the code. The simplest algorithm is to EOR all the crypted code with a value.
To be able to disassemble that kind of code, the best way would be to run the small part that transforms crypted code to readable (and executable) code and disassemble it after.
This is what SPY disks can do for you.
First, you need to look at boot disk code to understand what it does. When you see where the algorithm that decrypts the code is, you determine an address where SPY can set a breakpoint. You should select an address where the program goes after the decryption algorithm has been applied. You also need to remember the area where the new code has been decrypted.
Select 'Prepare spy disk'. A dialog box appears. Enter the breakpoint address in the upper left field called 'Patch addr'. This is the address where the code will be modified so SPY program can get control back. In fact, it overwrites the code to put a JMP instruction that points to SPY code. After, enter the address and the length of the area that will be decrypted by the program itself. It will be saved by SPY program on disk so you can examine it later. Press Add button to add this area to the 'Memory areas to save on spy disk' listbox.
You can enter a name for your SPY disk that will appear on screen when you run the SPY program. You can also check the 'Continue execution of boot disk after last patch' option if you want to check that the patch did not destroy anything in memory. This is very useful to check that the program works well even if it has been 'patched'. This way, you are sure that the decrypt algorithm that has been applied is the good one and that it works the normal way because you see the program running. This option lets you check that the SPY program did not disturb the normal execution of the boot disk.
Save the spy data into a fresh disk with the 'Save spy...' button. This disk will contain the spy data and the results. We will call it SPYDATA.ATR for example. Note that you have to copy another .ATR to SPYDATA.ATR before saving you work because the 'Save spy...' button will not create a new .ATR file. It will only overwrite an existing one.
At this point, you have
Now, you need to select one of the several SPY programs that will run in your Atari. It is the same program but assembled at different addresses. You have to look at the code of the boot disk and choose a memory location that is not used by the code. The possible addresses are $1000, $3000, $5000, $7000, $9000 and $B000. They are provided as boot disk under the name SPYxxxx.ATR where xxxx is one of the address (SPY1000.ATR for SPY program that runs at $1000).
Now you should have 3 disks (.ATR files):
Follow theses steps:
With SIO2PC or APE for example, load SPYxxxx.ATR
Turn on your Atari.
When the program is booted, it should display
Insert spy disk in D1: and press START.
Remove SPYxxxx.ATR and load SPYDATA.ATR then press START.
When the data are loaded, it should display
Insert boot disk in D1: and press START.
Under APE, remove SPYDATA.ATR and load BOOTGAME.ATR then press START.
The disk will boot the normal way and when the program finds the JMP patch, it will return in the SPY program. Then it should display
Insert spy disk in D1: and press START.
Remove BOOTGAME.ATR and load SPYDATA.ATR then press START.
The SPY prgram will save the memory you want to see on the SPYDATA disk. All is finished execpt if you have checked the 'Continue execution of boot disk after last patch' option. In this case, it should display
Insert boot disk in D1: and press START.
The program should continue the normal way. You should be able to play the game or use the software.
You now have a SPYDATA.ATR where some part of the memory has been saved. To examine the results, you have to run the 6502 disassembler for Atari. In the File menu, choose 'Open spy disk image data...'. Choose SPYDATA.ATR Now, if everything goes fine, you should be able to see the code that was previously crypted !
There are some disks that are heavily protected and that run a first decrypt code, then a second, then a third,...
In this case, you have to repeat the previous operations untill all the code is readable.
For example if you have some code at address $4000 that unprotects code from $4100 to $5000 and after, code at $4100 unprotects code from $4200 to $5000.
You must enter a first patch address of $40F0 for example and try the patch. Looking at the result, you see that there is still a part from $4200 to $5000 that is unreadable.
You must edit again the SPYDATA.ATR disk and ADD (do not remove the first patch !!!) a new patch address of $41F0 for example. The second try will reveal all the code from $4200 to $5000.
In many cases, you won't have to do that but look at the following code:
This code decrypts 256 bytes at label CRYPT. To use the SPY program to reveal the code, you need to select an address for the patch:
You can not put the patch AFTER the CRYPT label because it is the part that will be modified !
You can not put the patch BEFORE the CRYPT label because it will jump back into SPY program when only one byte (the first at label CRYPT) has been unprotected.
You can not use the normal SPY program to reveal this kind of code because you don't know where to put the patch (JMP instruction to get back to SPY program). You need to edit SPY.M65 and customize it for one particular case.
When you edit SPY.M65, you see a big comment like this one:
You don't need to look at the file SPYCORE.M65 that does the dirty work of applying the patch, removing the old one, saving memory to SPYDATA.ATR, and many other things...
What you need to know is that code at label USERCONTROL is executed when there are no more patches (it means that all the patches in the list have been applied or that the patch list was empty). Here, you can put your own code to do something. When your code has finished its work, it can call JMP USEREND to continue normal SPY program execution. The SPY program will then ask for the SPY disk and save the memory areas on disk.
What can we do here ? If we continue with our exemple, we could set a patch address at label START (LDY #0). Then type in the small piece of code that unprotects the 256 bytes:
This code will execute when there will be no more patch. When the SPY program boots, it asks for the SPY data disk. When you press the START key, the spy data are loaded. It then asks for the boot disk. When you press the Start key again, it loads the boot sectors as if the Atari has just been turned on. Then it applies the first patch and jumps to the init address of the boot disk. When the code patch (JMP instruction) is executed, it returns the control to the SPY program. The SPY program remove the first patch and search for the next patch. It sees that there is no more patch (patch address is $0000) so it jumps to the USERCONTROL label. Here, the code that we added unprotects the 256 bytes. Then we jump to USEREND to resume execution of the SPY program which prompts the user for the SPY data disk to save memory.
You have to assemble the source at the desired address (for example $3000. Then you have to use 6502 Disassembler for Atari to convert your SPY3000.COM file to a boot disk (SPY3000.ATR).
If you see another part of the code that is protected, it means that you have to do 2 patches, the first one is the code that you customized in SPY.M65. If the second patch can be applied the normal way (without modificatins to SPY.M65), you should do it this way:
Add a patch address of $0000 (after the patch address at label START), then the patch address for your second patch ($41F0 for example). The patch address of $0000 tells SPY program to not apply a patch in boot disk but to jump to USERCONTROL. The listbox should display
40F0 (the START label for example)
0000
41F0
Modify SPY.M65 to execute the code only the first time. If you do not change anything, the code at label USERCONTROL will execute twice. One time because of the patch address of $0000 and one time after the last patch (in fact, this is because the end of the patch list is seen as a patch with address $0000).
Again, you have to assemble the source at the desired address (for example $3000. Then you have to use 6502 Disassembler for Atari to convert your SPY3000.COM file to a boot disk (SPY3000.ATR).
The test CMP #1 prevents the code at label PATCH1 to be executed twice.