Example #1
0
        /// <summary>
        /// Reads the PAK file metadata, including file list information and the file list
        /// </summary>
        /// <exception cref="NotSupportedException">Is thrown if the given PAK file does not have a valid signature</exception>
        private void ReadMetadata()
        {
            using (BinaryReader reader = new BinaryReader(new MemoryStream(File.ReadAllBytes(FilePath))))
            {
                reader.BaseStream.Seek(-9L, SeekOrigin.End);

                uint fileListOffset = reader.ReadUInt32();
                uint fileCount      = reader.ReadUInt32();

                if ((reader.ReadByte()) != 0x12)
                {
                    throw new NotSupportedException("The signature of this PAK file is invalid!");
                }

                reader.BaseStream.Seek(fileListOffset, SeekOrigin.Begin);

                for (uint i = 0; i < fileCount; i++)
                {
                    FileEntry fileEntry = new FileEntry();

                    fileEntry.FileNameLength = reader.ReadByte();
                    fileEntry.Compression    = reader.ReadByte();
                    fileEntry.Offset         = reader.ReadUInt32();
                    fileEntry.FileSize       = reader.ReadUInt32();
                    fileEntry.RealFileSize   = reader.ReadUInt32();

                    byte[] tempName = reader.ReadBytes(fileEntry.FileNameLength);

                    if (fileEntry.Compression < 4)
                    {
                        uint decryptionKey = (uint)Key;

                        reader.BaseStream.Seek(1L, SeekOrigin.Current);
                        fileEntry.FileName = Encoding.UTF8.GetString(XOR.Cipher(tempName, decryptionKey));
                    }
                    else
                    {
                        uint[] decryptionKey = (uint[])Key;

                        fileEntry.Compression ^= 0x20;

                        fileEntry.FileName = DecryptFileName(tempName, decryptionKey);

                        uint[] decryptionData =
                        {
                            fileEntry.Offset,
                            fileEntry.RealFileSize
                        };

                        uint[] resultData = XTEA.Decipher(16, decryptionData, decryptionKey);

                        fileEntry.Offset       = resultData[0];
                        fileEntry.RealFileSize = resultData[1];
                    }

                    Entries.Add(fileEntry);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Reads the file entries of the PAK file
        /// </summary>
        public void ReadFileEntries()
        {
            long Position = Reader.BaseStream.Position;

            Reader.BaseStream.Seek(FileListOffset, SeekOrigin.Begin);

            for (uint i = 0; i < FileCount; i++)
            {
                FileEntry fileEntry = new FileEntry();

                fileEntry.FileNameLength = Reader.ReadByte();
                fileEntry.Compression    = Reader.ReadByte();
                fileEntry.Offset         = Reader.ReadUInt32();
                fileEntry.FileSize       = Reader.ReadUInt32();
                fileEntry.RealFileSize   = Reader.ReadUInt32();

                byte[] tempName = Reader.ReadBytes(fileEntry.FileNameLength);

                if (fileEntry.Compression < 4 && fileEntry.Compression > -1)
                {
                    uint decryptionKey = (uint)Key;

                    fileEntry.Unknown1 = Reader.ReadByte();
                    fileEntry.FileName = Encoding.UTF8.GetString(XOR.Cipher(tempName, decryptionKey));
                }
                else
                {
                    uint[] decryptionKey = (uint[])Key;

                    fileEntry.Compression ^= 0x20;

                    fileEntry.FileName = DecryptFileName(tempName, decryptionKey);

                    uint[] decryptionData = new uint[]
                    {
                        fileEntry.Offset,
                        fileEntry.RealFileSize
                    };

                    uint[] resultData = XTEA.Decipher(16, decryptionData, decryptionKey);

                    fileEntry.Offset       = resultData[0];
                    fileEntry.RealFileSize = resultData[1];
                }

                Entries.Add(fileEntry);
            }

            Reader.BaseStream.Seek(Position, SeekOrigin.Begin);
        }