Bypassing copy protection in old RISCOS software

Several months ago I became nostalgic about games I got the chance to play at school (aged about 9). Back then the school I went to hadn’t moved over to IBM PC – but had a suite of BBC Micro‘s and Acorn Archimedes computers. Unfortunately for me this made “scratching the itch” of re-playing these games somewhat more complex.

It’s not too hard to get a virtual Acorn computer up and running thanks to RPCEmu , however it took me several months to get hold of some of the games I remembered playing:

  • Sherston Software – Time Detectives The Victorians
  • Sherston Software – Aztecs
  • Sherston Software – ArcVenture I-IV (Probably Romans, but potentially others)

Whilst I’m still searching for Aztecs, I did manage to source the others. The next challenge became getting the physical floppy disks accessible to RPCEmu. After plenty of research, it turned out that none of the computers I have access to have a real Floppy Disk controller any more (and USB floppy drives wont work, as they expect an IBM PC disk geometry). I decided to pick up an old TEAK floppy disk drive and build myself a FluxEngine – This is a great project which allows you to read and store the magnetic signals from the disk.

Armed with my disk images created by FluxEngine, I was then able to install these games on my virtual Acorn. I was certain this would be the last hurdle, unfortunately for me – it wasn’t.

It turned out that even early-90s educational software came with copy protection. My understanding is that this relies on expecting to read or not read content from the disk (e.g. based on intentionally invalid CRC checks). Emulators really only work with the data in the image file, which doesn’t really capture this (although the FluxEngine copy does, the conversion to a format usable by RPCEmu loses this data). This left me with the option of either buying a physical Acorn Archimedes, or bypassing the copy protection.

Time Detectives – The Victorians

I decided to start with the game I remembered most fondly, Time Detectives. Luckily this was also the most straightforward to get working. RiscOS has application folders in a similar manner to MacOS, shift-clicking into an application folder displays additional files. After an hour or two poking around in BASIC code and associated scripts, a single line of code could be commented out to bypass the checks.

Bypassing !Runimage for Time Detectives so that it can run in an emulator

If you’re looking to get this working too, you can add “REM” to the start of “quit%=NOTFNpalset” in !Victorian.!Runimage

Hurray! Some 20+ years later I got to complete a game I remembered so fondly

ArcVenture I – The Romans

After managing to locate the original author of the ArcVenture series, he kindly provided me with the images of all ArcVenture games so that I could bypass the protections and return them to him with the protections bypassed.

Sherston Software had stepped up their copy protection efforts for the ArcVenture series – getting increasingly more complex as the series went on. After several efforts commenting out bits of BASIC code, I eventually narrowed down the copy protection to a binary “module” named ShAlloc. Thankfully there’s a really nice hex editor available for RiscOS named !Zap that made disassembly a breeze.

After getting my head round the ARM instruction set and RiscOS’s built-in debugger I was able to load the module, set a few breakpoints (on the XADFS_DiscOp calls) to figure out the execution flow. My best-guess to bypass the protection was then to modify the branch instruction at 0x208 (as shown above).

If you’re looking to liberate your ArcVenture I disk, you can modify !AVStart.ShAlloc at 0x208 to branch to &00000178.

ArcVenture II – The Egyptians

The Egyptians used similar methods (Calls to XADFS_DiscOp), however they were better obscured. Checking !AVStart.!RunImage the startup module is a binary file, with lots of garbage instructions in it. After some head scratching I realised the binary had probably been compressed in some way and was probably de-compressed in memory.

Fortunately, research led me to “!UNSQUEEZE” (Written by Colin R. Smale).Once decompressed, the binary could be examined more easily. Unfortunately this still left a large file which would be difficult to debug with the built-in RiscOS tools, enter !DDT

!DDT is an interactive Debugger, allowing you to more easily set breakpoints and step over instructions. I stared by setting breakpoints on calls to XADFS_DiscOp and then making notes of branch instructions before and after those calls. After several hours of trial and error I settled on a branch instruction to patch and was rewarded with success!

If you’re looking to bypass the protection, you need to decompress !AV2Start.!Runimage and modify the instruction at 0x81A0 from “BL &0000D84C” to “BL &000081A4”. You can then optionally re-compress with SQUEEZE.

ArcVenture III – The Vikings

The Vikings used XADFS_DiscOp, but did so without external files. Instead BASIC was being used to load words into memory and execute them. This took me some time to spot, eventually identified by adding “TRACE” commands to the basic file to spot where execution was stopping.

After the closing square-bracket I added the following to dump the relevant memory to disk so I could disassemble.

OSCLI "Save AV2-Test "+STR$~(palcode%)+" "+STR$~(P%)

This left me with a ARM binary that I could work my way through and patch, then translating the change back to the words being loaded by !RunImage.

I settled on two changes this time. My changes was to make the following changes to !AV3.!RunImage:

On BASIC line 4316, change EQUD &EB000029: to EQUD &EB000025:
On BASIC line 4317, change EQUD &EB000025: to EQUD &EB000021:

ArcVenture IV – The Saxons

This was by far the most complex of the ArcVenture series to bypass. I must have spent a day or more single-stepping through with !DDT (made even more frustrating due to frequent !DDT crashes). Again, !RunImage had been compressed with SQUEEZE.

This time the entire game had been written in C (rather than BASIC, with protection written in machine code). This meant that debugging required stepping through a single large binary. I dread to think how many different breakpoints I’d set, but eventually succeeded!

To reproduce this, you need to change !AVIV.!RunImage at 0x2F178 from “BL &0002FD20” to “BL &0002F184”.

And so there we have it. All that remains if Aztecs. I’d love to get a copy to poke around – so please get in touch if you can source one.

Recovering a certificate where the private key is marked as non-exportable

When importing a certificate and private key in Windows (e.g. from a PFX file), you are given the option to mark the key as exportable. If this is not ticked, it is not possible to export the private key at a later date.

The below instructions provide a method of extracting the private key into a PFX file.

On the server with the private key

Follow the below instructions. A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 is the thumbprint of the certificate.

From a PowerShell prompt, run the following commands to identify the file where the private key is stored:

PS C:\Windows\system32> $a = Get-Item Cert:\LocalMachine\My\A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0
PS C:\Windows\system32> $a.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName

50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1

From an elevated command prompt use PsExec to spawn a command prompt in the SYSTEM context and extract the private key data.

C:> PsExec64.exe -s -i cmd
C:> copy "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1" c:\

On a non-production computer

On a non-production computer import the public certificate part (.cer/.crt). Copy the file from above to C:\ .

From a PowerShell prompt, find the GUID that represents this computer.

PS C:\Windows\system32> Get-ItemPropertyValue Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\ -Name MachineGuid

2801936f-1239-4daa-89e5-f78df0ae0f2a

Rename the file you placed in C:\ so that the value after the underscore (_) matches the MachineGuid value. In our example, the file will now be named
50ed65430216d17c6e6efff6819c923b_2801936f-1239-4daa-89e5-f78df0ae0f2a

From a PowerShell prompt, move the file to the certificate store on this machine

PS C:\Windows\system32> Move-Item "C:\50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1" "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\50ed65430216d17c6e6efff6819c923b_2801936f-1239-4daa-89e5-f78df0ae0f2a"

From an elevated cmd prompt, run:

 C:> certutil -repairstore my AA73A8D8B69122DB7A861257400E52E4C14E39E5

If you now check the local machine certificate store you will notice a padlock icon against the certificate, indicating the private key is available. You can now export the certificate with the private key.

ADFS RADIUS Authentication Provider v1.1

The Authentication Provider I wrote for ADFS to make use of RADIUS (for use with something like SAFENET) has been updated to v1.1.

Changes include the NL localisation and support for differing claim types. Thanks to Dave Liefbroer for his work on these bits.

Custom identify claims make use of the IdentityClaims registry key, which will default to ttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn for User PrincipalNames. samAccountName etc can be used.

Updated binaries are available, but please do build this yourself.

Download: ADFS Authentication Adapter v1.1