Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

Hello,
I'm attaching an archive sample from RSC2
All the game data is packed in this format (.fa)
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

do you have another couple of samples containing different data?
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

This format is really horrible.
I guess it's the same or similar to the format used by Toca Race Driver for which, I remember, existed an extractor many years ago.

If you want to extract something you can use offzip but you miss filenames (that in any case use a sort of splitted scheme) and non-compressed data (a lot).
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

By any chance, is it similar to the Rallisport Challenge 1 format? (.rff)
Looks like it is packed the same way, but I might be wrong
I've attached an RSC1 example just for comparison
An extractor for ".rff" archives has been made years ago, I can attach it too if needed
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

If you prefer a bms script for that rff file, you can use my script 0.1.1:
http://aluigi.org/bms/rfa.bms
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

Yes, I knew about the RFFTool already, I just posted an ".rff" sample in case it could be helpful regarding the ".fa" format, by comparing it to ".rff" (hoping for similarities) :D
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

ah ok. no, it's totally different but I really remember that rc2 format used in other old games like Toca (the splitted filenames) but that's the max I remember.
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

Can this be helpful? Not .FA but .RFA, but maybe the structure is similar.
http://wiki.xentax.com/index.php?title=Battlefield_1942
As you can read it says it's the Xbox archive format for RSC1, so maybe it has been kept for RSC2 with minor changes.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

no
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

Any hopes for a script about this format?
It would be really useful :cry:
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AnonBaiter »

Perhaps it would be better to just decompress the whole .fa archive from the start, if the whole archive is compressed that is.
Actually, the 0x04 location of an .fa archive implies that the zlib file is actually just an index.

Anyway, here`s my WIP script:

Code: Select all

open FDDE "fa" 0

get INDEX_SIZE long
get DUMMY2 long
savepos INDEX_OFFSET
xmath INDEX_ZSIZE "INDEX_SIZE * (2 * 8)"
putarray 0 i INDEX_ZSIZE

clog MEMORY_FILE INDEX_OFFSET INDEX_SIZE INDEX_ZSIZE
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

This is a classical job for offzip, just as I said 2 years ago.
Maybe with the -c 0x20000 option because the files "may" be chunked.

The reason is simple, you have a TOC (information about the archived files) which is compressed and located at offset 8 after the size of compressed TOC+8 and the size of alignment (0x800). The problem is the format of this TOC which is chaotic and messed up so if you have time and experience feel free to reverse engineer that format, otherwise go easy with offzip and get most of the archive with nameless files and zero time wasted.

The solution already exists from 2 years.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AnonBaiter »

Sorry for not listening to you, but it seems like I'm already there and almost done with the format.

The only formats which used messy TOC I can think of is Dragon Quest VIII(PS2), Rogue Galaxy, and these big .PAK files that came out of SCEE PS2 games(and with lz-like compression, even!).
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »

I forgot to add @AMG in my previous post :)
Good to know that you are working on this format and I hope you will solve the mistery of that TOC
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AnonBaiter »

aluigi wrote:Good to know that you are working on this format and I hope you will solve the mistery of that TOC
I hope so.

Code: Select all

# Rallisport Challenge 2 (Xbox)
# TODO:
# 1. Decompression.
# 2. Directory tree support.

open FDDE "fa" 0

comtype deflate_noerror
get INDEX_SIZE long
get PAD_OFF long
get B1 byte
get B2 byte
savepos INDEX_OFFSET
xmath INDEX_ZSIZE "PAD_OFF * 4"
putarray 0 i INDEX_ZSIZE

clog MEMORY_FILE INDEX_OFFSET INDEX_SIZE INDEX_ZSIZE
get VER byte MEMORY_FILE
get FILES threebyte MEMORY_FILE
get FOLDERS short MEMORY_FILE
get DUMMY01 short MEMORY_FILE
for i = 0 < FOLDERS
   get SUB_ENTRIES short MEMORY_FILE
   get ENTRIES short MEMORY_FILE
   get DUMMY06 short MEMORY_FILE
   get DUMMY07 short MEMORY_FILE
   getdstring NAME 0x18 MEMORY_FILE
next i
for i = 0 < FILES
   get DUMMY09 longlong MEMORY_FILE
   get OFFSET long MEMORY_FILE
   get SIZE long MEMORY_FILE
   get BASE_OFF short MEMORY_FILE
   get CHUNKS short MEMORY_FILE
   getdstring NAME 0x2c MEMORY_FILE
   math OFFSET + PAD_OFF
   putarray 1 i OFFSET
   putarray 2 i SIZE
   putarray 3 i BASE_OFF
   putarray 4 i CHUNKS
   putarray 5 i NAME
next i

for i = 0 < FILES
   getarray OFFSET 1 i
   getarray SIZE 2 i
   getarray BASE_OFF 3 i
   getarray CHUNKS 4 i
   getarray NAME 5 i
   putvarchr MEMORY_FILE2 SIZE 0
   log MEMORY_FILE2 0 0 MEMORY_FILE
   append
   for x = 0 < CHUNKS
      get CHUNK_SIZE long MEMORY_FILE
      get CHUNK_ZSIZE long MEMORY_FILE
      get CHUNK_OFFSET long MEMORY_FILE
      get CHUNK_ZOFFSET long MEMORY_FILE
      # in case the decompression fails, just use offzip instead(with "-a -c 0x20000" parameters)
      /*
      if CHUNK_ZSIZE == CHUNK_SIZE
         log MEMORY_FILE2 CHUNK_OFFSET CHUNK_SIZE MEMORY_FILE
      else
         clog MEMORY_FILE2 CHUNK_OFFSET CHUNK_SIZE CHUNK_ZSIZE MEMORY_FILE
      endif
      */
   next x
   append
#   log MEMORY_FILE 0 SIZE MEMORY_FILE2
#   log NAME 0 SIZE MEMORY_FILE
next i
The attached .txt file is what I got so far. Decompression though is another story...
Last edited by AnonBaiter on Mon May 22, 2017 1:04 pm, edited 1 time in total.
AMG
Posts: 71
Joined: Sun Aug 10, 2014 1:13 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AMG »

Hi there, I'm back with useful informations about the format, from my friend Yallis.
He's working on his own tool for decompressing this format, but as he said, at the moment it doesn't work on all .FA files since he only examined few smaller files for now.

Anyway, here's the main .FA file layout:

uint32 compressedHeaderSize;
uint32 blockDataOffset;
byte compressedHeader[compressedHeaderSize];
byte blockData[...];

The header data is a DEFLATE compressed stream. The inflated header has
a list of nested directories with files. The files in turn consists of
a list of blocks which are DEFLATE compressed chunks in the blockData
section of the main file. When inflated these blocks are concatenated to
construct the extracted files.

This is the structure of the uncompressed header:

byte unknown0;
uint16 fileCount;
byte unknown1;
uint16 directoryCount;
uint16 blockCount;

struct Directory {
uint16 directoryCount;
uint16 fileCount;
uint16 firstFile;
uint16 firstDirectory;
char name[24];
} directories[directoryCount]

struct File {
FILETIME time;
uint32 offset;
uint32 uncompressedSize;
uint16 firstBlock;
uint16 blockCount;
char name[44];
} files[fileCount]

struct Block {
uint32 compressedSize;
uint32 uncompressedSize;
uint32 compressedOffset;
uint32 uncompressedOffset;
} blocks[blockCount];


Hoping these infos will be useful for understanding the format compression.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by AnonBaiter »

OK, I updated the script this time.

But what about the chunks? If the header is a DEFLATE compressed stream, then how come the rest of the files have a zlib header? Perhaps you could direct that question to your friend.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Post by aluigi »