Example #1
0
        public void Export(BasePakEntry uasset, BasePakEntry uexp, BasePakEntry ubulk)
        {
            if (uasset == null || uexp == null)
            {
                return;
            }
            var assetStream = new FPakFile(Reader, uasset, Aes).GetStream();
            var expStream   = new FPakFile(Reader, uexp, Aes).GetStream();
            var bulkStream  = ubulk == null ? null : new FPakFile(Reader, ubulk, Aes).GetStream();

            try
            {
                var exports = new AssetReader(assetStream, expStream, bulkStream).Exports;
                if (exports[0] is Texture2D)
                {
                    var tex = exports[0] as Texture2D;
                    tex.GetImage();
                }
            }
            catch (IndexOutOfRangeException) { }
            catch (NotImplementedException) { }
            catch (IOException) { }
            catch (Exception e)
            {
                DebugHelper.WriteException(e, "thrown in PakReader.cs by Export");
            }
        }
Example #2
0
 public Stream GetPackageStream(BasePakEntry entry)
 {
     lock (Reader)
     {
         return(new FPakFile(Reader, entry, Aes).GetStream());
     }
 }
Example #3
0
        const int     EncryptedBufferSize = 256; //?? TODO: check - may be value 16 will be better for performance

        public FPakFile(BinaryReader Reader, BasePakEntry Info, byte[] key = null)
        {
            Reader.BaseStream.Seek(Info.Pos + Info.StructSize, SeekOrigin.Begin);
            if (Info.Encrypted)
            {
                long   encSize   = (Info.Size & 15) == 0 ? Info.Size : ((Info.Size / 16) + 1) * 16;
                byte[] encBuffer = Reader.ReadBytes((int)encSize);
                data = AESDecryptor.DecryptAES(encBuffer, (int)encSize, key, key.Length).SubArray(0, (int)Info.UncompressedSize);
                if (encSize != Info.Size)
                {
                    data = data.SubArray(0, (int)Info.UncompressedSize);
                }
            }
            else
            {
                data = Reader.ReadBytes((int)Info.UncompressedSize);
            }
            //File.WriteAllBytes(Path.GetFileName(info.Name), data);

            /*
             * if (info.CompressionMethod != 0)
             * {
             *  Console.WriteLine("compressed");
             *  while (size > 0)
             *  {
             *      if ((UncompressedBuffer == null) || (ArPos < UncompressedBufferPos) || (ArPos >= UncompressedBufferPos + Info.CompressionBlockSize))
             *      {
             *          // buffer is not ready
             *          if (UncompressedBuffer == null)
             *          {
             *              UncompressedBuffer = new byte[Info.CompressionBlockSize];
             *          }
             *          // prepare buffer
             *          int BlockIndex = ArPos / Info.CompressionBlockSize;
             *          UncompressedBufferPos = Info.CompressionBlockSize * BlockIndex;
             *
             *          FPakCompressedBlock Block = Info.CompressionBlocks[BlockIndex];
             *          int CompressedBlockSize = (int)(Block.CompressedEnd - Block.CompressedStart);
             *          int UncompressedBlockSize = Math.Min(Info.CompressionBlockSize, (int)Info.UncompressedSize - UncompressedBufferPos); // don't pass file end
             *
             *          byte[] CompressedData;
             *          if (Info.bEncrypted == 0)
             *          {
             *              Reader.BaseStream.Seek(Block.CompressedStart, SeekOrigin.Begin);
             *              CompressedData = Reader.ReadBytes(CompressedBlockSize);
             *          }
             *          else
             *          {
             *              int EncryptedSize = Align(CompressedBlockSize, EncryptionAlign);
             *              Reader.BaseStream.Seek(Block.CompressedStart, SeekOrigin.Begin);
             *              CompressedData = Reader.ReadBytes(EncryptedSize);
             *              CompressedData = AESDecryptor.DecryptAES(CompressedData, EncryptedSize, key, key.Length);
             *          }
             *          // appDecompress(CompressedData, CompressedBlockSize, UncompressedBuffer, UncompressedBlockSize, Info.CompressionMethod);
             *          // https://github.com/gildor2/UModel/blob/39641f9e58cb4c286dde5f191e5db9a24b19f503/Unreal/UnCoreCompression.cpp#L183
             *          throw new NotImplementedException("Decompressing of files aren't written yet");
             *      }
             *
             *      // data is in buffer, copy it
             *      int BytesToCopy = UncompressedBufferPos + Info.CompressionBlockSize - ArPos; // number of bytes until end of the buffer
             *      if (BytesToCopy > size) BytesToCopy = size;
             *      if (BytesToCopy <= 0)
             *      {
             *          throw new ArgumentOutOfRangeException("Bytes to copy is invalid");
             *      }
             *
             *      // copy uncompressed data
             *      int OffsetInBuffer = ArPos - UncompressedBufferPos;
             *      Buffer.BlockCopy(UncompressedBuffer, OffsetInBuffer, data, dataOffset, BytesToCopy);
             *
             *      // advance pointers
             *
             *      // ArPos += BytesToCopy;
             *      size -= BytesToCopy;
             *      dataOffset += BytesToCopy;
             *  }
             *  throw new NotImplementedException("Decompressing of files aren't written yet");
             * }
             * else if (Info.bEncrypted != 0)
             * {
             *  Console.WriteLine("Encrypted");
             *  // Uncompressed encrypted data. Reuse compression fields to handle decryption efficiently
             *  if (UncompressedBuffer == null)
             *  {
             *      UncompressedBuffer = new byte[EncryptedBufferSize];
             *      UncompressedBufferPos = 0x40000000; // some invalid value
             *  }
             *
             *  while (size > 0)
             *  {
             *      if ((ArPos < UncompressedBufferPos) || (ArPos >= UncompressedBufferPos + EncryptedBufferSize))
             *      {
             *          // Should fetch block and decrypt it.
             *          // Note: AES is block encryption, so we should always align read requests for correct decryption.
             *          UncompressedBufferPos = ArPos & ~(EncryptionAlign - 1);
             *          Reader.BaseStream.Seek(Info.Pos + Info.StructSize + UncompressedBufferPos, SeekOrigin.Begin);
             *          int RemainingSize = (int)Info.Size;
             *          if (RemainingSize >= 0)
             *          {
             *              if (RemainingSize > EncryptedBufferSize)
             *                  RemainingSize = EncryptedBufferSize;
             *              RemainingSize = Align(RemainingSize, EncryptionAlign); // align for AES, pak contains aligned data
             *              UncompressedBuffer = Reader.ReadBytes(RemainingSize);
             *              UncompressedBuffer = AESDecryptor.DecryptAES(UncompressedBuffer, RemainingSize, key, key.Length);
             *          }
             *      }
             *
             *      // Now copy decrypted data from UncompressedBuffer (code is very similar to those used in decompression above)
             *      int BytesToCopy = UncompressedBufferPos + EncryptedBufferSize - ArPos; // number of bytes until end of the buffer
             *      if (BytesToCopy > size) BytesToCopy = size;
             *      if (BytesToCopy <= 0)
             *      {
             *          throw new ArgumentOutOfRangeException("Bytes to copy is invalid");
             *      }
             *
             *      // copy uncompressed data
             *      int OffsetInBuffer = ArPos - UncompressedBufferPos;
             *      Buffer.BlockCopy(UncompressedBuffer, OffsetInBuffer, data, dataOffset, BytesToCopy);
             *
             *      // advance pointers
             *
             *      // ArPos += BytesToCopy;
             *      size -= BytesToCopy;
             *      dataOffset += BytesToCopy;
             *  }
             *  throw new NotImplementedException("Decryption of files aren't written yet");
             * }
             * else
             * {
             *  // Pure data
             *  // seek every time in a case if the same 'Reader' was used by different FPakFile
             *  // (this is a lightweight operation for buffered FArchive)
             *  Reader.BaseStream.Seek(Info.Pos + Info.StructSize, SeekOrigin.Begin);
             *  data = Reader.ReadBytes(size);
             *  // ArPos += size;
             * }*/
        }