How fingerprinting identified a press leak
Back on the Atari ST and Amiga illegal copies were a big problem. It's impossible to stop, but it was often worth trying to at least make it hard for copies to get cracked and distributed.
For some reason, we suspected press versions might be a source of leaks. So for Ambermoon, I implemented a fingerprinting mechanism. And lo and behold, it helped us identify a leak!
And now that I've released the source code, I can more easily show how I did it.
Some of the relevant code is sadly lost, but you can see most of it in this innocuous bit of assembly code:
ifne Fingerprint tst.b First_fingerprint ; Fingerprinted ? beq .No_print jsr Init_diagnostic_screen ; Yes lea.l Fingerprint_start_text,a1 ; Print start text jsr DI_Print jsr DI_CR jsr DI_CR lea.l First_fingerprint,a0 ; Decrypt fingerprint lea.l Batch,a1 moveq.l #-1,d1 moveq.l #Fingerprint_size-1,d7 .Loop: move.b (a0)+,d0 eor.b d1,d0 move.b d0,(a1)+ dbra d7,.Loop clr.b (a1) ; Extra EOL lea.l Batch,a1 ; Print fingerprint jsr DI_Print jsr DI_CR jsr DI_CR lea.l Fingerprint_end_text,a1 ; Print end text jsr DI_Print_text jsr Exit_diagnostic_screen ; Wait & exit .No_print: endc
Here's what it does:
-
ifne
works like#ifdef
in C/C++. So I can compile out this code. This will become important later. - Then I use a very simple decryption mechanism to print the fingerprint text (the name of the journalist or magazine).
- The user had to acknowledge the message to start the game.
Elsewhere in the code (I sadly can't show the source for this), I check a particular key combination. If Fingerprint
has been defined, I show the fingerprint text again. If I recall correctly, that time I get the text from plain ASCII right at the start of the executable. If Fingerprint
has not been defined, I briefly show some pretty colors on the screen.
Meanwhile, all over the code, in between functions and even in between data, there are these macros:
.Exit: movem.l (sp)+,d0/d2/a0 rts FINGERPRINT
As I recall there were 9 of these.
FINGERPRINT
declares a 256 byte block with a magical character combination at the start.
With an external program, I would look at the executable, find the magical characters, and then take the fingerprint text and scramble it using a different algorithm. I forget exactly how I did it, but it worked in such a way that the checksum of these 256 bytes ended up being a special value.
With a second external program, I would look at the executable, calculate the checksum of each 256 byte block, and if it had the special value, I would decrypt it to retrieve the fingerprint text.
Crucially, there is no code in the executable that reads these fingerprint blocks.
So the fingerprint text appears in 3 different ways:
- Loosely scrambled, shown very obviously when you start the game.
- At the very start of the executable, shown by pressing a special key combination.
- Hidden 9 times in data blocks spread all over the executable.
We fingerprinted some copies. We sent them to the press. Then we found an illegal copy, wherever one found illegal copies back then.
I start the game. No fingerprinting message.
I press the special key combination. No colors. Aha! So this was a fingerprinted version!
I run my little decryption program. I see the name of a pretty well-known journalist appear on screen 9 times.
So we called him. He was very apologetic. His new intern must have leaked it yada yada. We got a good rating.