sd2 - themeldingwars/Documentation GitHub Wiki

Static Database, clientdb.sd2 located in system/db is the database file that contains the stats and item info for the items and entities in the game.

Implementations

Tools

  • Brutus - A SDB table & field name cracker
  • SDBrowser - Browser for Firefalls Static Database

Known File Info

  • Magic is a signed int equaling -629,491,106
  • Most recent file version is (build 1861) 11
  • Seems to be compressed using deflate 1.2.8 with a window size of 15

Structure

Header

Always 128 bytes long

int32 Magic;    // -629,491,106 | 0xDA7ABASE in big-endian
int32 Version;  // 11 - 12
int32 FileSize; // Size of the file contents (After Header)
int32 Flags;  // ???
int64 Timestamp;
char[104] FirefallPatch; // beta-xxxx, ascii encoded, null-terminated, zero padded

Compressed Data

Starts at offset 128 with the length set in FileSize in the header

The payload is encrypted with the help of a Mersenne Twister random number generator. The seed is the FNV hash of the patch version, e.g. beta-1869. An implementation of the MT RNG can be found below, but it's not producing an inflatable stream.

C++ Example

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>

unsigned int fnv(char* a1)
{
  char v1;
  int i;

  v1 = *a1;
  for(i = 0x811C9DC5; *a1; v1 = *a1)         // FNV hash function
  {
    ++a1;
    i = 0x1000193 * (i ^ (unsigned int)v1);
  }
  unsigned int res = 33 * (9 * (8193 * i ^ ((unsigned int)(8193 * i) >> 7)) ^ (9 * (8193 * i ^ ((unsigned int)(8193 * i) >> 7)) >> 17));
  return res;
}

struct MT {
  uint32_t *next;
  uint32_t items;
  uint32_t mt[624];
};

static uint8_t MT_getnext(struct MT *MT) {
  uint32_t r;

  if (!--MT->items) {
    uint32_t *mt = MT->mt;
    unsigned int i;

    MT->items = 624;
    MT->next = mt;

    for (i=0; i<227; i++)
      mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i+397];
    for (; i<623; i++)
      mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i-227];
    mt[623] = ((((mt[623] ^ mt[0])&0x7ffffffe)^mt[623])>>1)^((0-(mt[0]&1))&0x9908b0df)^mt[i-227];
  }

  r = *(MT->next++);
  r ^= (r >> 11);
  r ^= ((r & 0xff3a58ad) << 7);
  r ^= ((r & 0xffffdf8c) << 15);
  r ^= (r >> 18);
  return (uint8_t)(r >> 1);
}

static void MT_decrypt(unsigned char *buf, unsigned int size, uint32_t seed) {
  struct MT MT;
  unsigned int i;
  uint32_t *mt = MT.mt;

  *mt=seed;
  for(i=1; i<624; i++)
    mt[i] = i+0x6c078965*((mt[i-1]>>30)^mt[i-1]);
  MT.items = 1;
  MT.next = MT.mt;

  while(size--)
    *buf++ ^= MT_getnext(&MT);
}

int main()
{
    unsigned int hash = fnv("stabilization-1350");

    std::ifstream is ("db.sdb", std::ios::binary);
    if(is)
    {
        // get length of file:
        is.seekg (0, is.end);
        int length = is.tellg();
        is.seekg (0, is.beg);

        std::vector<char> buffer(length, 0);

        //std::cout << "Reading " << length << " characters... \n";
        // read data as a block:
        is.read(buffer.data(), length);

        if (!is)
            std::cout << "error: only " << is.gcount() << " could be read\n";
        is.close();
        
        MT_decrypt(reinterpret_cast<unsigned char*>(buffer.data()), buffer.size(), hash);
        
        std::ofstream os ("out.zip", std::ios::binary);
        
        if(os)
        {
            std::copy(buffer.begin(), buffer.end(), std::ostream_iterator<char>(os));
            os.close();
        }
        else
            std::cerr << "Couldn't open out.zip\n";
    }
}

010 Template

struct FILE
{
    struct HEADER // size 128b
    {
        uint magic; // 3665476190 // 0xDA7ABA5E
        uint version;
        uint payloadSize; 
        uint flags; // bitmask 13 = 1101
        byte unknown[8];
        char firefallPatch[9]; // beta-XXXX (larger for stabilization)
        byte padding[95];
    } header;

    byte compressed[header.payloadSize];

} file;

Useful Tools

Version History

sd2 - Version 12

  • Latest: prod-1962
  • Earliest: prod-1931

sd2 - Version 11

  • Latest: beta-1869
  • Earliest: beta-1475

sd2 - Version 9

  • Latest: beta-1460
  • Earliest: beta-1384

sd2 - Version 7

  • Latest: beta-1297
  • Earliest: beta-1297
⚠️ **GitHub.com Fallback** ⚠️