Format : "XCR File"
Version: 1.00
Extension:  .xcr
Used by:
 Games:
  Warlords Battlecry I - SSG
  Warlords Battlecry II - SSG
Summary:

 the XCR file is an archive file of files within, with basic file
integrity checking, and encryption. No compression.

Details:

 .xcr file consists of:

  - XCR Header (28 bytes)
  - XCR Entry (0x214 per entry)
  - XCR File contents (immediately follows XCR Entry)

 Most of the following is taken from my source file. Note all offsets in
[] are in hexadecimal unless denoted otherwise.

XCR File Header Structure:
 [ 0] = "xcr File 1.00\0"
 [ 10] = number of entries
 [ 14] = filesize (total - including header+entries)

XCR File Entry Structure:
 [ 0] = (14 x Byte = ASCIIZ) Filename
 [ 200] = Offset
 [ 204] = Size
 [ 208] = 00 00 00 00
 [ 20C] = Checksum (XOR32 of file contents, incl. encryption)
 [ 210] = 01 if crypted (mirrors 211)
 [ 211] = 01 if encrypted (the real flag)
 [ 212] = ?? ??

This should basically allow anyone to create a working XCR file archive
(as I have). Everything else in the header is (so far) irrelevant. There
is a 'pathname' at offset 0x100 generated within each Entry Header, but
not used.

Advanced details:

 Checksum:

  Basic 32 bit XOR of all bytes of the file (as stored within the xcr
file). This INCLUDES the encryption. The algorithm is as below. It's quite
self explanatory, and compensates for non-4 byte boundaries. The seed is
initialized to 0 when generating the figure.

This checksum is checked when reading files, which initializes the 'seed' to
that of the checksum entry in the Entry. If the file is not tampered, the
end result after reading SHOULD be 0 ( chksum ^ (init chksum) = 0)

unsigned long update_xor32(unsigned long xorsum, unsigned char *buf, int
len)
{
int n;

        for (n = 0 ; n < len; n++)
        {
                xorsum^=(buf[n] << ( (n%4) * 8));
        }
        return xorsum;
}

 Encryption:

  This was a bitch to figure out ;). It started out a lot of trial/error
and was taking a long time, until I found a breakthrough (outside scope).
Basically the encryption appears to be a homebrew translation table. ( No,
I didn't S-I this bit ;)).

  All you had to do was figure out the 1-to-1 translation of the
characters and you'll be home free. eg. 0xD7 (encrypted) => 0x00
(decrypted).

  I'll leave the coding up to you to figure out, but.. here's the XLAT
table I use.

char xlat_tab[] = {
//0
   'm', 'r', '8', 0x22, 0x8E, 0x1F, 0xF2, 0xD6, 'w', '#', 'k', 0xD7, 0x7F,0xCC, 0xC3, 0xAB,
   'Q', 0xD8, 0x96, 0xC9, 'u', 0xFC, ' ', 0x12, 0xCA, 0xBA, '\\', 0x2E,0xDF, 0xD1, 0xB4, 't',
  0xE6, 0x87, '|', 's', 0x90, '@', '5', 0x1E, 0x0E, 0x17, 0xAD, 0x94, 'P','e', 0x3C, 0xFB,
   '4', 0xB1, 0x9C, 0xD9, '^', 0xDB, 0x9D, 0xCF, 0xD0, 'U', 'L', 'C', 'Y',0x83, 0xBE, 'b',
// 40
  0x93, 'd', '9', 'M', '(', 0xED, 'H', 0x06, 'n', ')', 0xCB, 0xE5, 0x80,0x9A, 0xE2, 0xC6,
   '?', '`', 'O', 0x16, '*', 0xB7, 'i', '0', 'h', '~', 0x03, 0x8D, 0xF3,'1', 0xFF, 'z',
   'j', '2', 'l', 0x9B, 0x0C, 'E', 0xDD, 0xBD, 0x18, 0x9F, '{', 'D', 0x10,0xB9, 'Z', 0xE3,
  0xEA, 0xF5, '}', 0xC8, 'N', '=', 0xF9, 0xAA, 0xAF, 0xF7, '3', 0xA0,0xE9, 'x', 0xC1, 0xDC,
// 80
  0xC7, '6', 0xF1, 'S', '_', 0x0D, 0xEE, 'K', 0xA7, 0x9E, 0xC2, 0xEC,0xB3, 0x15, 0xA1, '7',
  0x92, 0xAC, 0xF4, 'F', 0xD4, 'v', 0xB5, 0xDA, 'f', 0xAE, 0x1D, 0x97,0x8F, 0xA9, 0x11, 0xC4,
   '/', '+', 0x05, '$', 'A', 0xDE, 0x04, 0xEB, 0xB0, 0x8B, 0x1A, '-',0xCE, 'q', 0x8C, 0xA5,
  0x99, 0x08, 'W', 0xD3, 0x14, 'R', ']', 0x98, 'J', 'o', 0xB6, '&', 0xBC,0x07, 0xF8, 'V',
// C0
  0x3B, 0x13, 0x85, 0xD2, 'X', 'c', 0xFD, 0x3E, 0x1B, 0xE1, '%', 0xFE,'g', 0xCD, 0x81, 0xBF,
  0xA4, 0x84, 0x3A, 0x86, 0x0F, 0x91, 0xE7, 0x00, 'p', 0xD5, 0x8A, 'I','!', '\'', 0xBB, 0xE0,
  0x01, 0xF0, 0xFA, 0x89, 0xA6, 0x09, 'a', 0x0B, 'T', 0xC5, 0x82, 0xA3, 'G', 0x19, 0xB2, '[',
  0xEF, 0xE4, 0x88, 0xA8, 0x1C, 'y', 0xC0, 0x95, 0xB8, ',', 0xE8, 0x02,0xA2, 0x0A, 'B', 0xF6
 };

Notes:

 Seeing the lack of XCR file programs around, I've decided to look into
it. XCRExtractor Plus (3.02)'s author had vanished from what I've seen,
and there's not been any updates since then. Even then, XCRExPlus doesn't
"add" files, it only extracts. I believe XCRExPlus3.02 has a few bugs as
well (like it uses the pathname from XCR Entry [0x100] as filename base).

 I've released this document in hope that people can make mods and other
changes to enhance the playability of the Warlords Battlecry (I and II)
games. Buy the game, it's great!

 Oh, I can't write GUI's for crap, so hopefully with this released specs,
someone can code a better 'xcr archiver' than my Linux C program.
Please leave me some credit for the format ;) should this document be
useful.

PS. the .hro file format for WBC1 and WBC2 will hopefully be forthcoming,
if I have the time to do it.

-90hex of [tRt]
