|T H E P R O T E C T I O N|
|Have you ever wondered how professional software writers 'protect' their programs from copying and alteration? Simon Goodwin chews over some of the techniques used on the Spectrum, and outlines ways in which these same principles could be incorporated in your own software.|
The first problem of program protection
comes when a tape has just loaded.
Obviously you don't want the user to
type SAVE and produce a new copy -
but how can your program take over
control of the computer? |
Ideally the program will start as soon as it's loaded. On the Spectrum this is quite easily achieved from Basic. If the word LINE is added to the end of the SAVE command, a Basic program will automatically start to run as soon as it's loaded, without the need for the user to type anything. The command SAVE "EXAMPLE" LINE 200 would save a Basic program which will RUN as soon as it has been LOADed. There is a snag, though.
The Spectrum LOAD command is not the only way to read a Basic program into the machine. Sinclair Research provides a MERGE instruction, which fetches a program from tape and then combines its lines with those which were already in the computer. The MERGE command never RUNs a program after it has been loaded, even if the program was saved using the LINE instruction. Consequently, the danger is that it's possible to break into, and list, any Basic program which would normally RUN straight away. Sinclair Research recognised this flaw when the Microdrive was designed - you can't MERGE a Microdrive file which has been saved with the LINE option, although the flaw in the tape system has not been corrected.
All anyone has to do is simply type NEW (so that there are no lines already in the computer) and "" to load the 'protected' program. Once it has loaded there'll be the normal 'OK' message. Finally, typing LIST will enable anyone to examine the program, regardless of any 'anti-break' mechanisms in it. It's a technique that, unfortunately, allows people to intercept the program before it has time to set up protection against STOP or BREAK.
At first sight SAVE "?" LINE would seem to be the only way to produce a Spectrum program which will RUN as
soon as it is loaded - but experience in
the shops will show that this is not the
Some programs are able to 'auto- RUN' even though they are saved as machine code blocks of memory. The Spectrum allows users to record the contents of any area of memory with the command SAVE "NAME" CODE START, LENGTH. NAME is the name of the tape file and START and LENGTH are the first address of the memory and the number of bytes it contains, respectively.
It is possible to use this command to SAVE any area of memory. If you saved the entire contents of the Spectrum RAM you would be able to save a kind of 'picture' of the state of the computer - since all of the information saved would correspond to the exact state of the computer when the SAVE
command was executed. If you then
loaded that 'picture' back you would
overwrite everything that had been done
since the SAVE was carried out. In
effect, you would restore the computer
to its state when the SAVE was underway. |
The Spectrum stores Basic in an area of memory, just as it stores everything else! The computer also uses 180 bytes of memory to store a description of the current Basic program, including notes on which variables are being used, what line is being executed, and so on. The program below saves itself as a CODE area, while the Basic is running. RUN it - it will save itself and then print a message. Then reset the computer (either by typing RANDOMIZE USR 0 or by pulling out the plug). When you load what was saved, you will find that the
Basic will pick up just where it left off.
Let's see it:
Now we have found a new way of making a Basic program RUN as soon as it is loaded. Of course, we could have started some machine code instead if we had put an appropriate USR call (to the first part of the code) on line 120. The advantage of this technique over SAVE "?" LINE is that you can't disable it with a MERGE instruction. In fact both of these techniques are used quite commonly in commercial software.
There is one other bonus of saving programs as CODE rather than Basic. If you replace the value 23552 with 16384 in line 110, you will create a single file which contains both Basic and the display picture at the moment of the SAVE. This combined file will load more quickly than two separate 'screen' and 'program' files. The only snag is that you have to save the contents of the printer buffer (256 bytes) since that is sandwiched in memory between the 'screen' storage and the Basic.
Unfortunately, it is still possible to break into a program saved as CODE, but it's rather more difficult, especially if the program is a long one. The LOAD "" CODE command allows you to specify a new load address for the taped program, so that you can stop it taking over by loading it into an area of memory where it will not overwrite your loader. This is obviously not easy on a 16K Spectrum.
Another snag of using SAVE "?" CODE rather than SAVE "?" LINE is that the VERIFY command doesn't usually succeed when you try to check the CODE block, even if the SAVE was perfectly successful. This is because our 'picture' saves a few values which are constantly changing without harm to the BASIC (the time, for instance) so that VERIFY will find that the file on tape is almost always different from the contents of the memory it came from.
Some software publishers use the three byte internal timer of the Spectrum as a way of detecting whether or not a program has been meddled with - they set the time to a fixed value when the program is saved, and then check for that value when the program runs. If there is a discrepancy of more than a few seconds the program self-destructs!
At least the usual way to foil such protection is rather long-winded. You have to break into the program once it has loaded and find the code which checks the time (search for the value 32673 in memory). Next, you need to examine the code using a disassembler, and disable it by altering or skipping it. Chapter 18 of the Spectrum manual contains a good example of the use of the timer.
KEEPING CONTROLWe've shown how it's possible to take over control of the computer during a LOAD. But how can a program keep control after the LOAD is complete?
If we aim to stop the user from saving a copy of our program, we must obviously make it impossible for them to get back to the 'OK' prompt, from which a SAVE command could be issued. Normally Basic checks the keyboard 50 times every second, to find out whether or not the Break key is pressed (among other things). We can stop this check quite easily by turning off the Spectrum's 'real time clock' which tells the computer when to examine the keys. Here's how:
This short program clobbers the Spectrum's clock. It temporarily stores a tiny machine code program in the computer's printer buffer, and then the two machine code instructions are carried
out The first one turns off the clock (243, Disable Interrupts) and the second one returns the user to Basic.
The snag is that the Spectrum needs the clock to survive! If you run the above program you'll find that the computer 'hangs up' (ignores you) as soon as the machine code has been executed. Without the clock, the Spectrum doesn't look at the keys. The INKEY$ function will still work, but INPUT is disabled. You can't enter any more instructions after the clock has been turned off. Add these lines to the program to turn off the clock before you type RUN, and you will find out the snag:
If you type BREAK, the computer will stop dead. It's waiting for another 'tick' - but will never hear one, because you've turned off the clock. Disconnect your computer and then plug it back in (be careful with the 9 volt socket, which can become loose with age). Now try to use an INPUT statement after the clock has been turned off.
This technique has other flaws. The clock is temporarily turned off during instructions such as BEEP and SAVE
(otherwise you would hear a ragged
sound as the computer keeps stopping
to look at the keyboard). Likewise the
COPY command turns off the clock
temporarily, so that the printer can be
served quickly, without interruption.
All of these commands turn the clock
back on once they have finished - you
cannot use them in a program which is
designed to work with the clock turned
The main advantage of running a program with the clock off is that it will work slightly faster, since the computer no longer has to check the keyboard 50 times a second. In practice, the advantage is not very great. However, this technique of protection is used in quite a few programs.
SOME FATAL ERRORSSo, another approach is needed to the problem and one interesting idea is to try to alter the way the computer treats 'errors'. The Spectrum classifies use of the Break key or a STOP statement as error, which means that every situation which leaves the user able to type a command such as SAVE is an error. But is it possible to 'intercept' the error before the computer gives the user the chance to SAVE?
Close examination of the Spectrum manual and ROM indicates that all errors are treated in a special way. The computer fetches an address from locations 23613-4 (called ERR-SP in the manual). That address is, in turn, the address of another location in memory. Next, the computer fetches the value in that location, and carries out a machine code GO TO to the address indicated!
This is a rather tangled route, but it allows the computer to get out of an error without losing track of its memory. The mechanism is quite complicated, but it all hinges on the value in locations 23613 and 23614. If we alter those values, we alter the way the Spectrum treats an error.
The next program example forces the Spectrum to jump to location zero whenever an error occurs. If you run the program you'll find that the computer resets itself - destroying the program - as soon as you type BREAK. Here it is:
The program forces Basic to look at addresses 23298 and 23299 - the printer buffer, once again - whenever an error occurs. The computer jumps to the address specified at the start of the buffer when the error is detected. We've specified the address 0 (lines 120 and 130) so that the machine jumps to address 0, the beginning of the ROM, and promptly behaves as if it has just been turned on, scrubbing the program in the process!
In principle, you can alter the program to carry out any other option when
the Break key is pressed. Alter line
and the computer will jump to address 32512 (127 times 256 plus 0) when an error is found. If you don't want to put the address in the printer buffer you can alter the POKEs in lines 100 and 110 so that they specify a different address. At the moment they 'point' to 91 times 256 plus 2, which is 23298 - part of the printer buffer.
If you always want an error to result in a system reset, you can point at a part of the ROM which always contains the address 0. The following example illustrates a simplified routine:
These two POKEs will force the computer to reset itself whenever it would otherwise have produced an error message.
Unfortunately, there is a snag with this method of protection. Basic obviously has its own use for the value in ERR-SP. Sometimes the Spectrum will alter the value, removing your protection system. The RUN, CLEAR, GO SUB and RETURN commands all change the value of ERR-SP, so that you cannot use any of them in programs which disable BREAK in this manner. The technique is consequently not much use in complex programs, although it is quite a good way of protecting short routines which call machine code.
DISPLAY DISMAYThere is another way of protecting programs which doesn't suffer from this problem, although it brings other difficulties of its own.
The Spectrum is an unusual computer in that it splits its display into two areas - the text or graphics area at the top of the screen, and the so-called edit area at the bottom - used for commands, error messages and editing. Each area is treated separately by Basic. If we can stop the computer using the edit area we will be able to stop all modifications and commands.
Luckily the Spectrum manual contains all the information we need to do this. Location 23659, unmemorably called DF-SZ, is used to record the number of lines in the edit area of the screen. This is normally two or more, which is why you can only plot on 176 lines of the Spectrum display, even though there are 192 lines there. In fact, 16 plot lines (enough for two lines of characters) are reserved for the edit area.
When the Spectrum ROM was written, the authors presumably noted that the edit area is never completely empty (zero lines) and programmed accordingly.
That was a reasonable assumption to make, and consequently the
ROM doesn't check for the case of
zero lines. |
If we put the statement POKE 23659,0 in a program, we are telling the computer that the edit area is zero lines long. If we try to write into the edit area after that, the computer becomes confused - there are no free lines for the message. The consequence is that the computer hangs - it just sits there, impervious to the user's attempts to disturb it.
Earlier we said that all error messages are printed in the edit area of the screen. After POKE 23659,0 the edit area does not exist, so there is nowhere for the message to be printed. Any attempt to break from a program protected in this way results in the screen being cleared (a side effect of the way the computer tries to tackle the problem) and then the computer hangs.
The only flaw of this system is that it disables the Basic commands CLS and BORDER. You probably know that the command OUT 254,2 has a similar
effect to that of BORDER 2. The OUT command passes the colour code 2 (or any other value 0-7) to the Spectrum ULA, where it is used to specify the colour of the screen border. The difference between this and the BORDER command is that BORDER also controls the colour of the edit area. A BORDER statement issues an OUT command and then colours in the edit area in the same colour as the perimeter of the screen. Finally it stores the new colour in RAM so that subsequent communication with the ULA (reading the keys, for example) will not suddenly change the colour of the border of the display.
The BORDER statement consequently tries to write to the edit area of the screen. If we use BORDER after POKE 23659,0 the computer will hang when it tries to write to the bottom of the screen. Likewise the CLS command clears both parts of the display, writing to the edit area in the process. Thus, we can't use CLS and POKE 23659,0 together.
Luckily it's quite easy to write Basic or machine code subroutines to simulate BORDER and CLS. Our next program example shows how this can be done. Use GO SUB 8000 instead of
CLS, and GO SUB 8100 for BORDER. The CLS routine uses the values
of INK and PAPER selected earlier.
Adjust the value of the variable BORD
to select a border colour. Let's take a
The first subroutine is quite simple - it overwrites every line of the display with a blank space in the current colour. Each comma at the end of line 8020 tells the computer to output 16 spaces. Consequently two commas produce 32 spaces, clearing an entire line. The sub- routine only alters the top 22 lines (those normally available to the Basic programmer).
The second subroutine is a little more complex. It begins by converting the border colour into the form used in the computer's attributes table, where the PAPER colour is a multiple of eight. Then the appropriate value is stored in the 64 locations which contain the attributes of the lower two lines of the Spectrum display. This will be the entire edit area,unless you typed RUN immediately after editing and deleting a long program line.
The next step is to change the colour of the border. Line 8140 sends the new value to the ULA. Finally we must put the border colour in the computer's working storage. Location 23624 (called BORDCR) is the place reserved for this information by the Spectrum ROM. Line 8160 ensures that the computer does not change the border colour back again as soon as it next communicates with the ULA.
We now have another practical way of protecting a Spectrum program from interruption. This scheme is also popular with professional software authors.
COPY TECHNIQUESThe publishing industry regularly gets upset about the ease with which books and magazines can be photocopied for a fraction of their proper prices. The software industry suffers from similar problems, although the mechanism used for copying is quite different (have you ever wished you could photocopy a cassette or floppy disk?). There are two ways of duplicating software - dubbing and bit-copying.
Dubbing is a simple process which should be familiar to all readers. You simply take two tape recorders and connect them together, playing the original tape and recording direct on to the duplicate. Dubbing is simple, cheap and totally undefeatable. There is no
way to stop people dubbing cassette
software, so long as the software can be
played back on a standard recorder. If
there was, be sure the record companies
would have found it by now!|
The disadvantage of dubbing is that it's not very reliable. A copy is of worse quality than the master - the original hiss and distortion has been duplicated and new distortion has been added. One educational software supplier in Birmingham has carried out experiments to determine how often a tape can be dubbed before it becomes unusable. Even good-quality recorders failed to produce loadable tapes after the third 'generation' of dubbing.
A bit-copier is a program that reads data from a tape without interpreting it in any way. Programs are saved as a succession of musical tones on a cassette. The tones, or their lengths, vary to signify a '1' bit or a '0'. Almost every computer uses different tones or lengths, which is the main reason why computers can't begin to make sense of each other's tapes.
The first bits on the tape usually determine the type of file, its name, where to load it, and so on. The data to be stored then follows, interspersed with other information such as 'check- sums' (the total of bits so far, used to check for loading errors) and other marker information. A bit copier ignores
the significance of all of this information. It just reserves a large buffer of
memory, and stores bits in the buffer as
they are read from tape. Once the entire
file is stored it can be squirted out just as
it was read. |
Such a copier can make an infinite number of generations of copy, since
each duplicate is identical to the original. They pose a much greater threat to software publishers than dubbing, since they make it possible for enormous numbers of illegal copies of a program to be produced. Luckily it's easy to defeat a bit copier, although surprise to say the combined brains of the UK software industry don't seem to have worked out how.
A bit copier for a Spectrum won't
copy BBC Micro programs - the tones
and timings are different, so that the
copier would read (say) pairs and triplets of 3.4s and 11s rather than
individual 1s and 0s. A program to copy any
tape would need to store detailed timing
information about each click encountered. Such a program is impractical,
requiring very large amounts of memory
to copy even a short file. |
To fool a bit copier all you need do is store part of your file in a non-standard format. Use different tones or timings. The first part of the file is formatted the usual way, so that the computer can load it. Besides various blind alleys and tricks, it contains a devious program to read the rest.
The only way to make a bit-copy of the whole file is to decode the first part and discover exactly how it works, then write a new copier for the rest of the data. That is hard work - more than £5 or even £50 worth of work. Anyone who can do it would be better off their skills and buying software, rather than duplicating it!
TO CONCLUDEComplex and costly though it is, it seems that software protection is here to stay. The techniques involved indicate one of the most fascinating aspects of programming - how to alter the fundamental behaviour of a computer.