Under the Microscope: Skeleton Warriors

After looking at Tony Hawk’s Pro Skater 2 in an previous edition of Rings of Saturn, I decided to check out Neversoft’s other titles. I chose Skeleton Warriors, the skeleton-themed beat-em-up for Saturn and PlayStation, since that was the studio’s first game.

I found that both the Saturn and PlayStation versions have some unreported cheat codes. I was able to determine one of them myself, but had to get a cryptography researcher to help with the other.

I shared my findings with Neversoft cofounder (and famous skeptic) Mick West, and he replied back with an excerpt of the the Skeleton Wars source code that confirms my findings.

Read on for the cheat codes, reverse engineering details, some intimidating math, and commentary from Mick!


The hashing code

I started where I normally do when looking for unknown cheat codes: examining how the already-known ones work. The cheat sites already list some for both versions Skeleton Warriors, and they’re entered on the pause screen.

On Saturn, the function at 06011c8c listens for input when the game is paused. Each button press updates three values in memory: the first at 06070904, the second at 0606ccd8, and a third at 0606aaa8. Here is some Python code (adapted from Ghidra’s decompilation of the game’s SH-2 assembly) that simulates the updates:

letter_map = {
    "L": 1, "R": 2, "U": 3, "D": 4,
    "A": 5, "B": 6, "C": 7,
    "X": 8, "Y": 9, "Z": 10,
}

def cheat_code_helper(x, buffer_03):
    ret = (buffer_03 & 0xFFFF) * (x & 0xFFFF)
    if (((x >> 0x10) << 0x10) | (buffer_03 >> 0x10)) == 0:
        return ret 

    y = (x & 0xFFFF) * (buffer_03 >> 0x10)
    z = (buffer_03 & 0xFFFF) * (x >> 0x10)
    return (ret + 0x10000 * (y * z)) & 0xFFFFFFFF

def process_sequence(code_buttons):
    buffer_01, buffer_02, buffer_03 = 0, 0, 1

    for button in code_buttons:
        index = letter_map[button]
        buffer_03 = (cheat_code_helper(index + 1, buffer_03) + buffer_02)
        for __ in range(4):
            if (index & 1) != 0:
                buffer_02 = buffer_02 ^ 0xA001
            a = ((buffer_01 & 0x80000000) == 0) ^ 1
            b = ((buffer_02 & 0x80000000) == 0) ^ 1
            buffer_01 = (buffer_01 * 2 + b) & 0xFFFFFFFF
            buffer_02 = (buffer_02 * 2 + a) & 0xFFFFFFFF
            index *= 2

    return (buffer_01, buffer_02, buffer_03)

That is, it’s computing some sort of hash, the result of which is stored in three 32-bit values. After you leave the pause screen, the hash values are compared to nine known ones:

On PlayStation it’s the same story, but the button mappings are different (Square is S, Triangle is T, Circle is O, X is X, and L1 is E). And there are ten target values:

One unknown cheat for each version! But what are the buttons?


A brute force approach

I first tried brute force enumeration — generating every possible button sequence, computing the hash values, and checking the results. Here’s my Python code:

from itertools import count, product

# Generate an infinite stream of button presses
def get_button_stream():
    for r in count(1):
        yield from product(letter_map, repeat=r)

# Check their hashes and print out any hits
def main():
    for code_buttons in get_button_stream():
        result = process_sequence(code_buttons)
        if result in targets:
            print(
                format(result[0], "08x"),
                format(result[1], "08x"),
                format(result[2], "08x"),
                "".join(code_buttons),
            )

This got me the missing PlayStation code! OUTDOORS, i.e. Circle, Up, Triangle, Down, Circle, Circle, Right, Square. What’s it do?

Answer: debug mode! Press all four face buttons to activate it. You can reposition your character with the D-pad, clip through walls and floors, and change items with R1:


The mathematical approach

Brute force didn’t get me anywhere with the missing Saturn code — I was able to check all of the character sequences up to length 14, but didn’t come up with the missing one.

Since the leading letters for the sequences spell things out (e.g. CRAZY BALL), I switched to something resembling dictionary attack. That is, I got a list of words; filtered it for the ones that use only U, D, L, R, A, B, C, X, Y, and Z; and then generated all possible permutations of them:

from itertools import count, permutations

def get_button_stream():
    for r in count(1):
        yield from permutations(letter_map, r)

This worked for Tony Hawk’s Pro Skater 2, but it got nowhere here. I checked the permutations up to length four (i.e. every possible ordering of four words), and had to stop the process — five would have taken forever complete.

I worked in information security long enough to know that you should never design your own hash algorithm — it will be breakable by a good cryptographer. I’m not a good cryptographer myself, so I asked for some help.

Mehdi Tibouchi is a good cryptographer. He looked at a version of the hash algorithm shown above and quickly answered:

Funny riddle. The answer is ybulldazzlzduuru, and can be obtained by a simple division in the ring F_2[x]/(x^64+1). I’ll give a more detailed answer later if needed.

Ha! I took a lot of math in school, but I didn’t get to Galois fields. Research shows that F_2[x] refers to, more or less, polynomials with binary coefficients. The division by the polynomial x^64+1 comes from the concatenation of the two 32-bit buffer_01 and buffer_02 values.

The specific answer wasn’t quite right. That was my fault, not Mehdi’s — I didn’t transcribe the algorithm correctly. I mistakenly left out the buffer_03 computation. Whoops! But his answer provided the hint I needed: dazzlz wasn’t in my word list for the dictionary attack.

I added it in, and… bingo. With that as a mandatory element in every permutation, the code popped out: RUBY BULL DAZZLZ DULL A, i.e. Right, Up, B, Y, B, Up, Left, Left, Down, A, Z, Z, L, Z, Down, Left, Left, A.

The effect is a very similar debug mode. This one lets you turn on hit boxes with the X button:

I actually knew about the effect before — here’s a video of it that I posted a while ago.


The real source

Mick West, co-founder of Neversoft, wrote a blog about his game development career. Its last post was about making Skeleton Warriors for the Saturn, and it includes some source code fragments.

I reached out to Mick about these new cheats, and he responded by sharing some of the source code for the game! Here is the actual cheat check:

Amusingly, the code keeps the Saturn debug mode buttons a secret also! There’s a comment above that says:

The cheat codes are stored as 64bit CRC checksums plus a 32 bit combination product. I’ve not worked it out, but I think the CRC of each code is practically unique and the only way to get a code from the CRC is to try all codes.

So, for most secure codes, do not used English words like DULLARD, use a random word like RLDBXYZ. For real security use a 16 letter code.

So that explains DAZZLZ. The source code also reveals some aspects of the debug controls that I missed above:

  • X+Start skips to the next stage
  • X+Z shows the coordinates
  • Holding L enables slow motion

Outro

Many thanks to Mehdi Tibouchi for the assistance. I wouldn’t have come up with the answer without his help! And many thanks also to Mick West for sharing a bit of video game history with us.

For previous coverage of long-undiscovered cheat codes, see my archive. What other games should I be looking at? I’ll have articles on some other Neversoft games in the future.

This article is syndicated from Rings of Saturn, Bo’s reverse engineering blog.

About the author

Be the first to comment

Leave a comment

Your email address will not be published.


*