Cracking the Key part 3

Okay, it’s been over a year since I wrote part 2; but I thought I may as well continue with the next step. I always said I was really good at procrastination!

Anyway, we had a look at how the protection of the key module was implemented and how it was spawned. The next step is to decode the files it encodes. This is the part that can be quite irritating, if you don’t get it right the key module will hard reset the computer.

Patching the module

The first step is to edit the decoded module to remove the timer and allow us to easily kill it without it resetting.

When I patch something I prefer to minimise the changes made, this usually means that there will be less real impact from something out of true. What we’re going to do is change the SWI call to SWINV so that the SWI instruction is never run.

The first step is to follow the link for the initialisation pointer and find the call of OS_CallAfter. The observant will notice that I’ve tuned Zap aware from manky dark mode to more readable colours.

Patching the timed reset

The next step is to remove the check from the finalisation routine where it checks that it has been called internally, this will allow us to kill of the module after use.

Patching the finalisation reset

We now have the module in a state were we load it (as long as there’s a valid original disc in drive :0) and kill it off using *rmkill sol.

Decoding the Files

We’re now in a state where we can decode the files. We know from part 2 of the series that the encoded files are:

  • Code.CMP_Handle
  • Code.SFX_Handle
  • Code.Map1

We’re going to use the module to decode them in the simplest way possible. The process will be:

  1. Copy encoded files to hard disc from the original floppy disc
  2. Load up the standard !Edit from ROMFS
  3. Run the edited module
  4. Load all three files into !Edit
  5. Kill the edited module with *rmkill Sol
  6. Save the files that we loaded into !Edit
  7. Reset the computer to make sure everything’s clean

Here’s a screenshot of me doing this. Note that there are visible strings in the decoded files, which gives some indication that the process has been successful:

Decoding files

Next Step

So let’s have a look at the files we decoded. CMP_Module is a file decompressor, SFX_Module appears to handle some sound effects, but what is Map1? Loading it into !Zap is interesting:

Map1 in !Zap

Look at the first nybble of the first octet of each of those words – it’s an &E for most of them. ARM uses the first nybble of each instruction to be the condition code for the instruction, e.g. EQ, NE etc. &E maps to the code AL – i.e. always run the instruction. This likely to be ARM code, changing !Zap to code mode confirms it:

Map1 in Code mode

So what if we make a really big assumption and assume that this is the loader program? We can rename it to !RunImage (to follow convention) and set its type to &FF8 (application – i.e. it runs from address 8000) and then edit !Boot to remove all the weird stuff and passive aggressive comments:

Cleaned up !Run

Okay, let’s try this out, ejecting the disc out of drive 1 and running our doctored !Star3000, and hey, look:

SF 3000 running without copy protection