Comments

This profile is from a federated server and may be incomplete. Browse more on the original instance.

mjhelto, to privacy in I don't have anything to hide, so I don't care

“Snowed In”

mjhelto, to asklemmy in What is your unpopular flim opinion

I’ve seen this movie many times and introduced many to it. It’s one of those movies that sticks with you. I think about it a lot, I find, drawing parallels to it all the time.

mjhelto, to asklemmy in What is your unpopular flim opinion

If you like the YouTube channel “Some More News”, you should check out their “movie”. Yes, they made a movie and yes, it’s out there at times, but the way it ties real world to the 1990s Mario Bros movie is so fragmented that when they finally connect all the dots, it’s a mind blow!

mjhelto, to asklemmy in What is your unpopular flim opinion

Where I wrote of MCU was Wonder Woman. I liked the movie and acting, but the story was so dumb. I called out the antagonist from the first time I saw him. The story was the same as all the MCU movies, I realized, after it:

Here’s this unstoppable bad guy, here’s the main characters getting their ass beat by the bad guy, here’s defeatist attitudes that they can never beat the bad guy, main protagonist suddenly “believes” they can beat the bad guy, beats bad guy, and roll credits. Splash of some sort of callback end-credits gush scene, and end.

mjhelto, (edited ) to asklemmy in What is your unpopular flim opinion

How bout a third? Aqua Teen Hunger Force movies!

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

Scripts

Here is a Python implementation for v2: aswreg_v2.py and aswreg_v2core.py

With bitstring installed, you can renew codes like python aswreg_v2.py renew “L4B5-9HJ5-P3NB” “Barbara Kloeppel” 1 “EV Nova” (just sample syntax, blacklisted codes will still fail in the app). There’s also a function to check a code’s timestamp with date or create a new license with generate.

As earlier cautioned, generating basekeys relies on code copied from disassembled PPC and will likely not work outside EV: Nova. In my tests with other v2 products, all essential parts of the algorithm remain the same, even the regions of the basekey which are checked as multiples of the factors. What differs is the actual calculation of base factors. Recall that these keys were created by Ambrosia outside the local registration system, so the only options are to copy the necessary chunks of code to make passable factors for each product or to fully reverse engineer the basekey algorithm. I’ve no doubt the factors are an easy computation once you know the algorithm, but code generation becomes less critical when renewal is an option for other games. I leave it to the authors of the Zeus renewal bot if they know how to find these factors more generally.

To renew codes for other games, keep in mind the name must be correct. For instance, Pillars of Garendall is called “Garendall” internally. You can find a game’s name by typing a gibberish license in the registration app and seeing what file is created in Preferences. It should be of the form License.

Finally, a couple disclaimers: I have only tested with a handful of keys, so my interpretations and implementations may not be completely correct. YMMV. Furthermore, these code snippets are posted as an interesting case study about how a defunct company once chose to combat software piracy, not to promote piracy. Had Ambrosia remained operational, I’m sure we would have seen a v3 registration system or a move to online-based play as so many other games are doing today, but I hope this has been helpful for those who still wish to revisit their favorite Ambrosia classics.

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

The Basekey

The basekey is where we must handle timestamps and several validation checks. Consider the binary representation of the sample 0x090a1452e822bd05:


<span style="color:#323232;">binary basekey (above) and indices for reference (below):
</span><span style="color:#323232;">0000 1001 0000 1010 0001 0100 0101 0010 1110 1000 0010 0010 1011 1101 0000 0101
</span><span style="color:#323232;">b0   b3   b7   b11  b15  b19  b23  b27  b31  b35  b39  b43  b47  b51  b55  b59  b63
</span>

Timestamps

Timestamp are encoded as a single byte comprised of bits indexed at b56,51,42,37,28,23,14,9 from the basekey. In this example, the timestamp is 01100010 or 0x62 or 98.

The timestamp represents the number of fortnights that have passed since Christmas Day, 2000 Eastern time, modulo 256 to fit in one byte. For example, 98 fortnights places the code at approximately October 2004.

Stored as a single byte, there are 256 unique timestamps. This is 512 weeks or about 10 years. Yes, this means that a code’s validity rotates approximately once every decade.

After the code’s timestamp is read, it is subtracted from the current timestamp (generated from the system clock or network time server if available). The difference must be less than 2, so codes are valid for 4 weeks or about a month at a time.

Of note, Pillars of Garendall has a bug in which the modulo is not taken correctly, so the timestamp corresponding to 0xFF is valid without expiry.

Validity Check

The last three bits, b60-63, contain the sum of all other 3-bit chunks in the basekey, modulo 7. Without the correct number in these bits, the result will be considered invalid.

To this point, we have covered sufficient material to renew licenses. The timestamp can be changed, the last three bits updated, the result XOR’d with the userkey, and finally, the code converted from binary to text.

Factors for Basekey Generation

I was next curious about code generation. For the purposes of this write-up, I have not fully reverse engineered the basekey, only duplicated the aspects which are used for validation. This yields functional keys, just not genuine ones. If the authors of the EV: Nova renewal bot have fully reversed the algorithm, perhaps they will one day share the steps to genuine basekey creation.

One aspect validated by the registration app is that the licensee name, number, and game name can be modified to yield a set of base factors. These are then multiplied by some number and written into the basekey. We do not need the whole algorithm; we simply must check that the corresponding regions in the basekey are multiples of the appropriate factors.

The regions of note in the basekey are f1 = b5-9,47-51,33-37,19-23, f2 = b43-47,29-33,15-19,57-61, and f3 = b24-28,10-14,52-56,38-42. The top 5 bits and f3 are never actually checked, so they can be ignored.

Considering f1 and f2, the values in the sample basekey are 0x25DA and 0x1500, respectively. The base factors are 0x26 and 0x1C, which are multiples by 0xFF and 0xC0, respectively.

Rather than analyze the code in detail, I wrote a small script to translate over the disassembled PPC to Python wholesale. It is sufficient for generating keys to EV: Nova, using the perfectly-valid multiple of 1x, but I have found it fails for other v2 products.

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

The New System

As Ambrosia’s Matt Slot explains, the old system continued to allow a lot of piracy, so in the early 2000’s they decided to switch to a more challenging registration system. This new method was based on polynomial hashing and included a timestamp so that codes could be expired and renewed. Ambrosia now had better control over code distribution, but they assumed their renewal server would never be shut down…

They also took more aggressive steps to reduce key sharing. The registration app checks against a list of blacklisted codes, and if found to be using one, the number of licenses is internally perturbed so that subsequent calculations fail. To combat tampering, your own information can get locally blacklisted in a similar manner if too many failed attempts occur, at least until the license file is deleted. Furthermore, the app attempts to verify the system time via a remote time server to minimize registration by changing the computer’s clock.

You can disable the internet connection, set the clock back, and enter codes. There’s also a renewal bot for EV: Nova. But let us look at the algorithm more closely.

64-bit Codes

The first noticeable difference is that registration codes in v2 are now 12 digits, containing both letters and numbers. This is due to a move from a 32-bit internal code to a 64-bit one. Rather than add an ASCII offset to hex digits, every letter or number in a new registration code has a direct mapping to a chunk of 5 bits. Using 5 bits per digit supports up to 32 values, or almost all letters of the alphabet and digits up to 9 (O, I, 0, and 1 were excluded given their visual similarities).

The resulting 64 bits (really only 60 because the upper 4 are unused: 12 digits * 5 bits each = 60) are a combination of two other hashes XOR’d together. This is a notable change from v1 because it only used the registration code to verify against the hashing algorithm. Only the licensee name, number of copies, and game name were really used. In v2, the registration code is itself a hash which contains important information like a code’s timestamp.

Two Hashes

To extract such information from the registration code, we must reverse the XOR operation and split out the two hashes which were combined. Fortunately, XOR is reversible, and we can compute one of the hashes. The first hash, which I’ll call the userkey, is actually quite similar to v1’s algorithm. It loops through the licensee name, adding the ASCII value, number of copies, and shifting bits. This is repeated with the game name. An important change is including multiplication by a factor based on the string size.

The second hash, which I’ll call the basekey, is the secret sauce of v2; it’s what you pay Ambrosia to generate when registering a product. It is not computed by the registration app, but there are several properties by which it must be validated.

The chart below visualizes the relationships among the various hashes, using the well-known “Barbara Kloeppel” code for EV: Nova.


<span style="color:#323232;">TEXTCODE:
</span><span style="color:#323232;">------------------
</span><span style="color:#323232;">| L4B5-9HJ5-P3NB |
</span><span style="color:#323232;">------------------                    HASH1 (userkey):
</span><span style="color:#323232;">	|                             calculated from licensee name,
</span><span style="color:#323232;">        |                             copies, and game name
</span><span style="color:#323232;">BINCODE:                              ----------------------
</span><span style="color:#323232;">5 bits per character,             /-> | 0x0902f8932acce305 |
</span><span style="color:#323232;">plus factors &amp; rotations         /    ----------------------
</span><span style="color:#323232;">----------------------          /
</span><span style="color:#323232;">| 0x0008ecc1c2ee5e00 |   &lt;-- XOR
</span><span style="color:#323232;">----------------------          
</span><span style="color:#323232;">	                             ----------------------
</span><span style="color:#323232;">	                          -> | 0x090a1452e822bd05 |
</span><span style="color:#323232;">	                              ----------------------
</span><span style="color:#323232;">	                              HASH2 (basekey):
</span><span style="color:#323232;">	                              generated by Ambrosia,
</span><span style="color:#323232;">	                              extracted via XOR
</span>
mjhelto, (edited ) to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

I make no claim to this info, nor do I understand it, nor do I take responsibility for its use. As linked, I got this from a reddit post about the company and copy/pasted it into Obsidian so I’d have it. The code blocks are as close to the original as I cared to fiddle with. This is all greek to me but there are Python scripts linked, which may help you generate a key that works to register EV. Good luck!

Note: I had to split this into multiple posts cause it was not wanting to post the entire thing in one reply.


Ambrosia and Registration (Site)

Now that Ambrosia is gone, new registrations are no longer possible, and due to their expiring codes, using legitimate license keys has become difficult. We may hope to see a few of their games revived in the future but at present, only the original releases are available. Perhaps this case study on Ambrosia’s registration algorithms will be useful to some.

The Old System

In their earliest days, ASW didn’t require registration, but they eventually began locking core features away behind codes. All of their classic titles use the original algorithm by Andrew Welch.

Given a licensee name, number of copies, and game name, the code generator runs through two loops. The first loop iterates over each letter of the capitalized licensee name, adding the ASCII representation of that letter with the number of copies and then rotating the resulting bits. The second loop repeats that operation, only using the game’s name instead of the license holder’s name.

Beginning with Mars Rising, later games added a step to these loops: XOR the current code with the common hex string $DEADBEEF. However, the rest of the algorithm remained essentially unchanged.

The resulting 32 bits are converted into a text registration code by adding the ASCII offset of $41 to each hex digit. This maps the 32-bit string into 8 characters, but due to the limit of a hex digit to only encode 16 values, codes only contain letters from the first 16 of the alphabet.

The following chart shows an example using a well-known hacked code for Slithereens.


<span style="color:#323232;">			Iteration 1 ('A' in ANONYMOUS)
</span><span style="color:#323232;">Name: Anonymous             Code = $0 + $41
</span><span style="color:#323232;">Number: 100 (hex: $64)  ->        &lt;&lt; 6             ... -> Code = $FD53 FFA0
</span><span style="color:#323232;">Game: Slithereens                 + $64
</span><span style="color:#323232;">                                  ^ $DEAD BEEF
</span><span style="color:#323232;">                                  >> 1
</span><span style="color:#323232;">
</span><span style="color:#323232;">Add $41 to each digit:                                      Registration
</span><span style="color:#323232;">-> $41 + $F = $50 = P    ->      Reverse string        ->   ------------
</span><span style="color:#323232;">   $41 + $D = $4E = N                                       | AKPPDFNP |
</span><span style="color:#323232;">   ...                                                      ------------
</span>

Here is a Python implementation of the v1 system: aswreg_v1.py

Once you have the bit-string module installed via sudo pip install bitstring, you can test the output yourself with python aswreg_v1.py “Anonymous” 100 “Slithereens”.

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

I have a link to how to take an old serial for the game and generate a new serial based on the algorithm. When I get back to my computer I’ll send it along.

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

Usually, not intentionally. More, I was defending myself and he was buzzing around me like a moth on a summer porch light when a stray laser beam hit his ship. :(

mjhelto, to piracy in Love devs' attitude towards piracy, TruePianos v1.9.8 (audio VSTi plugin)

Old enough to remember the Ambrosia Software game, Escape Velocity? That game had a shareware setup involving a really powerful ship that would message you several times in a game and eventually get so annoying it was almost impossible to play. If you accidentally shot him, he’s ruin you. Oh, gone are the days of true “try before you buy.”

mjhelto, to lemmyshitpost in Of the tens of thousands of lies told, I wish this one was true...

Yup, when America sneezes, the world gets a cold.

mjhelto, to memes in Happy long weekend to the parents out there

As long as it can’t blink, cause that was the first disappointment I’m both the book and movie. Snakes don’t have eyelids.

mjhelto, to piracy in Do you donate to FOSS projects?

Done and done!

  • All
  • Subscribed
  • Moderated
  • Favorites
  • localhost
  • All magazines
  • Loading…
    Loading the web debug toolbar…
    Attempt #