Beispiel #1
0
        /// <summary>
        /// Deserializes the <see cref="XvEntryHeader"/> from the underlying <see cref="Stream"/> of the specified <see cref="BinaryReader"/>.
        /// </summary>
        /// <param name="reader">The <see cref="BinaryReader"/> to read from.</param>
        /// <param name="key">The hash used to decrypt <see cref="XvEntryHeader"/> information.</param>
        /// <returns>A new <see cref="XvEntryHeader"/> populated with the entry's data.</returns>
        public static XvEntryHeader Deserialize(BinaryReader reader, ulong key)
        {
            //* get the basic entry information
            XvEntryHeader header = ReadHeader(reader);

            //* set the key incase it's not updated
            header.RollingKey = key;

            //* if the archive encrypts the meta data, decrypt it
            //* thanks to daxxy
            if ((header.Flags & XvEntryHeaderFlags.SafeHeader) != XvEntryHeaderFlags.SafeHeader)
            {
                ulong fileSizeKey   = (key * XvArchive.ENTRY_KEY) ^ header.Hash,
                      dataOffsetKey = (fileSizeKey * XvArchive.ENTRY_KEY) ^ ~(header.Hash);

                uint uncompressedKey = (uint)(fileSizeKey >> 32),
                     compressedKey   = (uint)(fileSizeKey & 0xFFFFFFFF);

                header.Size           ^= uncompressedKey;
                header.CompressedSize ^= compressedKey;
                header.OffsetData     ^= dataOffsetKey;

                header.RollingKey = dataOffsetKey;

                long returnPosition = reader.BaseStream.Position;

                reader.BaseStream.Seek((long)(header.OffsetData + header.CompressedSize - IV_OFFSET), SeekOrigin.Begin);
                header.IV              = reader.ReadBytes(16);
                header.CompressedSize -= IV_OFFSET;

                reader.BaseStream.Seek(returnPosition, SeekOrigin.Begin);
            }

            return(header);
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        private static XvEntryHeader ReadHeader(BinaryReader reader)
        {
            XvEntryHeader header = new XvEntryHeader {
                Hash           = reader.ReadUInt64(),
                Size           = reader.ReadUInt32(),
                CompressedSize = reader.ReadUInt32(),
                Flags          = (XvEntryHeaderFlags)reader.ReadUInt32(),
                OffsetName     = reader.ReadUInt32(),
                OffsetData     = reader.ReadUInt64(),
                OffsetFullPath = reader.ReadUInt32(),
                LocalizeType   = reader.ReadByte(),
                LocalizeLocale = reader.ReadByte(),
                Key            = reader.ReadUInt16()
            };

            long returnPosition = reader.BaseStream.Position;

            reader.BaseStream.Seek(header.OffsetName, SeekOrigin.Begin);
            header.Name = reader.ReadStringNullTerminated();
            reader.BaseStream.Seek(header.OffsetFullPath, SeekOrigin.Begin);
            header.Path = reader.ReadStringNullTerminated();

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

            return(header);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static XvEntryHeader Deserialize(BinaryReader reader)
        {
            XvEntryHeader header = ReadHeader(reader);

            if ((header.Flags & XvEntryHeaderFlags.SafeHeader) != XvEntryHeaderFlags.SafeHeader)
            {
                throw new InvalidDataException("SAFE HEADER FLAG NOT SET BUT WRONG DESERIALIZE CALLED");
            }

            return(header);
        }