Skip to content

Unmangling and decoding algorithms

ninjatobob edited this page Sep 14, 2025 · 16 revisions

Game files are obfuscated in the release versions of Fatal Racing and Whiplash using one or both of the following processes:

  • Mangling: "RLE algorithm on steroids"
  • Encoding: Fibonacci-like XOR cipher stream.

No obfuscation is used in the Fatal Racing demo or beta.

File unmangling

The Whiptools unmangler is adapted from this implementation by @samunders-core.

Mangled file specification

File header

4-byte header containing the length of the unmangled file.

Control byte

One of eight functions is performed depending on the control byte (next unread byte):

Literal / Diff / Clone
0xxxxxxx
Block
1xxxxxxx
Literal
00xxxxxx
Diff / Clone
01xxxxxx
Short block
10xxxxxx
Medium / Long block
11xxxxxx
Diff
010xxxxx
Clone
011xxxxx
Medium block
110xxxxx
Long block
111xxxxx
Byte diff
0100xxxx
Word diff
0101xxxx
Byte clone
0110xxxx
Word clone
0111xxxx
0x00–0x3F 0x40–0x4F 0x50–0x5F 0x60–0x6F 0x70–0x7F 0x80–0xBF 0xC0–0xDF 0xE0–0xFF

Original unmangler implementation

The Actua Soccer/UEFA Euro 96 England source code was accidentally distributed on the cover disc of issue 71 (May 1996) of French computer magazine Joystick, including the original unmangler implementation (UNMANGLE.C). The source code was later made available on the Gremlin Archive under a CC BY-NC-ND 4.0 licence.

Note that UNMANGLE.C ignores the 4-byte header containing the unmangled file length and instead terminates the output when a zero control byte is found. However, the header is used by SOUND.C in Fatal Racing/Whiplash (loadfile and getcompactedfilelength).

File decoding

Encoding is applied to .KC files (cheat audio activated by TOPTUNES), FATAL.INI (configuration file) and PASSWORD.INI (cheat names). To decode these, apply a bitwise XOR against the Fibonacci-like sequence $a_n = a_{n-1} + a_{n-2}$ with the first byte XORed against $a_2$, defined by the following initial constants:

  • .KC files: $a_0 = 115$, $a_1 = 150$

    Note .KC files must be unmangled first, then decoded.

  • FATAL.INI: $a_0 = 77$, $a_1 = 101$

  • PASSWORD.INI: $a_0 = 23$, $a_1 = 37$

    By decoding PASSWORD.INI in Fatal Racing V2.0 builds or Whiplash we can find two undocumented cheat names:

    • PROCESS: performs a Pentium FDIV bug check and changes to TYPE A if the bug is found or TYPE B if not
    • CLONES: not implemented.

frontend.c also calls this function with $a_0 = 43$ and $a_1 = 87$ to decode/re-encode the list of cheat names.

Clone this wiki locally