H E A D I N G|
F O R T R O U B L E
Continuing his codebusting theme, Terry Bulfib delves deeper into the loading methods used to 'protect' commercial software from the prying eyes of hackers. This month, he takes a look at programs claiming to be 'headerless'.
|If all you're looking for in this article is a
foolproof method of breaking into any
software package and then copying it for
all your mates, I'm afraid you're going to
be upset. Software piracy is both illegal
and immoral, and there's no way that I or
this magazine can condone it ... under
That said, under the copyright laws of this fair country, it's perfectly legal to make a copy of work for the purposes of private academic study ... and that's all we're proposing here. The only stipulation is that you mustn't use your copy for any other purpose than private study, or pass it on to your friends. There's no legal or moral objection to breaking the protection on a program in order to examine the programming methods, make alterations or just show off your programming prowess.
LOSING YOUR HEADKeeping the above firmly in mind, let's move on to the concept of loading a computer program from tape. Basically, to load anything at all, the computer must be told the start address and the length of the load, and what type of load it is (Basic or bytes). Usually, this information is in the 'header' which precedes each program, saved in the normal way. This makes things too easy for the hacker though, and hence the popularity of the 'headerless' load; however, the computer still needs to know this information, so it has to be told in another way. This is done with a short piece of machine code which puts the information into the appropriate Z80 registers and then calls the routine in the ROM which performs the load. The piece of code must be present for the headerless load to work. If you can't find it, then you're looking in the wrong place!
Sometimes the code will have a false header, one which is there only to mislead you. The loading program will have
two machine code loading routines, the
first of which is just there to throw away
the header; the second can then load the
code to a different address. Very droll.|
The simple way of dealing with the headerless load is to tack a header of your own manufacture on to the front of it. To do this you'll need to know the start and length numbers, and they'll be somewhere in the loader program. They have to be, so keep looking. Have a look at the example code with this article - it should look something like that.
There may be a great deal more code in the loader, but there cannot be less. It might check that certain bytes in the Basic have not been messed with, or it may load the registers from some address the Protection Artist (PA to you, John!) reckons you may have disturbed by breaking in. If you make a mistake, don't tell anyone about it and get laughed at - just try again, dummy, until you can brag about what a wizard you are.
If the PAs are feeling clever, they'll ring some changes in this fairly straightforward routine. For instance, the jump address may be pushed on to the stack and jump to the ROM routine instead, which will cause the routine to return from the ROM to the address on the stack. Perhaps the code is made to load over the top of the jump address, changing it to something else. It could even be arranged for the code to load over the stack, changing the return address stored there by the call instruction. Protection artists like to think they're smart, so watch for that extra wrinkle.
If it looks like there's just a simple jump to the M/C program on return from the load, then you could substitute an address of your own, one that goes somewhere safe (1303 Hex is worth remembering) or perhaps a little routine to un-set all the bombs first.
FAST AND FURIOUSThe headerless load may not be headerless, it may be loaded by a special routine - a fast loader perhaps - rather than using the Spectrum ROM. In this case you have a program loading a program to load a program. The way in is the same. The first LOAD has to use the standard Spectrum ROM routines.
That's the 'fast', but 'furious' is you when the fast load fails for the fifth time running. This is one that won't respond to a false header, because the actual tones on the tape are different from the standard format. Most of these fast loaders (and the saving routines for that matter) are pinched from the Spectrum ROM. Talk about piracy! All that's changed is the delay in the timing loops and sometimes the border colours. In fact, you may find that the routine calling the fast load routine is just like the code above for the headerless load. That's a useful landmark.
To get the main program aboard, you'll have to use the fast load routine ... nothing else will read the tape. But first
you'll want to re-write the fast load a
little, so you keep control. The principle
of such a fix is the same as for the headerless load, and the fast load routine will be
loaded in a way that's protected by the
same methods as the headerless loader.|
DANGER UXBThere are two popular bombs which most people know about: POKE 23659,0 will allow no lines in the lower screen (so any error message will crash the machine) - so does 'Scroll?' and so will CLS. This limitation means the bomb is only good for very short programs. Imagine a program that could neither clear nor scroll the screen!
The other booby-trap is set by corrupting ERR SP at 23613 and 23614. The idea is to POKE in the address of a pair of bytes holding zero. With the power-up RAMTOP of 65367 it's usually sufficient to POKE 23613,0 and let 23614 ride. Then whenever there is an error (BREAK is an error condition) the computer will collect an address from the address pointed to by ERR SP - which should be in the stack - and jump to it.
Point ERR SP at some zeros and the Spectrum ends up jumping to reset. This bomb will only work provided you are prepared to do without GO SUBs. A GO SUB doesn't crash the machine, it just corrupts ERR SP.
A much more useful variation is to POKE not ERR SP itself, but the address that it's pointing to in the stack. This is not vulnerable to the GO SUB do-good-ing. Instead of zeros, you could put in the address of your own machine code routine:
10 LET A=PEEK 23613+256*PEEK 23614: POKE A,0: POKE A+1,0
Defusing these traps is mostly a matter of not letting them be set. Don't let the program that does the POKEing run in the first place. However, the technique of LOADing a Basic program complete with the system variables as a block of code can also set these traps.
TOO MUCH!Some programs LOAD in as many as six chunks. There were two companies who used the same method of multiple LOADs for a while, specifically to combat the copying programs which were selling so widely. These put small
LOADs of just a few bytes into places
where particular copy tapes kept their
own info; the main program would check
to see that these bytes were undisturbed
before it would run.|
The cleverest of these short LOADs would put a certain value into the systems variables FRAMES (which is changed every 50th of a second by the computer unless the interrupts are disabled); you can't do this from Basic. The LOAD routine in the RAM enables the interrupts at the end of a load, so FRAMES starts changing as soon as it's loaded. The main program can therefore easily tell if someone's been fiddling.
This is easily enough dealt with in machine code, but it's meant to stop copying only, and doesn't keep you out of the main program - I shall oblige you to work out your own methods.
WAY TOO MUCH!One of the hardest things to deal with is the CODE LOAD which starts at the bottom of the screen and carries on right to the last byte of the memory. If you try to make such a recording yourself, you'll find that it crashed on loading it back in. The reason is you've loaded over the stack, and when the LOAD routine in ROM performs the return after LOADing, it takes the (in this case) wrong number from the stack.
The problem is that, with the whole of the RAM being LOADed, there's no room anywhere for your own routines. However, with luck, a short cut may work. It's a time-consuming short cut unfortunately, because each attempt requires about six minutes just for the loading time. What you do is change the RAMTOP to put the stack in a different place, then load as normal. The idea is to get a helpful address to LOAD on to the part of the stack that the ROM is using. While this approach is rather hit and miss, it does work. For a start, try two bytes (stack addresses are all two bytes, though RAMTOP can be even or odd) more or less than the standard RAMTOP, which is 65367 in 48K Speccys. I do know programs that this does work on.
Theoretically, this method must work if you guess the RAMTOP used by the saver, and there should be any number of happy accidents to be had. But why guess? Why not LOAD the first half of of the code, screen and all, higher up than it's meant to go, say at 26384 instead of 16384. That helps you find the start of of Basic which will then be at 33755 (you weren't trying to do this with Microdrives?). Then the RAMTOP in use at the time of saving can be found at 33730. Try loading with a RAMTOP a few bytes either side of that.
If this fails then you have to do a demolition and construction job. You can easily LOAD the first half of the CODE high up. Then you can get the far end of the code into the screen memory by loading the whole file higher up still (say
48000 or so) and letting it wrap around,
loading past the end of memory, over the
ROM and into the screen. It will, you
know! SAVE the pieces and LOAD
them all back together into a tame lump.|
Naturally this is more trouble than it sounds, and you may need to use false headers and write your own headerless load routines to get things into the right places and stop code from lapping over into the system variables. But I reckon you're the sort of person who rises to a challenge, right?
WHEN ALL ELSE FAILSAs wetware (that's the organic based soft hardware you carry about within your cranium) ages, it gets tired more quickly. Mine does anyhow. At about 5am, I start making dumb mistakes instead of the clever ones I usually make. It's never impossible to break into a program by sheer ingenuity and persistence, but it can be a lot of work; a truly ingenious hacker avoids that particular four letter word.
So you may wish to consider cheating a little. That is, you may decide to cheat unfairly, using not brainpower, but the crude brute force of hardware. I refer, of course, to the SoftROM project in YS issue 2. Obviously it's much easier to get code aboard unprotected if you can subvert the ROM routines themselves. You could even re-write the reset routine to
return you to Basic without wiping the
memory, then a bomb would actually be
a BREAK routine. This is advanced
cheating not within the abilities of everyone; it will, however, give the beginner at
skulduggery something to aim for.|
LAST BITWell, that's it for now ... the rest is up to you. Messing about with code may be a little bit harder than attempting to crack the umpteenth level of any game - but you'll find it's much more rewarding. As I said last month, don't be discouraged by plying your new-found tricks of the trade
on anything too difficult; pick a game
that's a couple of years old and have a
hack at that ... you'll soon get the hang of
One more thing before I take my leave. It's not clever to pirate software - not only is it dishonest (and get you into a lot of trouble to boot!) but it's also contributing to the high price of commercial games ... if the companies can afford to publish them in the first place that is! OK, soap box session over - but it is important. Remember, the only way to get more out of your Spectrum is to put more in - keep on hacking!
EXAMPLE LOADING PROGRAM