ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Wed Dec 13, 2017 5:07 pm

All times are UTC




Post new topic  Reply to topic  [ 2 posts ] 
Author Message
PostPosted: Sun Dec 28, 2014 8:51 am 
User avatar

Joined: Sat Dec 27, 2014 8:49 pm
Posts: 92
grimarc - Grim Dawn Archive File Extractor (.arc)

File Format Information
Please note this data and format is subject to change. Grim Dawn is still in alpha testing and is not completed.
The developers may change the formats at random causing this information to become invalid.
At the time of this post, the game is currently at build: B23


To start, the .arc files are broken into four sections.
Code:
file
{
    header
    file_data
    file_record_table
    file_table_of_contents
}

ARC File Header (v3)
Code:
/**
 * @brief ARC File Header (v3)
 */
struct ARC_V3_HEADER
{
    unsigned int Magic; // ARC
    unsigned int Version;
    unsigned int NumberOfFileEntries;
    unsigned int NumberOfDataRecords; // (NumberOfDataRecords * 12) = RecordTableSize
    unsigned int RecordTableSize;
    unsigned int StringTableSize;
    unsigned int RecordTableOffset;
};

  • NumberOfFileEntries is the total number of files this .arc contains.
  • NumberOfDataRecords is the total number of file parts within the second part of this .arc file.
  • RecordTableSize is the total size of the record parts table. (Each entry is 12 bytes long.)
  • StringTableSize is the total size of the string table.
  • RecordTableOffset is the offset to the file parts table.

Next, after the header is the file data parts. This chunk is handled by the next two parts of the file. So the next part we have the record table. The record table defines the file parts in the chunk of data before it. The format is:
Code:
/**
 * @brief ARC File Part Entry (v3)
 */
struct ARC_V3_FILE_PART
{
    unsigned int PartOffset;
    unsigned int CompressedSize;
    unsigned int DecompressedSize;
};

Each entry points to a part of a file. (Or a whole file if its not parted.) If the compressed size matches the decompressed size, the part is not considered compressed and can be dumped as-is. These file parts are compressed using LZ4 compression.

Following this table, is the string table. Each string is the name of a file within the archive. The string table is just a block of strings, null terminated in a row. The position of the string is the index of the file within the archive. So the first entry in the ToC table uses the first string in the string table, the second uses the second and so on. There is no string lookup in .arc files like there is in .arz files!

The last block of data in the file is the files table of contents. This is the major part of the file that is used to read and understand the rest of the file. The ToC attaches to the record table to know which blocks of data to read. The ToC is formatted like this:
Code:
/**
 * @brief ARC File Table Of Contents Entry (v3)
 */
#pragma pack(1)
struct ARC_V3_FILE_TOC_ENTRY
{
    unsigned int        EntryType;
    unsigned int        FileOffset;
    unsigned int        CompressedSize;
    unsigned int        DecompressedSize;
    unsigned int        Unknown0001; // Possible timestamp?
    unsigned __int64    FileTime;
    unsigned int        FileParts;
    unsigned int        FirstPartIndex;
    unsigned int        StringEntryLength;
    unsigned int        StringEntryOffset;
};
#pragma pop

  • EntryType determines how the entry is stored. Apparently if this is set to 1 the entry is not compressed at all. I do not believe this is used anymore and every entry I have seen has always been 3.
  • FileOffset is the offset to the first part of this file.
  • CompressedSize is the total compressed size of this file.
  • DecompressedSize is the total decompressed size of this file.
  • Unknown0001 is unknown. I think this may be some sort of timestamp.
  • FileTime is the file time of the file. (See http://msdn.microsoft.com/en-us/library ... 20(v=vs.85).aspx)
  • FileParts is the number of parts this file is broken into.
  • FirstPartIndex is the first index inside of the record table to start using as parts of this file.
  • StringEntryLength is the length of the string in the string table.
  • StringEntryOffset is the offset in the string table for this string.

_________________
My personal site: http://atom0s.com
Donations can be made via Paypal: Click Here


Last edited by atom0s on Sat Feb 13, 2016 7:40 am, edited 2 times in total.

Top
   
PostPosted: Sat Feb 13, 2016 7:29 am 
User avatar

Joined: Sat Dec 27, 2014 8:49 pm
Posts: 92
I have moved this project to Gitlab as Github has been bought over by corporate greed.
https://gitlab.com/atom0s/grimarc

_________________
My personal site: http://atom0s.com
Donations can be made via Paypal: Click Here


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 2 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited