Changes

Jump to navigation Jump to search
2,557 bytes added ,  00:37, 30 July 2019
m
→‎Header versions 6+: Updated a comment
Line 14: Line 14:     
===Header version 3===
 
===Header version 3===
* byte magic[8]: "NadeoPak"
+
byte magic[8];  // "NadeoPak"
* uint32 version (3)
+
uint32 version; // 3
* uint64 headerIV
+
uint64 headerIV;
* Blowfish encrypted:
+
Blowfish encrypted:
** uint128 headerMD5
+
{
** uint32 metaDataOffset
+
    uint128 headerMD5;
** uint32 dataOffset
+
    uint32 gbxHeadersStart; // offset to metadata section
** if version >= 2
+
    uint32 dataStart;
*** uint32 metaDataUncompressedSize
+
    if version >= 2:
*** uint32 metaDataCompressedSize
+
    {
** if version >= 3
+
        uint32 gbxHeadersSize;
*** uint128
+
        uint32 gbxHeadersComprSize;
** uint32 flags
+
    }
** uint32 numFolders
+
    if version >= 3:
** FolderEntry folders[numFolders]
+
        uint128 unused;
*** uint32 parentFolderIndex (index into folders; -1 if this is a root folder)
+
    uint32 flags;
*** string name
+
    uint32 numFolders;
** Set up ivXor
+
    FolderDesc folders[numFolders]
** uint32 numFiles
+
    {
** FileEntry files[numFiles]
+
        uint32 parentFolderIndex; // index into folders; -1 if this is a root folder
*** uint32 folderIndex (index into folders)
+
        string name;
*** string name
+
    }
*** uint32
+
    Set up ivXor;
*** uint32 uncompressedSize
+
    uint32 numFiles;
*** uint32 compressedSize
+
    FileDesc files[numFiles]
*** uint32 offset
+
    {
*** uint32 [[Class IDs|classID]] (indicates the type of the file)
+
        uint32 folderIndex; // index into folders
*** uint64 flags
+
        string name;
 +
        uint32 unknown;
 +
        uint32 uncompressedSize;
 +
        uint32 compressedSize;
 +
        uint32 offset;
 +
        uint32 [[Class IDs|classID]]; // indicates the type of the file
 +
        uint64 flags;
 +
    }
 +
}
    
====Header MD5====
 
====Header MD5====
Line 71: Line 79:  
There is one special exception with .gbx files. If the specific class ID is 0x07031000 (Control::CControlText), 0x07001000 (Control::CControlBase) is used as input instead.
 
There is one special exception with .gbx files. If the specific class ID is 0x07031000 (Control::CControlText), 0x07001000 (Control::CControlBase) is used as input instead.
   −
===Header versions 6-8===
+
===Header versions 6+===
  byte magic[8]: "NadeoPak"
+
  byte magic[8];  // "NadeoPak"
  uint32 version (6, 7, 8)
+
  uint32 version;
 
  if (version >= 6)
 
  if (version >= 6)
 
  {
 
  {
  uint256   ContentsChecksum; // Checksum Sha256 of the pack contents starting at next byte
+
    uint256 ContentsChecksum;   // Checksum Sha256 of the pack contents starting at next byte
  uint32    DecryptFlags;
+
     struct SHeaderFlagsUncrypt
  if (version >= 7)
  −
  {
  −
    SAuthorInfo AuthorInfo; (version=0, string login, string nick, string zone, string extra)
  −
    string  Comment;
  −
    uint128  unused;
  −
     if (version >= 8)
   
     {
 
     {
      string CreationBuildInfo;
+
        uint32 IsHeaderPrivate    : 1;
      string AuthorUrl;
+
        uint32 UseDefaultHeaderKey : 1;
    }
+
        uint32 IsDataPrivate      : 1;
  }
+
        uint32 IsImpostor          : 1;
}
+
        uint32 __Unused__          : 28;
 
+
    };
===Header versions 9+===
+
    if (version >= 15)
byte magic[8]: "NadeoPak"
+
        uint32 HeaderMaxSize;   // 0x4000 = Small (16 KB), 0x100000 = Big (1 MB), 0x1000000 = Huge (16 MB)
uint32 version (9 or higher)
+
     if (version >= 7)
if (version >= 6)
  −
{
  −
  uint256 ContentsChecksum; // Checksum Sha256 of the pack contents starting at next byte
  −
  uint32  DecryptFlags;
  −
  if (version >= 15)
  −
    uint32 HeaderMaxSize; // 0x4000 = small, 0x100000 = big, 0x1000000 = huge
  −
  if (version >= 9)
  −
  {
  −
    SAuthorInfo AuthorInfo; (version=0, string login, string nick, string zone, string extra)
  −
    string      ManialinkUrl;
  −
    if (version >= 13)
  −
      string    DownloadUrl;
  −
    uint64      CreationDate;
  −
    string      Comment;
  −
     if (version >= 12)
   
     {
 
     {
      string   Xml;
+
        struct SAuthorInfo
      string   TitleID;
+
        {
 +
            uint32 Version;
 +
            string Login;
 +
            string Nick;
 +
            string Zone;
 +
            string ExtraInfo;
 +
        };
 +
        if (version < 9)
 +
        {
 +
            string  Comment;
 +
            uint128 unused;
 +
        }
 +
        if (version == 8)
 +
        {
 +
            string CreationBuildInfo;
 +
            string AuthorUrl;
 +
        }
 +
        if (version >= 9)
 +
        {
 +
            string ManialinkUrl;
 +
            if (version >= 13)
 +
                string DownloadUrl;
 +
            uint64 CreationDate;  // Win32 FILETIME structure
 +
            string Comment;
 +
            if (version >= 12)
 +
            {
 +
                string Xml;
 +
                string TitleID;
 +
            }
 +
            string UsageSubDir;  // to known the kind of pack it is
 +
            string CreationBuildInfo;
 +
            uint128 unused;
 +
            if (version >= 10)
 +
            {
 +
                uint32 NbIncludedPacks;
 +
                struct SIncludedPacksHeaders
 +
                {
 +
                    uint256    ContentsChecksum; // Sha256
 +
                    string      Name;
 +
                    SAuthorInfo AuthorInfo;
 +
                    string      InfoManialinkUrl;
 +
                    uint64      CreationDate;
 +
                    string      Name;
 +
                    if (version >= 11)
 +
                        uint32 IncludeDepth;
 +
                } IncludedPacks[];
 +
            }
 +
        }
 
     }
 
     }
     string      UsageSubDir; // to known the kind of pack it is
+
     Blowfish encrypted: // Unencrypted if neither SHeaderFlagsUncrypt.IsHeaderPrivate nor SHeaderFlagsUncrypt.UseDefaultHeaderKey are set
    string      CreationBuildInfo;
  −
    uint128    unused;
  −
    if (version >= 10)
   
     {
 
     {
      uint32  NbIncludedPacks;
+
        uint128 Checksum;
      struct SIncludedPacksHeaders
+
        uint32 GbxHeadersStart; // Offset to the metadata section
      {
+
        if version < 15:
         uint256    ContentsChecksum; // Sha256
+
            uint32 DataStart;     // If version >= 15: DataStart = HeaderMaxSize
         string      Name;
+
        if version >= 2:
         SAuthorInfo AuthorInfo;
+
        {
         string     InfoManialinkUrl;
+
            uint32 GbxHeadersSize;
         uint64      CreationDate;
+
            uint32 GbxHeadersComprSize;
         string     Name;
+
        }
        if (version >= 11)
+
        if version >= 14:
          uint32    NestingLevel;
+
            uint128 unused;
        } IncludedPacks[];
+
         if version >= 16:
 +
            uint32 FileSize;
 +
         if version >= 3:
 +
            uint128 unused;
 +
         if version == 6:
 +
            SAuthorInfo;
 +
         uint32 Flags;
 +
        uint32 NumFolders;
 +
        FolderDesc Folders[NumFolders]
 +
        {
 +
            int32 FolderIndexParent;
 +
            string FolderName;
 +
         }
 +
        uint32 NumFiles;
 +
         FileDesc Files[NumFiles]
 +
        {
 +
            int32 FolderIndex;
 +
            string FileName;
 +
            uint32 unknown;
 +
            uint32 UncompressedSize;
 +
            uint32 CompressedSize;
 +
            uint32 Offset;
 +
            uint32 [[Class IDs|classID]];
 +
            if version >= 17:
 +
                uint32 Size;
 +
            if version >= 14:
 +
                uint128 Checksum;
 +
            struct SFileDescFlags
 +
            {
 +
                uint32 IsHashed          : 1;
 +
                uint32 PublishFid        : 1;
 +
                uint32 Compression      : 4;
 +
                uint32 IsSeekable        : 1;
 +
                uint32 _Unknown_        : 1;
 +
                uint32 __Unused1__      : 24;
 +
                uint32 DontUseDummyWrite : 1;
 +
                uint32 OpaqueUserData   : 16;
 +
                uint32 PublicFile        : 1;
 +
                uint32 ForceNoCrypt      : 1;
 +
                uint32 __Unused2__      : 13;
 +
            };
 +
        }
 
     }
 
     }
  }
   
  }
 
  }
    
===Data===
 
===Data===
The content of each file starts at Header.dataOffset + FileEntry.offset in the .pak file. First, an 8-byte plaintext IV is read. Then, FileEntry.compressedSize bytes are read and decrypted using Blowfish in CBC mode, using the same key that was used to decrypt the header. If FileEntry.flags & 0x7C is not zero, the file is compressed and should be decompressed using zlib deflate after decryption (it will end up at FileEntry.uncompressedSize bytes).
+
The content of each file starts at Header.dataStart + FileDesc.offset in the .pak file. From version 15, the data block starts at HeaderMaxSize. First, an 8-byte plaintext IV is read. Then, FileDesc.compressedSize bytes are read and decrypted using Blowfish in CBC mode, using the same key that was used to decrypt the header. If FileDesc.flags & 0x7C is not zero, the file is compressed and should be decompressed using zlib deflate after decryption (it will end up at FileDesc.uncompressedSize bytes).
    
The type of the file can be found from the extension in the name, or, if this is not available (many file names are actually just hashes), from the [[Class IDs|class ID]].
 
The type of the file can be found from the extension in the name, or, if this is not available (many file names are actually just hashes), from the [[Class IDs|class ID]].
Line 164: Line 235:  
== Tools ==
 
== Tools ==
   −
* {{ArchiveOrg|http://forum.mania-creative.com/thread-2379.html|TMPakTool|https://web.archive.org/web/20121007000654/http://forum.mania-creative.com/thread-2379.html}}: open source tool which can open and edit .pak files in an Explorer-like interface. Comes with a C# library which you can use in your own applications to work with .pak files. [http://www.mediafire.com/file/y4klvl2op6cpd4p/TMPakTool-v0.2.zip Download] & [http://www.mediafire.com/file/lq3j99k4tk6uav9/TMPakTool-v0.2+src.zip Source code]
+
* {{ArchiveOrg|http://forum.mania-creative.com/thread-2379.html|TMPakTool|https://web.archive.org/web/20121007000654/http://forum.mania-creative.com/thread-2379.html}} - an open source tool which can open and edit .pak files in an Explorer-like interface. Comes with a C# library which you can use in your own applications to work with .pak files. [http://www.mediafire.com/file/y4klvl2op6cpd4p/TMPakTool-v0.2.zip Download] & [http://www.mediafire.com/file/lq3j99k4tk6uav9/TMPakTool-v0.2+src.zip Source code]
 
* [[GbxDump]] - a Windows tool to dump and analyze the headers of .Challenge|Map.Gbx, .Replay.Gbx, .Pack.Gbx|.pak, .ObjectInfo.Gbx and .Item.Gbx files.
 
* [[GbxDump]] - a Windows tool to dump and analyze the headers of .Challenge|Map.Gbx, .Replay.Gbx, .Pack.Gbx|.pak, .ObjectInfo.Gbx and .Item.Gbx files.
 
* [http://www.xaseco.org/tools.php GBX Data Fetcher] - a PHP module with classes to extract useful data from .Challenge|Map.Gbx files (including the thumbnail image), .Replay.Gbx files and .Pack.Gbx|.pak files, and parse their XML blocks.
 
* [http://www.xaseco.org/tools.php GBX Data Fetcher] - a PHP module with classes to extract useful data from .Challenge|Map.Gbx files (including the thumbnail image), .Replay.Gbx files and .Pack.Gbx|.pak files, and parse their XML blocks.

Navigation menu