示例#1
0
 public override void ReadContents(byte[] bytes)
 {
     using (var ms = new MemoryStream(bytes))
     {
         var typeByte = (byte) ms.ReadByte();
         FrameType = (FrameType) (typeByte >> 4);
         Codec = (Codec) (typeByte & 0x0f);
         AVCType = AvcType.NotSet;
         if (Codec == Codec.AVC)
         {
             AVCType = (AvcType) ms.ReadByte();
             if (bytes.Length >= 5)
             {
                 switch (AVCType)
                 {
                     case AvcType.Nalu:
                         CompositionTime = Utils.GetUInt24(ms.ReadBytes(3), 0);
                         break;
                     default:
                         CompositionTime = Utils.GetUInt24(ms.ReadBytes(3), 0);
                         break;
                 }
             }
         }
         Payload = new byte[ms.Length - ms.Position];
         ms.Read(Payload, 0, Payload.Length);
     }
 }
示例#2
0
文件: Chunk.cs 项目: xupefei/APNG.NET
        internal Chunk(MemoryStream ms)
        {
            Length = Helper.ConvertEndian(ms.ReadUInt32());
            ChunkType = Encoding.ASCII.GetString(ms.ReadBytes(4));
            ChunkData = ms.ReadBytes((int)Length);
            Crc = Helper.ConvertEndian(ms.ReadUInt32());

            ParseData(new MemoryStream(ChunkData));
        }
 public GetWalletPubKeyResponse(byte[] bytes)
 {
     MemoryStream ms = new MemoryStream(bytes);
     var len = ms.ReadByte();
     UncompressedPublicKey = new PubKey(ms.ReadBytes(len));
     len = ms.ReadByte();
     var addr = Encoding.ASCII.GetString(ms.ReadBytes(len));
     Address = BitcoinAddress.GetFromBase58Data(addr);
     ChainCode = ms.ReadBytes(32);
 }
示例#4
0
文件: Chunk.cs 项目: xupefei/APNG.NET
        internal Chunk(byte[] bytes)
        {
            var ms = new MemoryStream(bytes);
            Length = Helper.ConvertEndian(ms.ReadUInt32());
            ChunkType = Encoding.ASCII.GetString(ms.ReadBytes(4));
            ChunkData = ms.ReadBytes((int)Length);
            Crc = Helper.ConvertEndian(ms.ReadUInt32());

            if (ms.Position != ms.Length)
                throw new Exception("Chunk length not correct.");
            if (Length != ChunkData.Length)
                throw new Exception("Chunk data length not correct.");

            ParseData(new MemoryStream(ChunkData));
        }
示例#5
0
 public static byte[] Decompress(this byte[] buffer)
 {
     if (buffer.Length > 17 && buffer.IsCompressed())
     {
         MemoryStream inputStream = new MemoryStream(buffer);
         int lzmaID = inputStream.ReadInt();
         int acutalSize = inputStream.ReadInt();
         int lzmaSize = inputStream.ReadInt();
         byte[] props = inputStream.ReadBytes(5);
         int lzmaBufferSize = buffer.Length - 17;
         if (lzmaBufferSize != lzmaSize)
             throw new Exception(string.Format("LZMA data corruption. Expected {0} bytes got {1}", lzmaSize, lzmaBufferSize));
         byte[] uncompressedBuffer = new byte[acutalSize];
         MemoryStream outputStream = new MemoryStream(uncompressedBuffer);
         try
         {
             LZMADecoder = new Decoder();
             LZMADecoder.SetDecoderProperties(props);
             LZMADecoder.Code(inputStream, outputStream, inputStream.Length, outputStream.Length, null);
         }
         catch (Exception e)
         {
             throw new Exception(e.Message);
         }
         return uncompressedBuffer;
     }
     else
         throw new Exception("Buffer is not compressed!");
 }
        private static ICollection<Sc2ReplayAttribute> ParseAttributes(IMpqArchive replay)
        {
            var file = replay.ReadFile("replay.attributes.events");

            using (var stream = new MemoryStream(file))
            {
                stream.Skip(5); // there is a 5-byte header; should we validate this?

                var attributeCount = stream.ReadInt32();
                var attributes = new List<Sc2ReplayAttribute>();

                for (var i = 0; i < attributeCount; i++)
                {
                    var attr = new Sc2ReplayAttribute
                               {
                                   Header = stream.ReadInt32(),
                                   Type = (Sc2ReplayAttributeType) stream.ReadInt32(),
                                   PlayerIndex = stream.ReadByte(),
                                   Value = stream.ReadBytes(4).Reverse().ToArray(),
                               };

                    attributes.Add(attr);
                }

                return attributes;
            }
        }
示例#7
0
 public void Decode(byte[] bytes)
 {
     using (var ms = new MemoryStream(bytes))
     {
         StreamId = dc.GetInt32(ms.ReadBytes(4), 0);
     }
 }
示例#8
0
		private static bool Fill(StealthMetadata output, Script metadata, byte[] data)
		{
			if(data == null || data.Length != 1 + 4 + 33)
				return false;
			MemoryStream ms = new MemoryStream(data);
			output.Version = ms.ReadByte();
			if(output.Version != 6)
				return false;
			output.Nonce = ms.ReadBytes(4);
			output.EphemKey = new PubKey(ms.ReadBytes(33));
			output.Script = metadata;
			output.Hash = Hashes.Hash256(data);
			var msprefix = new MemoryStream(output.Hash.ToBytes(false));
			output.BitField = Utils.ToUInt32(msprefix.ReadBytes(4), true);
			return true;
		}
 public void Decode(byte[] bytes)
 {
     using (var ms = new MemoryStream(bytes))
     {
         Value = dc.GetInt32(ms.ReadBytes(4), 0);
         Type = (LimitType) ms.ReadByte();
     }
 }
示例#10
0
        public void Decode(byte[] bytes)
        {
            using (var ms = new MemoryStream(bytes))
            {
                Type = (ControlType) dc.GetInt16(ms.ReadBytes(2), 0);

                switch (Type)
                {
                    case ControlType.STREAM_BEGIN:
                    case ControlType.STREAM_EOF:
                    case ControlType.STREAM_DRY:
                    case ControlType.STREAM_IS_RECORDED:
                        StreamID = dc.GetInt32(ms.ReadBytes(4), 0);
                        break;
                    case ControlType.SET_BUFFER:
                        StreamID = dc.GetInt32(ms.ReadBytes(4), 0);
                        BufferLength = dc.GetInt32(ms.ReadBytes(4), 0);
                        break;
                    case ControlType.PING_REQUEST:
                    case ControlType.PING_RESPONSE:
                        Time = dc.GetInt32(ms.ReadBytes(4), 0);
                        break;
                    case ControlType.SWFV_REQUEST:
                        break;
                    case ControlType.SWFV_RESPONSE:
                        Bytes = ms.ReadBytes(42);
                        break;
                    case ControlType.BUFFER_FULL:
                    case ControlType.BUFFER_EMPTY:
                        StreamID = dc.GetInt32(ms.ReadBytes(4), 0);
                        break;
                }
            }
        }
示例#11
0
		private static bool Fill(StealthMetadata output, Script metadata)
		{
			var ops = metadata.ToOps().ToArray();
			if(ops.Length != 2 || ops[0].Code != OpcodeType.OP_RETURN)
				return false;
			var data = ops[1].PushData;
			if(data == null || data.Length != 1 + 4 + 33)
				return false;
			MemoryStream ms = new MemoryStream(data);
			output.Version = ms.ReadByte();
			if(output.Version != 6)
				return false;
			output.Nonce = ms.ReadBytes(4);
			output.EphemKey = new PubKey(ms.ReadBytes(33));
			output.Script = metadata;
			output.Hash = Hashes.Hash256(data);
			var msprefix = new MemoryStream(output.Hash.ToBytes(false));
			output.BitField = Utils.ToUInt32(msprefix.ReadBytes(4), true);
			return true;
		}
示例#12
0
		public void SliceStreamTest()
		{
			MemoryStream MemoryStream = new MemoryStream(Encoding.ASCII.GetBytes("Hello World"));
			MemoryStream.ReadBytes(6);
			var SliceStream = MemoryStream.ReadStream();
			Assert.AreEqual("Wo", Encoding.ASCII.GetString(SliceStream.ReadBytes(2)));
			var SliceStream2 = SliceStream.ReadStream();
			Assert.AreEqual(0, SliceStream.Available());
			Assert.AreEqual("rld", Encoding.ASCII.GetString(SliceStream2.ReadBytes(3)));
			Assert.AreEqual(0, SliceStream2.Available());
		}
示例#13
0
        public byte[] DecodeImaAdpcmData()
        {
            var s = new MemoryStream(RawOutput);

            var numBlocks = DataSize / BlockAlign;
            var blockDataSize = BlockAlign - (Channels * 4);
            var outputSize = UncompressedSize * Channels * 2;

            var outOffset = 0;
            var output = new byte[outputSize];

            var predictor = new int[Channels];
            var index = new int[Channels];

            // Decode each block of IMA ADPCM data in RawOutput
            for (var block = 0; block < numBlocks; block++)
            {
                // Each block starts with a initial state per-channel
                for (var c = 0; c < Channels; c++)
                {
                    predictor[c] = s.ReadInt16();
                    index[c] = s.ReadUInt8();
                    /* unknown/reserved */ s.ReadUInt8();

                    // Output first sample from input
                    output[outOffset++] = (byte)predictor[c];
                    output[outOffset++] = (byte)(predictor[c] >> 8);

                    if (outOffset >= outputSize)
                        return output;
                }

                // Decode and output remaining data in this block
                var blockOffset = 0;
                while (blockOffset < blockDataSize)
                {
                    for (var c = 0; c < Channels; c++)
                    {
                        // Decode 4 bytes (to 16 bytes of output) per channel
                        var chunk = s.ReadBytes(4);
                        var decoded = ImaAdpcmReader.LoadImaAdpcmSound(chunk, ref index[c], ref predictor[c]);

                        // Interleave output, one sample per channel
                        var outOffsetChannel = outOffset + (2 * c);
                        for (var i = 0; i < decoded.Length; i += 2)
                        {
                            var outOffsetSample = outOffsetChannel + i;
                            if (outOffsetSample >= outputSize)
                                return output;

                            output[outOffsetSample] = decoded[i];
                            output[outOffsetSample + 1] = decoded[i + 1];
                            outOffsetChannel += 2 * (Channels - 1);
                        }

                        blockOffset += 4;
                    }

                    outOffset += 16 * Channels;
                }
            }

            return output;
        }
示例#14
0
        public Packet Parse()
        {
            var p = new Packet();

            byte header = _socket.ReceiveByte();

            int chunktype = (header & 0xC0) >> 6;
            p.ChunkType = chunktype;

            p.ChunkStreamId = header & 0x3F;

            switch (p.ChunkStreamId)
            {
                case 0:
                    p.ChunkStreamId = 64 + _socket.ReceiveByte();
                    break;
                case 1:
                    p.ChunkStreamId = 64 + _socket.ReceiveByte() + (_socket.ReceiveByte()*256);
                    break;
            }

            switch (p.ChunkType)
            {
                case 3:
                    p.TimeStamp = _previousReadPacket[p.ChunkStreamId].TimeStamp;
                    p.Length = _previousReadPacket[p.ChunkStreamId].Length;
                    p.Type = _previousReadPacket[p.ChunkStreamId].Type;
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 2:
                    p.Length = _previousReadPacket[p.ChunkStreamId].Length;
                    p.Type = _previousReadPacket[p.ChunkStreamId].Type;
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 1:
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 0:
                    break;
            }

            _previousReadPacket[p.ChunkStreamId] = p;
            int headersize = HeaderSizes[p.ChunkType];

            if (headersize == MaxHeaderSize)
            {
                p.HasAbsTimestamp = true;
            }

            if (!Operations.ContainsKey(p.ChunkStreamId))
            {
                Operations[p.ChunkStreamId] = new Operation();
            }

            if (Operations[p.ChunkStreamId].Response != null)
            {
                p = Operations[p.ChunkStreamId].Response;
                headersize = 0;
            }
            else
            {
                Operations[p.ChunkStreamId].CreateResponse(p);
            }

            headersize--;
            var headerbytes = new byte[0];
            if (headersize > 0)
            {
                headerbytes = new byte[headersize];
                _socket.Receive(headerbytes, 0, headersize);
            }
            using (var headerstream = new MemoryStream(headerbytes))
            {
                if (headersize >= 3)
                {
                    p.TimeStamp = (int) Utils.GetUInt24(headerstream.ReadBytes(3), 0);
                    if (!p.HasAbsTimestamp)
                    {
                        if (!_streamTimestamps.ContainsKey(p.ChunkStreamId)) _streamTimestamps[p.ChunkStreamId] = 0;
                        p.TimeStamp += _streamTimestamps[p.ChunkStreamId];
                        _streamTimestamps[p.ChunkStreamId] = p.TimeStamp;
                    }
                }
                if (headersize >= 6)
                {
                    p.Length = (int) Utils.GetUInt24(headerstream.ReadBytes(3), 0);
                    p.BytesRead = 0;
                    p.BytePayload = null;
                }
                if (headersize > 6)
                {
                    p.Type = (PayloadType) headerstream.ReadByte();
                }
                if (headersize == 11)
                {
                    p.MessageStreamId = DataConverter.LittleEndian.GetInt32(headerstream.ReadBytes(4), 0);
                }
            }

            int ntoread = p.Length - p.BytesRead;
            int nchunk = ChunkSizeR;

            if (ntoread < nchunk)
            {
                nchunk = ntoread;
            }
            if (p.BytePayload == null)
            {
                p.BytePayload = new byte[0];
            }

            int prevLength = p.BytePayload.Length;
            Array.Resize(ref p.BytePayload, prevLength + nchunk);
            _socket.Receive(p.BytePayload, prevLength, nchunk);

            if (p.BytesRead + nchunk != p.BytePayload.Length)
            {
                throw new Exception(String.Format("Read failed, have read {0} of {1}", p.BytePayload.Length,
                    p.BytesRead + nchunk));
            }

            p.BytesRead += nchunk;

            if (!p.IsReady())
            {
                return null;
            }
            p.DecodePayload();

            //Special cases that affect the packet parser
            switch (p.Type)
            {
                case PayloadType.CHUNK_SIZE:
                    ChunkSizeR = ((ChunkSize) p.Payload).Size;
                    break;
                case PayloadType.VIDEO:
                    var v = (Video) p.Payload;
                    v.FlvTag.TimeStamp = (uint) p.TimeStamp;
                    //v.FlvTag.StreamID = (uint)p.MessageStreamID;
                    break;
                case PayloadType.AUDIO:
                    var a = (Audio) p.Payload;
                    a.FlvTag.TimeStamp = (uint) p.TimeStamp;
                    //v.FlvTag.StreamID = (uint)p.MessageStreamID;
                    break;
            }

            return p;
        }
示例#15
0
        public async Task<Stream> DecryptDatabase(byte[] source, byte[] aesKey)
        {
            var unreadData = source;
            byte[] decryptedDatabase = null;
            try
            {
                _encryptionEngine.AlgorithmType = CryptoAlgoritmType.AES_CBC_PKCS7;
                decryptedDatabase = await _encryptionEngine.Decrypt(source, aesKey, file.pbEncryptionIV);

            }
            catch (Exception e)
            {
                throw new SecurityException("There was a problem opening your database", e);
            }
            var startBytes = new byte[32];
            var databaseReader = new MemoryStream(decryptedDatabase);

            databaseReader.ReadBytes(startBytes);
            var headerStartBytes = file.pbStreamStartBytes;
            for (int iStart = 0; iStart < 32; ++iStart)
            {
                if (startBytes[iStart] != headerStartBytes[iStart])
                    throw new Exception();
            }
            return databaseReader;
        }
示例#16
0
 protected override void ParseData(MemoryStream ms)
 {
     SequenceNumber = Helper.ConvertEndian(ms.ReadUInt32());
     FrameData = ms.ReadBytes((int) Length - 4);
 }
示例#17
0
        public ME2Texture2D(ME2PCCObject pcc, int pccExpID, String pathBioGame)
        {
            ME2ExportEntry exp = pcc.Exports[pccExpID];
            if (String.Compare(exp.ClassName, className) != 0 && String.Compare(exp.ClassName, class2) != 0 && String.Compare(exp.ClassName, class3) != 0)
            {
                throw new FormatException("Export is not a texture");
            }
            Class = exp.ClassName;
            exportOffset = exp.DataOffset;
            FullPackage = exp.PackageFullName;
            texName = exp.ObjectName;
            pccFileName = pcc.pccFileName;
            allPccs = new List<string>();
            allPccs.Add(pcc.pccFileName);
            properties = new Dictionary<string, SaltPropertyReader.Property>();
            byte[] rawData = (byte[])exp.Data.Clone();
            Compression = "No Compression";
            int propertiesOffset = SaltPropertyReader.detectStart(pcc, rawData);
            headerData = new byte[propertiesOffset];
            Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset);
            pccOffset = (uint)exp.DataOffset;
            UnpackNum = 0;
            List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pcc, rawData);
            for (int i = 0; i < tempProperties.Count; i++)
            {
                SaltPropertyReader.Property property = tempProperties[i];
                if (property.Name == "UnpackMin")
                    UnpackNum++;

                if (!properties.ContainsKey(property.Name))
                    properties.Add(property.Name, property);

                switch (property.Name)
                {
                    case "Format": texFormat = property.Value.StringValue; break;
                    case "TextureFileCacheName": arcName = property.Value.StringValue; break;
                    case "LODGroup": LODGroup = property.Value.StringValue; break;
                    case "CompressionSettings": Compression = property.Value.StringValue; break;
                    case "None": dataOffset = (uint)(property.offsetval + property.Size); break;
                }
            }
            // if "None" property isn't found throws an exception
            if (dataOffset == 0)
                throw new Exception("\"None\" property not found");

            if (!String.IsNullOrEmpty(arcName))
                FullArcPath = GetTexArchive(pathBioGame);

            imageData = new byte[rawData.Length - dataOffset];
            Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset));

            //DebugOutput.PrintLn("ImageData size = " + imageData.Length);
            pccExpIdx = pccExpID;

            MemoryStream dataStream = new MemoryStream(imageData);
            privateimgList = new List<ImageInfo>();
            dataStream.ReadValueU32(); //Current position in pcc
            numMipMaps = dataStream.ReadValueU32();
            uint count = numMipMaps;
            ArcDataSize = 0;
            //DebugOutput.PrintLn(numMipMaps + " derp");
            while (dataStream.Position < dataStream.Length && count > 0)
            {
                ImageInfo imgInfo = new ImageInfo();
                imgInfo.storageType = (storage)dataStream.ReadValueS32();
                imgInfo.uncSize = dataStream.ReadValueS32();
                imgInfo.cprSize = dataStream.ReadValueS32();
                imgInfo.offset = dataStream.ReadValueS32();
                if (imgInfo.storageType == storage.pccSto)
                {
                    imgInfo.offset = (int)dataStream.Position;
                    dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current);
                }
                else if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc)
                {
                    ArcDataSize += imgInfo.uncSize;
                }

                imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32());
                if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize))
                {
                    uint width = imgInfo.imgSize.width;
                    uint height = imgInfo.imgSize.height;
                    if (width == 4 && privateimgList.Exists(img => img.imgSize.width == width))
                        width = privateimgList.Last().imgSize.width / 2;
                    if (width == 0)
                        width = 1;
                    if (height == 4 && privateimgList.Exists(img => img.imgSize.height == height))
                        height = privateimgList.Last().imgSize.height / 2;
                    if (height == 0)
                        height = 1;
                    imgInfo.imgSize = new ImageSize(width, height);
                    if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize))
                        throw new Exception("Duplicate image size found");
                }
                privateimgList.Add(imgInfo);
                count--;
                //DebugOutput.PrintLn("ImgInfo no: " + count + ", Storage Type = " + imgInfo.storageType + ", offset = " + imgInfo.offset);
            }
            // Grab the rest for the footer
            footerData = new byte[dataStream.Length - dataStream.Position];
            footerData = dataStream.ReadBytes(footerData.Length);
        }
示例#18
0
        private ME1Package(string path)
        {
            
            DebugOutput.PrintLn("Load file : " + path);
            FileName = Path.GetFullPath(path);
            MemoryStream tempStream = new MemoryStream();
            if (!File.Exists(FileName))
                throw new FileNotFoundException("PCC file not found");
            using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
            {
                FileInfo tempInfo = new FileInfo(FileName);
                tempStream.WriteFromStream(fs, tempInfo.Length);
                if (tempStream.Length != tempInfo.Length)
                {
                    throw new FileLoadException("File not fully read in. Try again later");
                }
            }

            tempStream.Seek(12, SeekOrigin.Begin);
            int tempNameSize = tempStream.ReadValueS32();
            tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin);
            int tempGenerations = tempStream.ReadValueS32();
            tempStream.Seek(36 + tempGenerations * 12, SeekOrigin.Current);
            int tempPos = (int)tempStream.Position + 4;
            tempStream.Seek(0, SeekOrigin.Begin);
            header = tempStream.ReadBytes(tempPos);
            tempStream.Seek(0, SeekOrigin.Begin);

            if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic)
            {
                DebugOutput.PrintLn("Magic number incorrect: " + magic);
                throw new FormatException("This is not an ME1 Package file. The magic number is incorrect.");
            }
            MemoryStream listsStream;
            if (IsCompressed)
            {
                DebugOutput.PrintLn("File is compressed");
                listsStream = CompressionHelper.DecompressME1orME2(tempStream);

                //Correct the header
                IsCompressed = false;
                listsStream.Seek(0, SeekOrigin.Begin);
                listsStream.WriteBytes(header);

                // Set numblocks to zero
                listsStream.WriteValueS32(0);
                //Write the magic number
                listsStream.WriteBytes(new byte[] { 0xF2, 0x56, 0x1B, 0x4E });
                // Write 4 bytes of 0
                listsStream.WriteValueS32(0);
            }
            else
            {
                DebugOutput.PrintLn("File already decompressed. Reading decompressed data.");
                //listsStream = tempStream;
                listsStream = new MemoryStream();
                tempStream.WriteTo(listsStream);
            }
            tempStream.Dispose();
            ReadNames(listsStream);
            ReadImports(listsStream);
            ReadExports(listsStream);
        }
示例#19
0
        private void ReadExports(MemoryStream fs)
        {
            DebugOutput.PrintLn("Reading Exports...");
            fs.Seek(ExportOffset, SeekOrigin.Begin);
            exports = new List<ME1ExportEntry>();
            byte[] buffer;

            for (int i = 0; i < ExportCount; i++)
            {
                long start = fs.Position;

                fs.Seek(40, SeekOrigin.Current);
                int count = fs.ReadValueS32();
                fs.Seek(4 + count * 12, SeekOrigin.Current);
                count = fs.ReadValueS32();
                fs.Seek(4 + count * 4, SeekOrigin.Current);
                fs.Seek(16, SeekOrigin.Current);
                long end = fs.Position;
                fs.Seek(start, SeekOrigin.Begin);

                ME1ExportEntry exp = new ME1ExportEntry(this, fs.ReadBytes((int)(end - start)), (uint)start);
                buffer = new byte[exp.DataSize];
                fs.Seek(exp.DataOffset, SeekOrigin.Begin);
                fs.Read(buffer, 0, buffer.Length);
                exp.Data = buffer;
                exp.DataChanged = false;
                exp.Index = i;
                exp.PropertyChanged += exportChanged;
                exports.Add(exp);
                fs.Seek(end, SeekOrigin.Begin);
            }
        }
        public static SaveFile Deserialize(Stream input, DeserializeSettings settings)
        {
            if (input.Position + 20 > input.Length)
            {
                throw new SaveCorruptionException("not enough data for save header");
            }

            var check = input.ReadValueU32(Endian.Big);
            if (check == 0x434F4E20)
            {
                throw new SaveFormatException("Xbox 360 save game loading is in the works");

            }
            input.Seek(-4, SeekOrigin.Current);

            var readSha1Hash = input.ReadBytes(20);
            using (var data = input.ReadToMemoryStream(input.Length - 20))
            {
                byte[] computedSha1Hash;
                using (var sha1 = new System.Security.Cryptography.SHA1Managed())
                {
                    computedSha1Hash = sha1.ComputeHash(data);
                }

                if ((settings & DeserializeSettings.IgnoreSha1Mismatch) == 0 &&
                    readSha1Hash.SequenceEqual(computedSha1Hash) == false)
                {
                    throw new SaveCorruptionException("invalid SHA1 hash");
                }

                data.Position = 0;
                var uncompressedSize = data.ReadValueU32(Endian.Big);

                var uncompressedBytes = new byte[uncompressedSize];
                if (uncompressedSize <= BlockSize)
                {
                    var actualUncompressedSize = (int)uncompressedSize;
                    var compressedSize = (uint)(data.Length - 4);
                    var compressedBytes = data.ReadBytes(compressedSize);
                    var result = LZO.Decompress(compressedBytes,
                                                0,
                                                (int)compressedSize,
                                                uncompressedBytes,
                                                0,
                                                ref actualUncompressedSize);
                    if (result != LZO.ErrorCode.Success)
                    {
                        throw new SaveCorruptionException(string.Format("LZO decompression failure ({0})", result));
                    }

                    if (actualUncompressedSize != (int)uncompressedSize)
                    {
                        throw new SaveCorruptionException("LZO decompression failure (uncompressed size mismatch)");
                    }
                }
                else
                {
                    var blockCount = data.ReadValueU32(Endian.Big);
                    var blockInfos = new List<Tuple<uint, uint>>();
                    for (uint i = 0; i < blockCount; i++)
                    {
                        var blockCompressedSize = data.ReadValueU32(Endian.Big);
                        var blockUncompressedSize = data.ReadValueU32(Endian.Big);
                        blockInfos.Add(new Tuple<uint, uint>(blockCompressedSize, blockUncompressedSize));
                    }

                    int uncompressedOffset = 0;
                    int uncompressedSizeLeft = (int)uncompressedSize;
                    foreach (var blockInfo in blockInfos)
                    {
                        var blockUncompressedSize = Math.Min((int)blockInfo.Item2, uncompressedSizeLeft);
                        var actualUncompressedSize = blockUncompressedSize;
                        var compressedSize = (int)blockInfo.Item1;
                        var compressedBytes = data.ReadBytes(compressedSize);
                        var result = LZO.Decompress(compressedBytes,
                                                    0,
                                                    compressedSize,
                                                    uncompressedBytes,
                                                    uncompressedOffset,
                                                    ref actualUncompressedSize);
                        if (result != LZO.ErrorCode.Success)
                        {
                            throw new SaveCorruptionException(string.Format("LZO decompression failure ({0})", result));
                        }

                        if (actualUncompressedSize != blockUncompressedSize)
                        {
                            throw new SaveCorruptionException("LZO decompression failure (uncompressed size mismatch)");
                        }

                        uncompressedOffset += blockUncompressedSize;
                        uncompressedSizeLeft -= blockUncompressedSize;
                    }

                    if (uncompressedSizeLeft != 0)
                    {
                        throw new SaveCorruptionException("LZO decompression failure (uncompressed size left != 0)");
                    }
                }

                using (var outerData = new MemoryStream(uncompressedBytes))
                {
                    var innerSize = outerData.ReadValueU32(Endian.Big);
                    var magic = outerData.ReadString(3);
                    if (magic != "WSG")
                    {
                        throw new SaveCorruptionException("invalid magic");
                    }

                    var version = outerData.ReadValueU32(Endian.Little);
                    if (version != 2 &&
                        version.Swap() != 2)
                    {
                        throw new SaveCorruptionException("invalid or unsupported version");
                    }
                    var endian = version == 2 ? Endian.Little : Endian.Big;

                    var readCRC32Hash = outerData.ReadValueU32(endian);
                    var innerUncompressedSize = outerData.ReadValueS32(endian);

                    var innerCompressedBytes = outerData.ReadBytes(innerSize - 3 - 4 - 4 - 4);
                    var innerUncompressedBytes = Huffman.Decoder.Decode(innerCompressedBytes,
                                                                        innerUncompressedSize);
                    if (innerUncompressedBytes.Length != innerUncompressedSize)
                    {
                        throw new SaveCorruptionException("huffman decompression failure");
                    }

                    var computedCRC32Hash = CRC32.Hash(innerUncompressedBytes, 0, innerUncompressedBytes.Length);
                    if ((settings & DeserializeSettings.IgnoreCrc32Mismatch) == 0 &&
                        computedCRC32Hash != readCRC32Hash)
                    {
                        throw new SaveCorruptionException("invalid CRC32 hash");
                    }

                    using (var innerUncompressedData = new MemoryStream(innerUncompressedBytes))
                    {
                        var saveGame =
                            ProtoBuf.Serializer.Deserialize<WillowTwoSave.WillowTwoPlayerSaveGame>(innerUncompressedData);

                        if ((settings & DeserializeSettings.IgnoreReencodeMismatch) == 0)
                        {
                            using (var testData = new MemoryStream())
                            {
                                ProtoBuf.Serializer.Serialize(testData, saveGame);

                                testData.Position = 0;
                                var testBytes = testData.ReadBytes((uint)testData.Length);
                                if (innerUncompressedBytes.SequenceEqual(testBytes) == false)
                                {
                                    throw new SaveCorruptionException("reencode mismatch");
                                }
                            }
                        }

                        saveGame.Decompose();
                        return new SaveFile()
                        {
                            Endian = endian,
                            SaveGame = saveGame,
                        };
                    }
                }
            }
        }
        public void Serialize(Stream output)
        {
            var saveGame = this.SaveGame;

            byte[] innerUncompressedBytes;
            using (var innerUncompressedData = new MemoryStream())
            {
                saveGame.Compose();
                try
                {
                    ProtoBuf.Serializer.Serialize(innerUncompressedData, saveGame);
                }
                finally
                {
                    saveGame.Decompose();
                }
                innerUncompressedData.Position = 0;
                innerUncompressedBytes = innerUncompressedData.ReadBytes((uint)innerUncompressedData.Length);
            }

            byte[] innerCompressedBytes;
            using (var innerCompressedData = new MemoryStream())
            {
                var endian = this.Endian;

                innerCompressedData.WriteValueS32(0, Endian.Big);
                innerCompressedData.WriteString("WSG");
                innerCompressedData.WriteValueU32(2, endian);
                innerCompressedData.WriteValueU32(CRC32.Hash(innerUncompressedBytes, 0, innerUncompressedBytes.Length),
                                                  endian); // crc32
                innerCompressedData.WriteValueS32(innerUncompressedBytes.Length, endian);

                var encoder = new Huffman.Encoder();
                encoder.Build(innerUncompressedBytes);
                innerCompressedData.WriteBytes(encoder.Encode(innerUncompressedBytes));

                innerCompressedData.Position = 0;
                innerCompressedData.WriteValueU32((uint)(innerCompressedData.Length - 4), Endian.Big);

                innerCompressedData.Position = 0;
                innerCompressedBytes = innerCompressedData.ReadBytes((uint)innerCompressedData.Length);
            }

            byte[] compressedBytes;

            if (innerCompressedBytes.Length <= BlockSize)
            {
                compressedBytes = new byte[innerCompressedBytes.Length +
                                           (innerCompressedBytes.Length / 16) + 64 + 3];
                var actualCompressedSize = compressedBytes.Length;

                var result = LZO.Compress(innerCompressedBytes,
                                          0,
                                          innerCompressedBytes.Length,
                                          compressedBytes,
                                          0,
                                          ref actualCompressedSize);
                if (result != LZO.ErrorCode.Success)
                {
                    throw new SaveCorruptionException(string.Format("LZO compression failure ({0})", result));
                }

                Array.Resize(ref compressedBytes, actualCompressedSize);
            }
            else
            {
                int innerCompressedOffset = 0;
                int innerCompressedSizeLeft = innerCompressedBytes.Length;

                using (var blockData = new MemoryStream())
                {
                    var blockCount = (innerCompressedSizeLeft + BlockSize) / BlockSize;
                    blockData.WriteValueS32(blockCount, Endian.Big);

                    blockData.Position = 4 + (blockCount * 8);

                    var blockInfos = new List<Tuple<uint, uint>>();
                    while (innerCompressedSizeLeft > 0)
                    {
                        var blockUncompressedSize = Math.Min(BlockSize, innerCompressedSizeLeft);

                        compressedBytes = new byte[blockUncompressedSize +
                                                   (blockUncompressedSize / 16) + 64 + 3];
                        var actualCompressedSize = compressedBytes.Length;

                        var result = LZO.Compress(innerCompressedBytes,
                                                  innerCompressedOffset,
                                                  blockUncompressedSize,
                                                  compressedBytes,
                                                  0,
                                                  ref actualCompressedSize);
                        if (result != LZO.ErrorCode.Success)
                        {
                            throw new SaveCorruptionException(string.Format("LZO compression failure ({0})", result));
                        }

                        blockData.Write(compressedBytes, 0, actualCompressedSize);
                        blockInfos.Add(new Tuple<uint, uint>((uint)actualCompressedSize, BlockSize));

                        innerCompressedOffset += blockUncompressedSize;
                        innerCompressedSizeLeft -= blockUncompressedSize;
                    }

                    blockData.Position = 4;
                    foreach (var blockInfo in blockInfos)
                    {
                        blockData.WriteValueU32(blockInfo.Item1, Endian.Big);
                        blockData.WriteValueU32(blockInfo.Item2, Endian.Big);
                    }

                    blockData.Position = 0;
                    compressedBytes = blockData.ReadBytes((uint)blockData.Length);
                }
            }

            byte[] uncompressedBytes;
            using (var uncompressedData = new MemoryStream())
            {
                uncompressedData.WriteValueS32(innerCompressedBytes.Length, Endian.Big);
                uncompressedData.WriteBytes(compressedBytes);
                uncompressedData.Position = 0;
                uncompressedBytes = uncompressedData.ReadBytes((uint)uncompressedData.Length);
            }

            byte[] computedHash;
            using (var sha1 = new System.Security.Cryptography.SHA1Managed())
            {
                computedHash = sha1.ComputeHash(uncompressedBytes);
            }

            output.WriteBytes(computedHash);
            output.WriteBytes(uncompressedBytes);
        }
示例#22
0
        private void ReadExports(MemoryStream fs)
        {
            DebugOutput.PrintLn("Reading Exports...");
            fs.Seek(ExportOffset, SeekOrigin.Begin);
            Exports = new List<ME1ExportEntry>();

            for (int i = 0; i < ExportCount; i++)
            {
                long start = fs.Position;
                ME1ExportEntry exp = new ME1ExportEntry();
                exp.pccRef = this;
                exp.infoOffset = (int)start;

                fs.Seek(40, SeekOrigin.Current);
                int count = fs.ReadValueS32();
                fs.Seek(4 + count * 12, SeekOrigin.Current);
                count = fs.ReadValueS32();
                fs.Seek(4 + count * 4, SeekOrigin.Current);
                fs.Seek(16, SeekOrigin.Current);
                long end = fs.Position;
                fs.Seek(start, SeekOrigin.Begin);
                exp.info = fs.ReadBytes((int)(end - start));
                Exports.Add(exp);
                fs.Seek(end, SeekOrigin.Begin);

                if (LastExport == null || exp.DataOffset > LastExport.DataOffset)
                    LastExport = exp;
            }
        }
示例#23
0
        private STFSPackage(IFile f)
        {
            Stream input = f.GetStream();

            FileName = f.Name;
            disposed = false;

            stream = input;

            // Set the type of STFS file.
            string magic = stream.ReadASCIINullTerminated(4);

            switch (magic)
            {
            case "CON ":
                Type = STFSType.CON;
                break;

            case "LIVE":
                Type = STFSType.LIVE;
                break;

            case "PIRS":
                Type = STFSType.PIRS;
                break;

            default:
                throw new InvalidDataException("STFS is not CON, LIVE, or PIRS");
            }

            BlockCache = new byte[0x1000];

            // Set up STFS info.
            stream.Position = 0x340;
            headerSize      = stream.ReadInt32BE();

            if ((((headerSize + 0xFFF) & 0xF000) >> 0xC) == 0xB)
            {
                tableSizeShift = 0;
            }
            else
            {
                tableSizeShift = 1;
            }

            // Volume Descriptor begins at 0x379
            stream.Position      = 0x37C;
            fileTableBlockCount  = stream.ReadInt16LE();
            fileTableBlockNumber = stream.ReadInt24LE();

            stream.Position = 0x39D;
            fileCount       = stream.ReadInt32LE();

#if !MINIMAL
            // Read both package thumbnails into Image instances
            stream.Position = 0x1712;
            int thumbnailImgSize      = stream.ReadInt32BE();
            int titleThumbnailImgSize = stream.ReadInt32BE();
            stream.Position = 0x171A;
            if (thumbnailImgSize > 0)
            {
                Thumbnail = System.Drawing.Image.FromStream(new System.IO.MemoryStream(stream.ReadBytes(thumbnailImgSize)));
            }
            stream.Position = 0x571A;
            if (titleThumbnailImgSize > 0)
            {
                TitleThumbnail = System.Drawing.Image.FromStream(new System.IO.MemoryStream(stream.ReadBytes(titleThumbnailImgSize)));
            }
#endif

            root = new STFSDirectory(null, ROOT_DIR);
            var dirsOrdinal = new Dictionary <int, STFSDirectory>();
            dirsOrdinal.Add(-1, root);
            int   items           = 0;
            int[] fileTableBlocks = GetFileBlocks(fileTableBlockNumber, fileTableBlockCount, false);
            for (var x = 0; x < fileTableBlocks.Length; x++)
            {
                var  curBlock = fileTableBlocks[x];
                long basePosition;
                CacheBlockAt(BlockToOffset(curBlock));
                using (var curBlockStream = new System.IO.MemoryStream(BlockCache))
                {
                    for (var i = 0; i < 0x40; i++)
                    {
                        basePosition            = 0x40 * i;
                        curBlockStream.Position = basePosition;
                        if (curBlockStream.ReadByte() == 0)
                        {
                            break;
                        }
                        curBlockStream.Position = basePosition + 0x28;
                        byte flags = (byte)curBlockStream.ReadByte();
                        curBlockStream.Position = basePosition;
                        String name;
                        using (var sr = new System.IO.StreamReader(
                                   new System.IO.MemoryStream(curBlockStream.ReadBytes(flags & 0x3f)), Encoding.GetEncoding(1252)))
                        {
                            name = sr.ReadToEnd();
                        }
                        curBlockStream.Position = basePosition + 0x29;
                        int numBlocks = curBlockStream.ReadInt24LE();
                        curBlockStream.ReadInt24LE();
                        int           startBlock = curBlockStream.ReadInt24LE();
                        int           parentDir  = curBlockStream.ReadInt16BE();
                        uint          size       = curBlockStream.ReadUInt32BE();
                        int           update     = curBlockStream.ReadInt32BE();
                        int           access     = curBlockStream.ReadInt32BE();
                        STFSDirectory parent;
                        if (!dirsOrdinal.TryGetValue(parentDir, out parent)) // get the parent if it exists
                        {
                            throw new InvalidDataException("File references non-existent directory.");
                        }

                        if ((flags & 0x80) == 0x80)
                        {
                            // item is a directory
                            var tmp = new STFSDirectory(parent, name);
                            dirsOrdinal.Add(items, tmp);
                            parent.AddDir(tmp);
                        }
                        else
                        {
                            // item is a file
                            STFSFile tmp;
                            if ((flags & 0x40) == 0x40) // blocks are sequential
                            {
                                var dataBlocks = GetFileBlocks(startBlock, numBlocks, (flags & 0x40) == 0x40);
                                tmp = new STFSFile(name, size, dataBlocks, parent, this);
                            }
                            else // offload block calculation until we need it
                            {
                                tmp = new STFSFile(name, size, startBlock, numBlocks, parent, this);
                            }
                            parent.AddFile(tmp);
                        }
                        items++;
                    }
                }
            }
        }
示例#24
0
 private byte[] GetData()
 {
     MemoryStream ms = new MemoryStream(pccRef.listsStream.GetBuffer());
     {
         ms.Seek((long)DataOffset, SeekOrigin.Begin);
         return ms.ReadBytes(DataSize);
     }
 }
示例#25
0
        void PCCObjectHelper(MemoryStream tempStream, string filePath)
        {
            tempStream.Seek(0, SeekOrigin.Begin);
            Names = new List<string>();
            Imports = new List<ImportEntry>();
            Exports = new List<ExportEntry>();

            if (GameVersion != 3)
            {
                // Find ME1 and 2 header...Why so difficult ME1 and 2?
                tempStream.Seek(12, SeekOrigin.Begin);
                int tempNameSize = tempStream.ReadInt32();
                tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin);
                int tempGenerator = tempStream.ReadInt32();
                tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current);
                int tempPos = (int)tempStream.Position + (GameVersion == 2 ? 0 : 4);
                tempStream.Seek(0, SeekOrigin.Begin);
                header = tempStream.ReadBytes(tempPos);
                tempStream.Seek(0, SeekOrigin.Begin);
            }
            else
                header = tempStream.ReadBytes(headerSize);

            if (magic != ZBlock.magic &&
                    magic.Swap() != ZBlock.magic)
                throw new FormatException(filePath + " is not a pcc file");

            if (GameVersion == 3 && lowVers != 684 && highVers != 194)
                throw new FormatException("unsupported version");

            if (compressed)
            {
                if (GameVersion == 3)
                    ReadCompressedME3(tempStream);
                else
                    ReadCompressedME1And2(tempStream);

                compressed = false;
            }
            else
                listsStream = tempStream;

            //Fill name list
            listsStream.Seek(NameOffset, SeekOrigin.Begin);
            for (int i = 0; i < NameCount; i++)
            {
                int strLength = listsStream.ReadInt32();
                string name = null;

                switch (GameVersion)
                {
                    case 1:
                        name = ReadME1Name(strLength);
                        break;
                    case 2:
                        name = ReadME2Name(strLength);
                        break;
                    case 3:
                        name = ReadME3Name(strLength);
                        break;
                }

                Names.Add(name);               
            }

            byte[] buffer = null;

            // fill import list
            listsStream.Seek(ImportOffset, SeekOrigin.Begin);
            buffer = new byte[ImportEntry.byteSize];
            for (int i = 0; i < ImportCount; i++)
                Imports.Add(new ImportEntry(this, listsStream));

            //fill export list
            listsStream.Seek(ExportOffset, SeekOrigin.Begin);
            for (int i = 0; i < ExportCount; i++)
            {
                uint expInfoOffset = (uint)listsStream.Position;

                // Find export data size
                int count = 0;
                int expInfoSize = 0;
                if (GameVersion == 3)
                {
                    listsStream.Seek(44, SeekOrigin.Current);
                    count = listsStream.ReadInt32();
                    expInfoSize = 68 + (count * 4);
                }
                else
                {
                    listsStream.Seek(40, SeekOrigin.Current);
                    count = listsStream.ReadInt32();
                    listsStream.Seek(4 + count * 12, SeekOrigin.Current);
                    count = listsStream.ReadInt32();
                    listsStream.Seek(4 + count * 4, SeekOrigin.Current);
                    listsStream.Seek(16, SeekOrigin.Current);
                    expInfoSize = (int)(listsStream.Position - expInfoOffset);
                }
                
                // Read export data
                buffer = new byte[expInfoSize];
                listsStream.Seek(expInfoOffset, SeekOrigin.Begin);
                listsStream.Read(buffer, 0, buffer.Length);
                Exports.Add(new ExportEntry(this, buffer, expInfoOffset));
            }
        }
示例#26
0
        private void LoadHelper(MemoryStream tempStream)
        {
            tempStream.Seek(12, SeekOrigin.Begin);
            int tempNameSize = tempStream.ReadValueS32();
            tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin);
            int tempGenerator = tempStream.ReadValueS32();
            tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current);
            int tempPos = (int)tempStream.Position + 4;
            tempStream.Seek(0, SeekOrigin.Begin);
            header = tempStream.ReadBytes(tempPos);
            tempStream.Seek(0, SeekOrigin.Begin);

            if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic)
            {
                DebugOutput.PrintLn("Magic number incorrect: " + magic);
                throw new FormatException("This is not a pcc file. The magic number is incorrect.");
            }

            if (bCompressed)
            {
                DebugOutput.PrintLn("File is compressed");
                listsStream = lzo.DecompressPCC(tempStream, this);

                //Correct the header
                bCompressed = false;
                listsStream.Seek(0, SeekOrigin.Begin);
                listsStream.WriteBytes(header);

                // Set numblocks to zero
                listsStream.WriteValueS32(0);
                //Write the magic number
                listsStream.WriteBytes(new byte[] { 0xF2, 0x56, 0x1B, 0x4E });
                // Write 4 bytes of 0
                listsStream.WriteValueS32(0);
            }
            else
            {
                DebugOutput.PrintLn("File already decompressed. Reading decompressed data.");
                //listsStream = tempStream;
                listsStream = new MemoryStream();
                tempStream.WriteTo(listsStream);
            }
            tempStream.Dispose();
            ReadNames(listsStream);
            ReadImports(listsStream);
            ReadExports(listsStream);
            LoadExports();
        }
示例#27
0
        public PCCObject(String path, Boolean littleEndian=true)
        {
            lzo = new SaltLZOHelper();
            fullname = path;
            BitConverter.IsLittleEndian = littleEndian;
            StreamHelpers.setIsLittleEndian(littleEndian);
            DebugOutput.PrintLn("Load file : " + path);
            pccFileName = Path.GetFullPath(path);
            MemoryStream tempStream = new MemoryStream();
            if (!File.Exists(pccFileName))
                throw new FileNotFoundException("PCC file not found");
            using (FileStream fs = new FileStream(pccFileName, FileMode.Open, FileAccess.Read))
            {
                FileInfo tempInfo = new FileInfo(pccFileName);
                tempStream.WriteFromStream(fs, tempInfo.Length);
                if (tempStream.Length != tempInfo.Length)
                {
                    throw new FileLoadException("File not fully read in. Try again later");
                }
            }

            tempStream.Seek(12, SeekOrigin.Begin);
            int tempNameSize = tempStream.ReadValueS32();
            tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin);
            int tempGenerator = tempStream.ReadValueS32();
            tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current);
            int tempPos = (int)tempStream.Position;
            NumChunks = tempStream.ReadValueS32();
            tempStream.Seek(0, SeekOrigin.Begin);
            header = tempStream.ReadBytes(tempPos);
            tempStream.Seek(0, SeekOrigin.Begin);

            if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic)
            {
                DebugOutput.PrintLn("Magic number incorrect: " + magic);
                throw new FormatException("This is not a pcc file. The magic number is incorrect.");
            }

            if (bCompressed)
            {
                DebugOutput.PrintLn("File is compressed");
                {
                    listsStream = lzo.DecompressPCC(tempStream, this);

                    //Correct the header
                    bCompressed = false;
                    listsStream.Seek(0, SeekOrigin.Begin);
                    listsStream.WriteBytes(header);

                    //Set numblocks to zero
                    listsStream.WriteValueS32(0);
                    //Write the magic number
                    listsStream.WriteValueS32(1026281201);
                    //Write 8 bytes of 0
                    listsStream.WriteValueS32(0);
                    listsStream.WriteValueS32(0);
                }
            }
            else
            {
                DebugOutput.PrintLn("File already decompressed. Reading decompressed data.");
                listsStream = tempStream;
            }

            ReadNames(listsStream);
            ReadImports(listsStream);
            ReadExports(listsStream);
            LoadExports();
        }
示例#28
0
 private void ReadImports(MemoryStream fs)
 {
     DebugOutput.PrintLn("Reading Imports...");
     Imports = new List<ME1ImportEntry>();
     fs.Seek(ImportOffset, SeekOrigin.Begin);
     for (int i = 0; i < ImportCount; i++)
     {
         ME1ImportEntry import = new ME1ImportEntry();
         import.Package = Names[fs.ReadValueS32()];
         fs.Seek(12, SeekOrigin.Current);
         import.link = fs.ReadValueS32();
         import.Name = Names[fs.ReadValueS32()];
         fs.Seek(-24, SeekOrigin.Current);
         import.raw = fs.ReadBytes(28);
         Imports.Add(import);
     }
 }
示例#29
0
文件: APNG.cs 项目: mwheeler/APNG.NET
        public APNG(byte[] fileBytes)
        {
            ms = new MemoryStream(fileBytes);

            // check file signature.
            if (!Helper.IsBytesEqual(ms.ReadBytes(Frame.Signature.Length), Frame.Signature))
                throw new Exception("File signature incorrect.");

            // Read IHDR chunk.
            IHDRChunk = new IHDRChunk(ms);
            if (IHDRChunk.ChunkType != "IHDR")
                throw new Exception("IHDR chunk must located before any other chunks.");

            // Now let's loop in chunks
            Chunk chunk;
            Frame frame = null;
            List<ITextChunk> text_chunks = new List<ITextChunk>();
            bool isIDATAlreadyParsed = false;
            do
            {
                if (ms.Position == ms.Length)
                    throw new Exception("IEND chunk expected.");

                chunk = new Chunk(ms);

                switch (chunk.ChunkType)
                {
                    case "IHDR":
                        throw new Exception("Only single IHDR is allowed.");
                        break;

                    case "acTL":
                        if (IsSimplePNG)
                            throw new Exception("acTL chunk must located before any IDAT and fdAT");

                        TextChunks = text_chunks.ToArray();
                        text_chunks.Clear();

                        acTLChunk = new acTLChunk(chunk);
                        break;

                    case "IDAT":
                        // To be an APNG, acTL must located before any IDAT and fdAT.
                        if (acTLChunk == null)
                        {
                            TextChunks = text_chunks.ToArray();
                            text_chunks.Clear();
                            IsSimplePNG = true;
                        }

                        // Only default image has IDAT.
                        defaultImage.IHDRChunk = IHDRChunk;
                        defaultImage.AddIDATChunk(new IDATChunk(chunk));
                        isIDATAlreadyParsed = true;
                        break;

                    case "fcTL":
                        // Simple PNG should ignore this.
                        if (IsSimplePNG)
                            continue;

                        if (frame != null && frame.IDATChunks.Count == 0)
                            throw new Exception("One frame must have only one fcTL chunk.");

                        // IDAT already parsed means this fcTL is used by FRAME IMAGE.
                        if (isIDATAlreadyParsed)
                        {
                            // register current frame object and build a new frame object
                            // for next use
                            if (frame != null)
                            {
                                frame.TextChunks = text_chunks.ToArray();
                                frames.Add(frame);
                                text_chunks.Clear();
                            }

                            frame = new Frame
                                        {
                                            IHDRChunk = IHDRChunk,
                                            fcTLChunk = new fcTLChunk(chunk)
                                        };
                        }
                            // Otherwise this fcTL is used by the DEFAULT IMAGE.
                        else
                        {
                            defaultImage.fcTLChunk = new fcTLChunk(chunk);
                        }
                        break;
                    case "fdAT":
                        // Simple PNG should ignore this.
                        if (IsSimplePNG)
                            continue;

                        // fdAT is only used by frame image.
                        if (frame == null || frame.fcTLChunk == null)
                            throw new Exception("fcTL chunk expected.");

                        frame.AddIDATChunk(new fdATChunk(chunk).ToIDATChunk());
                        break;

                    case "IEND":
                        // register last frame object
                        if (frame != null)
                        {
                            frame.TextChunks = text_chunks.ToArray();
                            frames.Add(frame);
                            text_chunks.Clear();
                        }

                        if (DefaultImage.IDATChunks.Count != 0)
                            DefaultImage.IENDChunk = new IENDChunk(chunk);
                        foreach (Frame f in frames)
                        {
                            f.IENDChunk = new IENDChunk(chunk);
                        }
                        break;

                    case "iTXt":
                        text_chunks.Add(new iTXtChunk(chunk));
                        break;

                    case "tEXt":
                        text_chunks.Add(new tEXtChunk(chunk));
                        break;

                    case "zTXt":
                        text_chunks.Add(new zTXtChunk(chunk));
                        break;

                    default:
                        //TODO: Handle other chunks.
                        break;
                }
            } while (chunk.ChunkType != "IEND");

            // We have one more thing to do:
            // If the default image if part of the animation,
            // we should insert it into frames list.
            if (defaultImage.fcTLChunk != null)
            {
                frames.Insert(0, defaultImage);
                DefaultImageIsAnimeated = true;
            }
        }
示例#30
0
        /// <summary>
        /// Takes compressed archived image data and returns the raw image data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] DecompressTex(Stream archiveStream, int offset, int uncSize, int cprSize)
        {
            int pos = 0;
            archiveStream.Seek(offset, SeekOrigin.Begin);
            int magicNumber = archiveStream.ReadValueS32();
            pos += 4;
            if (magicNumber != -1641380927)
            {
                throw new FormatException("Magic Number is not correct. Invalid archive data");
            }
            int blockSize = archiveStream.ReadValueS32();
            pos += 4;
            int readCprSize = archiveStream.ReadValueS32(); //Archive cprSize doesn't include header size
            pos += 4;
            int uncReadSize = archiveStream.ReadValueS32();
            if (uncReadSize != uncSize)
            {
                throw new FormatException("Uncompressed data sizes don't match. Read: " + uncReadSize + ", expected: " + uncSize);
            }
            pos += 4;
            int noChunks = (uncSize + blockSize - 1) / blockSize;

            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = new CompressedChunkBlock();
                chunk.cprSize = archiveStream.ReadValueS32();
                chunk.uncSize = archiveStream.ReadValueS32();
                chunk.rawData = new byte[chunk.cprSize];
                pos += 8;
                chunks[i] = chunk;
            }
            if (readCprSize + pos != cprSize)
            {
                throw new FormatException("Compressed data sizes don't match. Invalid archive data");
            }
            byte[] rawData = new byte[readCprSize];
            rawData = archiveStream.ReadBytes(readCprSize);
            archiveStream.Close();
            using (MemoryStream data = new MemoryStream(rawData))
            {
                for (int i = 0; i < noChunks; i++)
                {
                    chunks[i].rawData = data.ReadBytes(chunks[i].cprSize);
                }
            }

            byte[] imgBuffer = new byte[uncSize];
            int resultPos = 0;

            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = chunks[i];
                byte[] tempResult = new byte[chunk.uncSize];
                try
                {
                    LZO1X.Decompress(chunk.rawData, tempResult);
                }
                catch
                {
                    throw new Exception("LZO decompression failed!");
                }
                Buffer.BlockCopy(tempResult, 0, imgBuffer, resultPos, chunk.uncSize);
                resultPos += chunk.uncSize;
            }

            return imgBuffer;
        }
        private static void Main(string[] args)
        {
            var paths = Directory.GetFiles("saves", "*.sav");

            var successes = 0;
            var failures = 0;

            foreach (var path in paths)
            {
                var name = Path.GetFileNameWithoutExtension(path);

                using (var input = File.OpenRead(path))
                {
                    var readHash = input.ReadBytes(20);
                    using (var data = input.ReadToMemoryStream(input.Length - 20))
                    {
                        byte[] computedHash;
                        using (var sha1 = new System.Security.Cryptography.SHA1Managed())
                        {
                            computedHash = sha1.ComputeHash(data);
                        }

                        if (readHash.SequenceEqual(computedHash) == false)
                        {
                            Console.WriteLine("{0}: failed (SHA1 mismatch)", name);
                            failures++;
                            continue;
                        }

                        data.Position = 0;
                        var uncompressedSize = data.ReadValueU32(Endian.Big);
                        var actualUncompressedSize = (int)uncompressedSize;
                        var uncompressedBytes = new byte[uncompressedSize];
                        var compressedSize = (int)(data.Length - 4);
                        var compressedBytes = data.ReadBytes(compressedSize);
                        var result = LZO.Decompress(compressedBytes,
                                                    0,
                                                    compressedSize,
                                                    uncompressedBytes,
                                                    0,
                                                    ref actualUncompressedSize);
                        if (result != LZO.ErrorCode.Success)
                        {
                            Console.WriteLine("{0}: failed (LZO error {1})", name, result);
                            failures++;
                            continue;
                        }

                        using (var outerData = new MemoryStream(uncompressedBytes))
                        {
                            var innerSize = outerData.ReadValueU32(Endian.Big);
                            var magic = outerData.ReadString(3);
                            if (magic != "WSG")
                            {
                                Console.WriteLine("{0}: failed (bad magic)", name);
                                failures++;
                                continue;
                            }

                            var version = outerData.ReadValueU32(Endian.Little);
                            if (version != 2 &&
                                version.Swap() != 2)
                            {
                                Console.WriteLine("{0}: failed (bad version)", name);
                                failures++;
                                continue;
                            }

                            var endian = version == 2 ? Endian.Little : Endian.Big;

                            var hash = outerData.ReadValueU32(endian);
                            var innerUncompressedSize = outerData.ReadValueS32(endian);

                            var innerCompressedBytes = outerData.ReadBytes(innerSize - 3 - 4 - 4 - 4);
                            var innerUncompressedBytes = Huffman.Decoder.Decode(innerCompressedBytes,
                                                                                innerUncompressedSize);
                            using (var innerUncompressedData = new MemoryStream(innerUncompressedBytes))
                            {
                                using (var output = File.Create("temp.bin"))
                                {
                                    output.WriteBytes(innerUncompressedBytes);
                                }

                                var save =
                                    Serializer.Deserialize<WillowTwoSave.WillowTwoPlayerSaveGame>(innerUncompressedData);

                                using (var testData = new MemoryStream())
                                {
                                    Serializer.Serialize(testData, save);

                                    testData.Position = 0;
                                    var testBytes = testData.ReadBytes((uint)testData.Length);
                                    if (innerUncompressedBytes.SequenceEqual(testBytes) == false)
                                    {
                                        Console.WriteLine("{0}: failed (reencode mismatch)", name);

                                        using (var output = File.Create(Path.Combine("failures", name + "_before.bin")))
                                        {
                                            output.WriteBytes(innerUncompressedBytes);
                                        }

                                        using (var output = File.Create(Path.Combine("failures", name + "_after.bin")))
                                        {
                                            output.WriteBytes(testBytes);
                                        }

                                        failures++;
                                        continue;
                                    }

                                    successes++;
                                }
                            }
                        }
                    }
                }
            }

            Console.WriteLine("{0} processed ({1} failed, {2} succeeded).",
                              paths.Length,
                              failures,
                              successes);
        }