How Registration Details are Stored in ClarisWorks 2.0 and 2.1

How Registration Details are Stored in ClarisWorks 2.0 and 2.1

Where is the Registration Data Stored?

Older versions of Claris software store the registration details in the data fork. In the 68k only versions of software, it is the only information stored there and so deleting all data in the data fork resets the software to unregistered (only ever try this on a duplicate copy of the program) and you are prompted to enter new registration details when you next launch the software. This is how utilities such as Repersonalize clear the registered details in early Claris software, as well as Microsoft software.

PowerPC code in Mac applications is actually stored in the data fork, in both PPC and FAT applications. This means that running a program like Repersonalize on a PPC version will damage the application by removing all the PPC code. Looking at the data fork and comparing before and after registering a fresh copy, I found that the registration information is stored at the very end of the data fork and if you know which section it is, it can be still manually removed. I used the software Resorcerer which lets you view the data fork as well as the resource fork.

The first version of ClarisWorks to support PowerPC processors natively that I know of is version 2.1, and it is specifically 2.1CDv3 that I’ve been looking at. In this exact version, the data/code at the end of the PowerPC code in the data fork is “0012 24EC” and the first offset of the registration data is at offset 134448. This will likely vary between versions.

I might write an automated tool for this at some point if I can make sure it works with various versions.

How is the Registration Data Stored?

When you register ClarisWorks 2.1CDv3 (and some other Claris software), there are three fields, Name, Company and Serial Number. All three accept just about any text. The three strings are obfuscated, concatenated, and then appended to the data fork as three pascal strings. This means that the first byte of each string is the length of the string, and the three strings are joined together (each starting with their length).

The strings are not readable as stored because each character has been XOR’d with a number. Claris alternated between two numbers, 79 and 66 (at least in ClarisWorks 2.1CDv3). XOR means Exclusive OR, and is a binary operation. XORing a byte with another byte (which we’ll call Brian for clarity) effectively inverts (flips) any bits in the byte that match locations that are a ‘1’ in Brian, when viewed in binary notation.

For example, if our byte is 11110000, and Brian is 10101010, then XORing our byte with Brian will give the result “01011010” – we flipped every second bit. By applying Brian a second time, the bits are flipped back, and we get the original data.

You can work out what the XOR value is (i.e. Brian), if you have the input byte and the result, by XORing the original value and recorded result. So, because

Result = Byte XOR Brian

It is also true that…

Brian = Byte XOR Result

Remembering that in this case the byte is the ASCII value of a known letter in the registration details.

A Worked Example

Imagine we enter the following data into the three fields in ClarisWorks to register the software…

First, lets consider the easy bit. The first string is 8 characters long, the second is 7, and the third is 6. We now know that the three lengths that will be included will be those. I made a little spreadsheet to get the ASCII values of each letter, XOR it with 79 or 66, and then display the result in Hex.

Putting the lengths and three strings together in hex we would have…

080A 2E2A 3227 2321 3607 0C2A 2621 2427 2106 1C27 3D2B 2E2E

So lets check if we got it right by loading the registered copy of ClarisWorks in Resorcerer…

Yay! It matches, so I’m not daft. The reverse is also possible, lets start with the data as stored in the datafork…

So our hex data is…

060C 2E2E 3026 3105 182D 3D29 3C03 7D6C 7E

We can see the first byte is a 6 (in hex remember, but in this instance it is 6 in hex and in decimal), so we count 6 bytes, then one more, to find the next length… which is 05, so we count 5 bytes, then one more, and find 03. So our three strings are 6, 5 and 3 characters long. Lets make another spreadsheet.

Oh look, it says “Claris”, “Works” and “2.1”! If you would like a play, you can download the spreadsheet (in OpenOffice format, compatible with Excel and LibreOffice) here :

Leave a Reply