From the Past: Apple ][+ Boot Tracing
The other day I posted a bit about the old old days of Apple ][+ software cracking: https://medium.com/@masonoise/an-intro-to-apple-cracking-489156062fe9#.cmzhma8pn. See that post for some back-story.
While poking around the depths of the internet I also found another BBS post that I wrote back then about boot-tracing, which may perhaps be interesting to some either for nostalgia or just curiosity to see the amount of work high-schoolers like me put into cracking and copying games. I never even played the games, and didn’t keep most of them either. I was just in it for the technical challenge. So here you go, from around 1981: enjoy.
I want to mention that some of the following information was received from various other boards, including Pirate’s Cove, Pirate’s Harbor, etc.
First of all, let’s get some things straight. This method of cracking will generally work on most software, but it requires a lot of patience, dedication, and assembly language knowledge.
Obviously, in order to run, a disk has to be able to boot. How does this occur?
When you type PR#6 or 6, the Apple jumps to the disk controller card routine at $C600. This short routine loads in the next stage of the boot, at $0801. From there, what’s on the disk has control. Of course, we can’t change the routine at $C600, because it’s in ROM — but we can move it, and then change it.
So do this, using the monitor move routine. Boot something normal, like your system master, and enter the monitor. Then move the first stage boot down to $9600 with a 9600 <C600.C700M. Looking from 9600 you will eventually come across a JMP $0801. This is the jump to the next boot stage. Change this now, to a safe jump, like $FF69 (monitor).
Put in the disk you want to crack. Some good ones are Apple Galaxian, or nearly any other game-type software that doesn’t access the disk after it loads. Then type 9600g. The disk will start to boot, moving the arm across, but then you will exit to the monitor. Of course, the disk drive will keep spinning, since nothing told it to quit. You can stop it if you want, with just typing ‘C0E8 ‘.
Now the next stage boot is in memory for you to examine. It loads in at $0801, so list it with an 801l. You will be able to see what the program does as it enters this stage of the boot. Tracing it along, you will eventually come to the next jump. Since you want to intercept this, move this stage of the boot up with a 9800<800.8FFm. You will almost always be forced to do some changing with this stage of the boot, however, to make it run at the new location, so change the locations that access addresses in the 800 page of memory so that they access the new locations in the 9800 page. Then change the jump at 96F8 to a JMP 9801 with a 96F8:4C 01 98, and type 9600g. But first, of course, change the jump from the second stage boot to something harmless, like jmp FF69. Remember where the jump was to, however, so you can check it.
Again, usually the disk drive will continue spinning, so stop it again like before, with a C0E8. Now, remembering where the jump from the second stage boot was to, list that location. For instance, if the jump from the 800 page was to 300, list with a 300l. This location can be anywhere — for Apple Galaxian it is 0300, for another program it might be 2000, etc. But this stage will often be the last one, the one that loads in the program itself. Software varies a lot, though — some programs may have four or more boot stages, some may jump from the second stage straight into the program. There’s no telling, except by experimenting. Try each stage, until you find the one that starts the program.
One good thing to look for is the turning on of the hi-res pages, with a LDA C050, LDA C054, and similar instructions. These will obviously be accessed before the program actually starts, or just as it starts. If you find those instructions, you’ve found the program, in all probability.
Well, I may soon return with an actual example of boot-tracing, but in the meantime give it a look. It can be a very practical way of cracking, especially for those of you who don’t have access to a monitor ROM machine or a modified ROM, such as the Lockbuster ROM.
— — — —
I have received some requests for a continuation of my previous column on boot trace cracking, so here it is, folks!
People have a tendency to think that boot tracing is something extremely difficult, that one has to be one of the “great crackers” to be able to do it. Not so. It does require a lot of patience, tenacity, and of course a good working knowledge of assembly language. In other words, no more than any other method of cracking.
Boot tracing is not useful for every piece of software. If the disk has a special DOS on it, or really any DOS at all, it is certainly not the easiest way. Whenever a disk has a DOS on it, pulling the files off the disk is far easier than boot tracing it, and in fact boot tracing a disk of that kind is rather silly. But for single-loading games and utilities, boot tracing can be one of the easiest ways. If you are the owner of a monitor ROM, simply pressing reset can do the job, although those days are coming to an end.
Previously, software had no real protection versus a monitor ROM. Those who had access to one were able to crack practically anything on the market. Ah, for the good old days. But there are ways to stop a monitor ROM, and they are being implemented in almost every piece of software being released now. Perhaps the most common is simply placing data on the text page. When you press reset, although you exit to the monitor, you lose the top line of text, and are likely to lose all of the text screen. With a special ROM this can be avoided, but that is not the subject here.
When boot tracing, it is not hard to avoid the above problem. In Gorgon, for instance, data was loaded over the text screen by the boot. Simply modifying the boot in memory to load it and then move it to a safe place would avoid the problem. This doesn’t always solve everything, but it helps. Simply pressing reset from within the program would lose the top line of data.
A more recent release, Pensate, from Penguin Software, does a similar thing. The boot1 loads in at $800, as always, and loads in more data directly after it, starting at $900. After the data is loaded in, it branches to $881, where it starts more initializing, and continues executing through the instructions that were loaded at $900. These instructions perform some interesting feats, including erasing whatever might be in a language card upon booting (nasty folks, aren’t they!), and then move some instructions over the text page, where they are executed by a JMP $789 (if I remember correctly). Simply changing this to a JMP $6000 and then placing the following code at $6000 allows you to examine the code at your leisure:
loop LDA $400,X
This code pretty obviously performs a memory move, moving the text page up to $8000, then jumping to the monitor (I like to use a JMP $FF59 rather than $FF69, so I get a beep). It is a very simple move — they can get far more complex, but there is no need for something elegant in this situation.
Another point that was brought to my attention by someone was the fact that boots often use indirect jumps, which make boot tracing them a bit more complex. This is true, but they are usually pretty easy to get around. One possible solution is to simply put a BRK instruction where the jump is, and when it reaches the BRK examine the memory locations which were to be used for the JMP. For example, one common jump is a
One can replace the $6C with a $00, and when the program hits the BRK, look at locations 8FE and 8FF to find the address the jump was heading for.
The problem with this approach is that a BRK doesn’t always do what you want it to. You can also, however, make the JMP a JMP to $FF59, and then examine the addresses.
Again, however, there is a problem. Sometimes the nasty folks behind all our problems choose an address that isn’t always what it appears to be. The most common of these is $003E. If you try the BRK method or the JMP $FF59 method, you are likely to find some nonsense address rather than what you’re looking for. What do you do in this circumstance?
What you can do is write a small routine to print out for you the address that boot is jumping to. Replace the JMP ($003E) with a JMP $6000, or some other safe location. Then write the short routine below at that location:
This routine will display the address that the jump was heading for. If the boot is relatively normal, you are likely to see a C65C. You may wonder what the boot is doing jumping to such a location.
Well, a normal boot1 (rare enough these days!) is meant to load in the next 9 sectors from track 0. These sectors contain the rwts and some code which will load in the rest of DOS, and jump to the DOS start location. But the boot1 is only a page long, and can’t handle the entire duty of loading in all of that, so it calls on some of the boot0 code to help it out. This is the sector read routine at $C65C. However, if we want to boot-trace the disk, we can’t let that jump occur, since once the routine is done it jumps once again to $801.
We can fix this, though. As you should recall from the previous column, the basis of boot tracing is moving the boot0 down and changing the jump. Well, instead of letting boot1 jump to $C65C, we can change that indirect jump to $965C, which when it is done will jump to our moved boot1.
One more note about these indirect jumps. You should all be aware of a bug in the 6502, which has on occasion been used by software protectors (yes, our arch-enemies!). When the 6502 finds an indirect jump, it takes the lo-byte of the address from the specified location, then increments that location, and gets the hi-byte. However, when that increment is done, no check of an overflow is done. This means that if the increment causes a change from $FF to $00, the hi-byte is not incremented. Thus, if an indirect jump of JMP ($8FF) is done, the address to jump to is not taken from 8FF and 900, it is taken from 8FF and 800! This should always be in the back of your head — always be suspicious of indirect jumps.
Some further notes. Even if a boot is too complicated for you to follow (which can indeed happen), it is possible to get something out of it. If you have an autostart ROM, sometimes you can find the part of the program that changes the reset vector, and make it skip the change, thereby enabling you to press reset once the program has started.
Make printouts when you are boot tracing. It is often possible to miss something, and find the disk booting completely. When this happens you have to go back and start over, which can be a big problem if you haven’t made any printouts or any notes. Write down the locations you change. If you’re wrong, you can backtrack, with good notes.
That’s all for this time. I hope some of you can make good use of this, and present some new software to the general public.
>>>>>>>>>>The Cracker’s Guild<<<<<<<<<