READ THE RULES: Click here

Follow us on Facebook: https://www.facebook.com/xentax/ :)

Illusion Softworks (*.DTA) SFL Block Compression

Read or post about compression. And decompression. Or ask questions how to decompress your files.
Post Reply
Ekey
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1637
Joined: Wed Mar 31, 2010 6:54 am
Has thanked: 62 times
Been thanked: 821 times

Illusion Softworks (*.DTA) SFL Block Compression

Post by Ekey » Tue Mar 25, 2014 4:44 pm

Hi every one. I try make generic unpacker for old games by Illusion Softworks such as:
  • * Mafia - (DTA version ISD0) - Encrypted
    * Chameleon - (DTA version ISD1) - Encrypted
    * Hidden & Dangerous 2 - (DTA version ISD0) - Encrypted
    * Hidden & Dangerous 2 : Sabre Squadron - (DTA version ISD0 + ISD1) - Encrypted
    * Wings of War - (DTA version ISD1) - Not Encrypted
but need help with decompressing file datas. With comptype scanner i found compression method - it's SFL Block (#34). Ok here general info about structure DTA's , quick and crappy code.

Code: Select all

struct t_DTAHeader
{
   DWORD dwID; //Can be ISD0 and ISD1
   DWORD dwTotalFiles;
   DWORD dwTableOffset;
   DWORD dwTableSize;
};

struct t_DTATableEntry
{
   DWORD dwUnknown;
   DWORD dwOffsetAH;  // Offset for additional header
   DWORD dwOffsetFD;  // Offset for compressed file data
   char pFileNameHint[16];
};

// Additional header
struct t_DTA_AC_ISD1
{
    DWORD dwExtra1;
    DWORD dwExtra2;
    DWORD dwExtra3;
    DWORD dwExtra4;
    DWORD dwSize; // Decompressed size
    DWORD dwBlocksCount; // Nums of compressed block for current file data
    DWORD pExtra5;
    DWORD pFNameLength; // &0x7FFF (or you can use 2x short)
};
  
   DWORD dwTempPos = 0;
   t_DTAHeader pDTAHeader;
   t_DTATableEntry pDTATableEntry;
   t_DTA_AC_ISD1 pDTAACISD1;
   
   // Reading header
   fread(&pDTAHeader, sizeof(pDTAHeader), 1, fi);
   fseek(fi, pDTAHeader.dwTableOffset, SEEK_SET);
   
   for(int i = 0; i < pDTAHeader.dwTotalFiles; i++)
   {
      fread(&pDTATableEntry, sizeof(pDTATableEntry), 1, fi);
      fseek(fi, pDTATableEntry.dwOffsetAH, SEEK_SET);
	  

      // Read additional header
      fread(&pDTAACISD1, sizeof(pDTAACISD1), 1, fi);
      unsigned char* pFileName = new unsigned char[pDTAACISD0.pFNameLength & 0x7FFF];
      memset(pFileName, 0, pDTAACISD1.pFNameLength & 0x7FFF);
      fread(pFileName, sizeof(char), pDTAACISD1.pFNameLength & 0x7FFF, fi);
      dwTempPos = ftel(fi);
		 
      WORD wZSize;
      WORD wOSize = 0;
      WORD wUnknown;
		 
      unsigned char* pDstBuffer = new unsigned char[pDTAACISD1.dwSize];
      memset(pDstBuffer, 0, pDTAACISD1.dwSize);
      
      int pResult = 0;	 
      for(int j = 0; j < pDTAACISD1.dwBlocksCount; j++)
      {
            //Read compressed sizes after filename in additional header
            fseek(fi, dwTempPos, SEEK_SET);
            fread(&wZSize, 2, 1, fi);
            fread(&wUnknown, 2, 1, fi);
            dwTempPos = ftel(fi);
            
            unsigned char* pScrBuffer = new unsigned char[wZSize];
            memset(pScrBuffer, 0, wZSize);
            fseek(fi, pDTATableEntry.dwOffsetFD, SEEK_SET);
            fread(pScrBuffer, wZSize, 1, fi);
            pDTATableEntry.dwOffsetFD = ftel(fi);
			
            //https://github.com/imatix/gsl/blob/master/src/sflcomp.c
            wOSize = expand_block(pScrBuffer, pDstBuffer[pResult], wZSize);
            pResult = pResult + wOSize;
            free((void*) pScrBuffer);
      }
      //Save file... bla bla bla.....
   }
}
  

Well, 1st block decompressed fine, but with next blocks something wrong :( . Can someone help? Top secret files here from Wings of War.

Thanks advance for any hint :)

hdmaster
ultra-n00b
Posts: 1
Joined: Sun Jan 02, 2011 10:05 pm
Been thanked: 1 time

Re: Illusion Softworks (*.DTA) SFL Block Compression

Post by hdmaster » Wed May 07, 2014 12:51 pm

I already wrote a working generic unpacker but actually never released the sources [roll] . I'll post a link to source code here soon.
Although the DTA compression looks similar to SFL Block to me, it is a little bit different. Both use LZSS and RLE but DTA also uses some kind of differential pulse code modulation (DPCM) for WAV files.

EDIT: I've uploaded a quick & dirty VC++ 2013 sample project (uncommented): https://dl.dropboxusercontent.com/u/321 ... w_data.rar

Ekey
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1637
Joined: Wed Mar 31, 2010 6:54 am
Has thanked: 62 times
Been thanked: 821 times

Re: Illusion Softworks (*.DTA) SFL Block Compression

Post by Ekey » Fri May 09, 2014 2:27 pm

Interesting. Thanks for share :)

btw:

Chameleon

Code: Select all

bilboard0.dta    0xDE75DDF2      0xDEDC644B
bilboard1.dta    0xDE75DDF2      0xDEDC644B
bilboard2.dta    0xDE75DDF2      0xDEDC644B
isdata.dta       0xDE75DDF2      0xDEDC644B
Mafia

Code: Select all

bilboard0.dta   0xA1B2C3D4      0x23463458
bilboard1.dta   0xA1B2C3D4      0x23463458
bilboard2.dta   0xA1B2C3D4      0x23463458
isdata.dta      0xA1B2C3D4      0x23463458

huckleberrypie
mega-veteran
mega-veteran
Posts: 319
Joined: Mon Apr 26, 2010 6:51 am
Has thanked: 96 times
Been thanked: 13 times

Re: Illusion Softworks (*.DTA) SFL Block Compression

Post by huckleberrypie » Wed Jun 25, 2014 2:22 pm

What kind of encryption did Illusion use for Mafia and some of their other LS3D games? Also, what exactly does the Mafia DTA Extractor do to rw_data.dll, besides allowing loose archives to be read of course? Does it disable whatever signature or encryption flag the game imposes on things?

Post Reply