예제 #1
0
 public FObjectExport(FPackageFileSummary InSum)
 {
     Sum = InSum;
 }
예제 #2
0
        private static void ProcessFile(string Path, string OutPath)
        {
            using (var Input = File.OpenRead(Path))
            {
                using (var Reader = new BinaryReader(Input))
                {
                    var Sum = new FPackageFileSummary();
                    Sum.Deserialize(Reader);

                    if ((Sum.CompressionFlags & ECompressionFlags.COMPRESS_ZLIB) == 0)
                    {
                        throw new Exception("Unsupported CompressionFlags");
                    }

                    // Decrypt the rest of the package header
                    var EncryptedSize = Sum.TotalHeaderSize - Sum.GarbageSize - Sum.NameOffset;
                    EncryptedSize = (EncryptedSize + 15) & ~15;                     // Round up to the next block

                    var EncryptedData = new byte[EncryptedSize];

                    Input.Seek(Sum.NameOffset, SeekOrigin.Begin);
                    Input.Read(EncryptedData, 0, EncryptedData.Length);

                    var DecryptedData = Decrypt(EncryptedData);

                    var ChunkInfo = new TArray <FCompressedChunkInfo>(() => new FCompressedChunkInfo(Sum));

                    using (var DecryptedStream = new MemoryStream(DecryptedData))
                    {
                        using (var DecryptedReader = new BinaryReader(DecryptedStream))
                        {
                            // Get the compressed chunk info from inside the encrypted data
                            DecryptedStream.Seek(Sum.CompressedChunkInfoOffset, SeekOrigin.Begin);
                            ChunkInfo.Deserialize(DecryptedReader);

                            // Store exports for reserialization
                            DecryptedStream.Seek(Sum.ExportOffset - Sum.NameOffset, SeekOrigin.Begin);
                        }
                    }

                    // Copy the original file data
                    var FileBuf = new byte[Input.Length];
                    Input.Seek(0, SeekOrigin.Begin);
                    Input.Read(FileBuf, 0, FileBuf.Length);

                    // Save to output file
                    using (var Output = File.Open(OutPath, FileMode.Create))
                    {
                        Output.Write(FileBuf, 0, FileBuf.Length);

                        // Write decrypted data
                        Output.Seek(Sum.NameOffset, SeekOrigin.Begin);
                        Output.Write(DecryptedData, 0, DecryptedData.Length);

                        // Decompress compressed chunks
                        foreach (var Chunk in ChunkInfo)
                        {
                            Input.Seek(Chunk.CompressedOffset, SeekOrigin.Begin);
                            var Header = new FCompressedChunkHeader();
                            Header.Deserialize(Reader);

                            var TotalBlockSize = 0;
                            var Blocks         = new List <FCompressedChunkBlock>();

                            while (TotalBlockSize < Header.Sum.UncompressedSize)
                            {
                                var Block = new FCompressedChunkBlock();
                                Block.Deserialize(Reader);
                                Blocks.Add(Block);
                                TotalBlockSize += Block.UncompressedSize;
                            }

                            Output.Seek(Chunk.UncompressedOffset, SeekOrigin.Begin);

                            foreach (var Block in Blocks)
                            {
                                var CompressedData = new byte[Block.CompressedSize];
                                Input.Read(CompressedData, 0, CompressedData.Length);

                                // Zlib inflate
                                var ZlibStream = new InflaterInputStream(new MemoryStream(CompressedData));
                                ZlibStream.CopyTo(Output);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
 public FCompressedChunkInfo(FPackageFileSummary InSum)
 {
     Sum = InSum;
 }