public void Compress(int level = 5)
        {
            Contract.Requires(level.IsNone() ||
                              (level >= IO.Compression.ZLib.kNoCompression && level <= IO.Compression.ZLib.kBestCompression));

            // Assume the compressed data will be at most the same size as the uncompressed data
            if (CompressedData == null || CompressedData.Length < (int)mHeader.UncompressedSize)
            {
                CompressedData = new byte[mHeader.UncompressedSize];
            }
            else
            {
                Array.Clear(CompressedData, 0, CompressedData.Length);
            }

            uint adler32;

            CompressedData = IO.Compression.ZLib.LowLevelCompress(UncompressedData, level,
                                                                  out adler32 /*mHeader.CompressedAdler32*/, CompressedData);

            mHeader.CompressedAdler32 = Adler32.Compute(CompressedData);
            if (mHeader.CompressedAdler32 != adler32)
            {
#if false
                Debug.Trace.Resource.TraceInformation("ZLib.LowLevelCompress returned different adler32 ({0}) than our computations ({1}). Uncompressed adler32={2}",
                                                      adler32.ToString("X8"),
                                                      mHeader.CompressedAdler32.ToString("X8"),
                                                      mHeader.UncompressedAdler32.ToString("X8"));
#endif
            }

            mHeader.CompressedSize = (ulong)CompressedData.LongLength;
        }
Beispiel #2
0
        uint ReadSysenvSeed(ArcView file, IEnumerable <Entry> dir, uint key)
        {
            var entry = dir.FirstOrDefault(e => e.Name.Equals("sysenv.tbl", StringComparison.InvariantCultureIgnoreCase));

            if (null == entry)
            {
                return(key);
            }
            var data = file.View.ReadBytes(entry.Offset, entry.Size);

            if (data.Length <= 4)
            {
                throw new InvalidFormatException("Invalid sysenv.tbl size");
            }
            Decrypt(data, entry.Offset, key);
            uint adler32 = LittleEndian.ToUInt32(data, 0);

            if (adler32 != Adler32.Compute(data, 4, data.Length - 4))
            {
                throw new InvalidEncryptionScheme();
            }
            using (var input = new MemoryStream(data, 4, data.Length - 4))
                using (var sysenv_stream = new ZLibStream(input, CompressionMode.Decompress))
                {
                    var seed = new byte[0x10];
                    if (0x10 != sysenv_stream.Read(seed, 0, 0x10))
                    {
                        throw new InvalidFormatException("Invalid sysenv.tbl size");
                    }
                    return(EncryptionScheme.GenerateContentKey(seed));
                }
        }
Beispiel #3
0
 public void Test_Adler32_computation(byte[] input, uint expected)
 {
     unchecked {
         var actual = Adler32.Compute(input);
         Assert.Equal((int)expected, actual);
     }
 }
Beispiel #4
0
        byte[] ReadSysenvSeed(ArcView file, Entry entry, uint key)
        {
            var data = file.View.ReadBytes(entry.Offset, entry.Size);

            if (data.Length <= 4)
            {
                throw new InvalidFormatException("Invalid sysenv.tbl size");
            }
            Decrypt(data, entry.Offset, key);
            uint adler32 = LittleEndian.ToUInt32(data, 0);

            if (adler32 != Adler32.Compute(data, 4, data.Length - 4))
            {
                throw new InvalidEncryptionScheme();
            }
            using (var input = new MemoryStream(data, 4, data.Length - 4))
                using (var sysenv_stream = new ZLibStream(input, CompressionMode.Decompress))
                {
                    var seed = new byte[0x10];
                    if (0x10 != sysenv_stream.Read(seed, 0, 0x10))
                    {
                        throw new InvalidFormatException("Invalid sysenv.tbl size");
                    }
                    return(seed);
                }
        }
        public void ReadData(System.IO.Stream s)
        {
            UncompressedData = new byte[mHeader.UncompressedSize];
            s.Read(UncompressedData, 0, UncompressedData.Length);

            mHeader.UncompressedAdler32 = Adler32.Compute(UncompressedData);
        }
        public void TestCompute()
        {
            var expected = result1;
            var result   = Adler32.Compute(test1, Encoding.ASCII);

            Assert.AreEqual(expected, result);
            Assert.IsTrue(result <= (long)uint.MaxValue);
        }
Beispiel #7
0
        void Transform(byte[] data, int index, int length)
        {
            uint key = Adler32.Compute(data, index, length);

            data[index + 0x200] ^= (byte)key;
            data[index + 0x201] ^= (byte)(key >> 8);
            data[index + 0x202] ^= (byte)(key >> 16);
            data[index + 0x203] ^= (byte)(key >> 24);
        }
Beispiel #8
0
        protected override void DecryptPre(byte[] data, int index, uint length)
        {
            uint key = Adler32.Compute(data, index, 0x100);

            data[index + 0x204] ^= (byte)key;
            data[index + 0x205] ^= (byte)(key >> 8);
            data[index + 0x206] ^= (byte)(key >> 16);
            data[index + 0x207] ^= (byte)(key >> 24);
        }
Beispiel #9
0
		public byte[] ReadZlib(byte[] content, int start, int count) {
			var zlibHeader = new ZlibHeader {
				CMF = (ZlibCompressionMethodAndFlags)reader.ReadByte(),
				FLG = (ZlibFlags)reader.ReadByte(),
			};
			if (zlibHeader.Method != ZlibCompressionMethodAndFlags.Deflate)
				throw new IOException($"Zlib compression method unsupported: {zlibHeader.CMF}");
			if ((zlibHeader.FLG & ZlibFlags.Dict) != 0)
				throw new IOException("Zlib Dict unsupported");

#if XELF_PNGREADER_DISABLE_COMPRESSION

			var blockHeader = new DeflateBlockHeader {
				Flags = (DeflateBlockHeaderFlags)reader.ReadByte(),
				Length = reader.ReadUInt16(),
				LengthComplement = reader.ReadUInt16(),
			};
			if (blockHeader.Flags != DeflateBlockHeaderFlags.Final)
				throw new IOException($"Unsupported Deflate Flags: {blockHeader.Flags}");
			if (blockHeader.Length != (ushort)~blockHeader.LengthComplement)
				throw new IOException($"Deflate Block Length corrupted: {blockHeader.Length} {~blockHeader.LengthComplement}");
			var bytes = reader.ReadBytes(blockHeader.Length);
#else

			uint adler32;
			var bytes = new byte[(Width + 1) * Height];
			using (var m = new MemoryStream(content, start + 2, count - 6)) {
				var start2 = 0;
				using (var deflate = new DeflateStream(m, CompressionMode.Decompress, true)) {
					do {
						var read = deflate.Read(bytes, start2, bytes.Length - start2);
						if (read == 0)
							break;
						start2 += read;
					} while (start2 < bytes.Length);
					deflate.Close();
					//Debug.Log($"{bytes.Length} {count}");
				}
#endif
				stream.Position = start + count - 4;
				//Debug.Log($"s={start} c={count} p={stream.Position} l={content.Length}");
				adler32 = ReadSwappedUInt32();

			}
			var computed = Adler32.Compute(bytes, 0, bytes.Length);
			if (adler32 != computed) {
				//Debug.Log($"Incorrect Adler32 | file:{adler32:X} computed:{computed:X}");
				throw new IOException($"Incorrect Adler32 | file:{adler32:X} computed:{computed:X}");
			}
			var data = GetUnfiltered(bytes);
			return data;
		}
Beispiel #10
0
        void PrepareHeader(KgdMetaData info)
        {
            Buffer.BlockCopy(PngFormat.HeaderBytes, 0, m_buffer, 0, 8);
            BigEndian.Pack(0x0D, m_buffer, 8);
            BigEndian.Pack(0x49484452, m_buffer, 0x0C);  // 'IHDR'
            BigEndian.Pack(info.Width, m_buffer, 0x10);
            BigEndian.Pack(info.Height, m_buffer, 0x14);
            m_buffer[0x18] = info.BitsPerPlane;
            m_buffer[0x19] = info.ColorType;
            uint checksum = Adler32.Compute(m_buffer, 0x10, 0x0D);

            BigEndian.Pack(checksum, m_buffer, 0x1D);
            m_buffer_size = 0x21;
        }
Beispiel #11
0
        Stream UnpackData(byte[] data, int index = 0)
        {
            int length = data.Length - index;

            if (length <= 4)
            {
                return(new MemoryStream(data, index, length));
            }
            uint adler32 = LittleEndian.ToUInt32(data, index);

            if (adler32 != Adler32.Compute(data, index + 4, length - 4))
            {
                return(new MemoryStream(data, index, length));
            }
            var input = new MemoryStream(data, index + 4, length - 4);

            return(new ZLibStream(input, CompressionMode.Decompress));
        }
Beispiel #12
0
        /// <summary>
        /// Compresses the data array.
        /// </summary>
        /// <param name="data">The data to compress.</param>
        /// <returns>The compressed data.</returns>
        private static byte[] CompressData(byte[] data)
        {
            var adler = BitConverter.GetBytes(Adler32.Compute(data));

            using (var compressedStream = new MemoryStream())
            {
                compressedStream.WriteByte(0x58);
                compressedStream.WriteByte(0x85);
                using (var outputStream = new DeflateStream(compressedStream, CompressionMode.Compress, true))
                {
                    outputStream.Write(data, 0, data.Length);
                }
                compressedStream.WriteByte(adler[3]);
                compressedStream.WriteByte(adler[2]);
                compressedStream.WriteByte(adler[1]);
                compressedStream.WriteByte(adler[0]);
                return(compressedStream.ToArray());
            }
        }
Beispiel #13
0
        void FillBuffer()
        {
            m_buffer_pos = m_buffer_size = 0;
            if (m_eof)
            {
                return;
            }
            if (m_input.PeekByte() == -1)
            {
                m_eof = true;
                BigEndian.Pack(0, m_buffer, 0);
                BigEndian.Pack(0x49454E44, m_buffer, 4);  // 'IEND'
                BigEndian.Pack(0xAE426082, m_buffer, 8);
                m_buffer_size = 12;
                return;
            }
            int chunk_size = m_input.ReadInt32();
            int type       = m_input.ReadByte();

            if (type != 2)
            {
                m_eof = true;
                return;
            }
            if (chunk_size + 12 > m_buffer.Length)
            {
                m_buffer = new byte[chunk_size + 12];
            }
            chunk_size = m_input.Read(m_buffer, 8, chunk_size);
            BigEndian.Pack(chunk_size, m_buffer, 0);
            BigEndian.Pack(0x49444154, m_buffer, 4);  // 'IDAT'
            uint checksum = Adler32.Compute(m_buffer, 8, chunk_size);

            BigEndian.Pack(checksum, m_buffer, 8 + chunk_size);
            m_buffer_size = 12 + chunk_size;
            return;
        }
Beispiel #14
0
        AzArchive ReadIndex(ArcView file, byte[] header, EncryptionScheme scheme)
        {
            int  ext_count    = LittleEndian.ToInt32(header, 4);
            int  count        = LittleEndian.ToInt32(header, 8);
            uint index_length = LittleEndian.ToUInt32(header, 12);

            if (ext_count < 1 || ext_count > 8 || !IsSaneCount(count) || index_length >= file.MaxOffset)
            {
                return(null);
            }
            var packed_index = file.View.ReadBytes(header.Length, index_length);

            if (packed_index.Length != index_length)
            {
                return(null);
            }
            Decrypt(packed_index, header.Length, scheme.IndexKey);
            uint checksum = LittleEndian.ToUInt32(packed_index, 0);

            if (checksum != Adler32.Compute(packed_index, 4, packed_index.Length - 4))
            {
                if (checksum != Crc32.Compute(packed_index, 4, packed_index.Length - 4))
                {
                    throw new InvalidFormatException("Index checksum mismatch");
                }
            }
            using (var input = new MemoryStream(packed_index, 4, packed_index.Length - 4))
            {
                var dir = ParseIndex(input, count, header.Length + index_length, file.MaxOffset);
                if (null == dir)
                {
                    return(null);
                }
                uint content_key = GetContentKey(file, dir, scheme);
                return(new AzArchive(file, this, dir, scheme.IndexKey, content_key));
            }
        }
        public static void CompressFromStream(IO.EndianWriter blockStream, System.IO.Stream source,
                                              out uint streamAdler, out int streamSize)
        {
            Contract.Requires <ArgumentNullException>(blockStream != null);
            Contract.Requires <ArgumentNullException>(source != null);

            using (var ms = new System.IO.MemoryStream((int)source.Length + Header.kSizeOf))
                using (var s = new IO.EndianStream(ms, Shell.EndianFormat.Big, permissions: FA.Write))
                    using (var cs = new CompressedStream())
                    {
                        s.StreamMode = FA.Write;

                        cs.InitializeFromStream(source);
                        cs.Compress();

                        cs.Serialize(s);

                        ms.Position = 0;
                        streamSize  = (int)ms.Length;
                        streamAdler = Adler32.Compute(ms, streamSize);

                        ms.WriteTo(blockStream.BaseStream);
                    }
        }
Beispiel #16
0
        AzArchive ReadIndex(ArcView file, byte[] header, EncryptionScheme scheme)
        {
            int  ext_count    = LittleEndian.ToInt32(header, 4);
            int  count        = LittleEndian.ToInt32(header, 8);
            uint index_length = LittleEndian.ToUInt32(header, 12);

            if (ext_count < 1 || ext_count > 8 || !IsSaneCount(count) || index_length >= file.MaxOffset)
            {
                return(null);
            }
            var packed_index = file.View.ReadBytes(header.Length, index_length);

            if (packed_index.Length != index_length)
            {
                return(null);
            }
            Decrypt(packed_index, header.Length, scheme.IndexKey);
            uint checksum = LittleEndian.ToUInt32(packed_index, 0);

            if (checksum != Adler32.Compute(packed_index, 4, packed_index.Length - 4))
            {
                if (checksum != Crc32.Compute(packed_index, 4, packed_index.Length - 4))
                {
                    throw new InvalidFormatException("Index checksum mismatch");
                }
            }
            uint base_offset = (uint)header.Length + index_length;

            using (var input = new MemoryStream(packed_index, 4, packed_index.Length - 4))
                using (var zstream = new ZLibStream(input, CompressionMode.Decompress))
                    using (var index = new BinaryReader(zstream))
                    {
                        var dir         = new List <Entry> (count);
                        var name_buffer = new byte[0x20];
                        for (int i = 0; i < count; ++i)
                        {
                            uint offset = index.ReadUInt32();
                            uint size   = index.ReadUInt32();
                            uint crc    = index.ReadUInt32();
                            index.ReadInt32();
                            if (name_buffer.Length != index.Read(name_buffer, 0, name_buffer.Length))
                            {
                                return(null);
                            }
                            var name = Binary.GetCString(name_buffer, 0, 0x20);
                            if (0 == name.Length)
                            {
                                return(null);
                            }
                            var entry = FormatCatalog.Instance.Create <Entry> (name);
                            entry.Offset = base_offset + offset;
                            entry.Size   = size;
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        uint content_key = GetContentKey(file, dir, scheme);
                        return(new AzArchive(file, this, dir, scheme.IndexKey, content_key));
                    }
        }
Beispiel #17
0
        public static byte[] GenerateChecksum(string checksum, int offset, byte[] buffer, int eof = -1)
        {
            byte[] returnValue = null;
            switch (checksum)
            {
            case "Adler8 - {1Bytes}":
                returnValue = eof == -1 ? Adler8.Compute(offset, buffer) : Adler8.Compute(offset, buffer, eof);
                break;

            case "Adler16 - {2Bytes}":
                returnValue = eof == -1 ? Adler16.Compute(offset, buffer) : Adler16.Compute(offset, buffer, eof);
                break;

            case "Adler32 - {4Bytes}":
                returnValue = eof == -1 ? Adler32.Compute(offset, buffer) : Adler32.Compute(offset, buffer, eof);
                break;

            case "Checksum8 - {1Bytes}":
                returnValue = eof == -1 ? Checksum8.Compute(offset, buffer) : Checksum8.Compute(offset, buffer, eof);
                break;

            case "Checksum16 - {2Bytes}":
                returnValue = eof == -1 ? Checksum16.Compute(offset, buffer) : Checksum16.Compute(offset, buffer, eof);
                break;

            case "Checksum24 - {3Bytes}":
                returnValue = eof == -1 ? Checksum24.Compute(offset, buffer) : Checksum24.Compute(offset, buffer, eof);
                break;

            case "Checksum32 - {4Bytes}":
                returnValue = eof == -1 ? Checksum32.Compute(offset, buffer) : Checksum32.Compute(offset, buffer, eof);
                break;

            case "Checksum40 - {5Bytes}":
                returnValue = eof == -1 ? Checksum40.Compute(offset, buffer) : Checksum40.Compute(offset, buffer, eof);
                break;

            case "Checksum48 - {6Bytes}":
                returnValue = eof == -1 ? Checksum48.Compute(offset, buffer) : Checksum48.Compute(offset, buffer, eof);
                break;

            case "Checksum56 - {7Bytes}":
                returnValue = eof == -1 ? Checksum56.Compute(offset, buffer) : Checksum56.Compute(offset, buffer, eof);
                break;

            case "Checksum64 - {8Bytes}":
                returnValue = eof == -1 ? Checksum64.Compute(offset, buffer) : Checksum64.Compute(offset, buffer, eof);
                break;

            case "CRC16 - {2Bytes}":
                Crc16 crc16 = new Crc16();
                returnValue = eof == -1 ? crc16.Compute(offset, buffer) : crc16.Compute(offset, buffer, eof);
                break;

            case "CRC16 CCITT - {2Bytes}":
                Crc16ccitt crc16Ccitt = new Crc16ccitt();
                returnValue = eof == -1 ? crc16Ccitt.Compute(offset, buffer) : crc16Ccitt.Compute(offset, buffer, eof);
                break;

            case "CRC32 - {4Bytes}":
                returnValue = eof == -1 ? Crc32.Compute(offset, buffer) : Crc32.Compute(offset, buffer, eof);
                break;

            case "HMAC SHA 1 (128)  - {16Bytes}":
                returnValue = eof == -1 ? HmacSha1.Compute(offset, buffer) : HmacSha1.Compute(offset, buffer, eof);
                break;

            case "HMAC SHA 256 - {32Bytes}":
                returnValue = eof == -1 ? HmacSha256.Compute(offset, buffer) : HmacSha256.Compute(offset, buffer, eof);
                break;

            case "HMAC SHA 384 - {48Bytes}":
                returnValue = eof == -1 ? HmacSha384.Compute(offset, buffer) : HmacSha384.Compute(offset, buffer, eof);
                break;

            case "HMAC SHA 512 - {64Bytes}":
                returnValue = eof == -1 ? HmacSha512.Compute(offset, buffer) : HmacSha512.Compute(offset, buffer, eof);
                break;

            case "MD5 - {16Bytes}":
                returnValue = eof == -1 ? Md5.Compute(offset, buffer) : Md5.Compute(offset, buffer, eof);
                break;

            case "MD5 CNG - {16Bytes}":
                returnValue = eof == -1 ? Md5Cng.Compute(offset, buffer) : Md5Cng.Compute(offset, buffer, eof);
                break;
            }
            return(returnValue);
        }