Exemplo n.º 1
0
        /// <summary>
        /// Assume header is clean
        /// </summary>
        /// <param name="br"></param>
        /// <param name="bw"></param>
        /// <param name="context"></param>
        private static void WriteEncryptPartialHeader(BinaryReader br, BinaryWriter bw, PsbStreamContext context, PsbHeader header)
        {
            var checksumStartPosition = br.BaseStream.Position;

            header.HeaderLength = br.ReadUInt32();
            header.OffsetNames  = br.ReadUInt32();
            if (header.HeaderLength == 0)
            {
                header.HeaderLength = header.OffsetNames;
            }
            header.OffsetStrings      = br.ReadUInt32();
            header.OffsetStringsData  = br.ReadUInt32();
            header.OffsetChunkOffsets = br.ReadUInt32();
            header.OffsetChunkLengths = br.ReadUInt32();
            header.OffsetChunkData    = br.ReadUInt32();
            header.OffsetEntries      = br.ReadUInt32();
            if (header.Version > 2)
            {
                header.Checksum = br.ReadUInt32();
            }
            if (header.Version > 3)
            {
                header.OffsetUnknown1        = br.ReadUInt32();
                header.OffsetUnknown2        = br.ReadUInt32();
                header.OffsetResourceOffsets = br.ReadUInt32();
            }
            var checksumEndPosition = br.BaseStream.Position;

            context.Write(header.HeaderLength, bw);
            context.Write(header.OffsetNames, bw);
            context.Write(header.OffsetStrings, bw);
            context.Write(header.OffsetStringsData, bw);
            context.Write(header.OffsetChunkOffsets, bw);
            context.Write(header.OffsetChunkLengths, bw);
            context.Write(header.OffsetChunkData, bw);
            context.Write(header.OffsetEntries, bw);

            if (header.Version > 2)
            {
                int checkLength = 32;
                br.BaseStream.Seek(checksumStartPosition, SeekOrigin.Begin);
                var checkBuffer = new byte[checkLength];
                br.BaseStream.Read(checkBuffer, 0, checkLength);
                br.BaseStream.Seek(checksumEndPosition, SeekOrigin.Begin); //Jump back
                Adler32 adler32 = new Adler32();
                adler32.Update(checkBuffer);
                header.Checksum = (uint)adler32.Checksum;
                if (header.Version == 3)
                {
                    context.Write(header.Checksum, bw);
                }
                else //PSBv4
                {
                    checkBuffer = BitConverter.GetBytes(header.OffsetUnknown1)
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknown2))
                                  .Concat(BitConverter.GetBytes(header.OffsetResourceOffsets)).ToArray();
                    adler32.Update(checkBuffer);
                    header.Checksum = (uint)adler32.Checksum;
                    context.Write(header.Checksum, bw);
                    context.Write(header.OffsetUnknown1, bw);
                    context.Write(header.OffsetUnknown2, bw);
                    context.Write(header.OffsetResourceOffsets, bw);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Assume header is encrypted
        /// </summary>
        /// <param name="br"></param>
        /// <param name="bw"></param>
        /// <param name="context"></param>
        /// <param name="header"></param>
        private static void WriteDecryptPartialHeader(BinaryReader br, BinaryWriter bw, PsbStreamContext context,
                                                      PsbHeader header)
        {
            header.HeaderLength       = context.ReadUInt32(br);
            header.OffsetNames        = context.ReadUInt32(br);
            header.OffsetStrings      = context.ReadUInt32(br);
            header.OffsetStringsData  = context.ReadUInt32(br);
            header.OffsetChunkOffsets = context.ReadUInt32(br);
            header.OffsetChunkLengths = context.ReadUInt32(br);
            header.OffsetChunkData    = context.ReadUInt32(br);
            header.OffsetEntries      = context.ReadUInt32(br);
            if (header.Version > 2)
            {
                header.Checksum = context.ReadUInt32(br);
            }

            if (header.Version > 3)
            {
                header.OffsetUnknownOffsets = context.ReadUInt32(br);
                header.OffsetUnknownLengths = context.ReadUInt32(br);
                header.OffsetUnknownData    = context.ReadUInt32(br);
            }

            //var checksumStartPosition = bw.BaseStream.Position;
            bw.Write(header.HeaderLength);
            bw.Write(header.OffsetNames);
            bw.Write(header.OffsetStrings);
            bw.Write(header.OffsetStringsData);
            bw.Write(header.OffsetChunkOffsets);
            bw.Write(header.OffsetChunkLengths);
            bw.Write(header.OffsetChunkData);
            bw.Write(header.OffsetEntries);
            //var checksumPosition = bw.BaseStream.Position;

            if (header.Version > 2)
            {
                int checkLength = 32;
                bw.BaseStream.Seek(-checkLength, SeekOrigin.Current);
                var checkBuffer = new byte[checkLength];
                bw.BaseStream.Read(checkBuffer, 0, checkLength);
                Adler32 adler32 = new Adler32();
                adler32.Update(checkBuffer);
                header.Checksum = (uint)adler32.Checksum;
                if (header.Version == 3)
                {
                    bw.Write(header.Checksum);
                }
                else //PSBv4
                {
                    checkBuffer = BitConverter.GetBytes(header.OffsetUnknownOffsets)
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknownLengths))
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknownData)).ToArray();
                    adler32.Update(checkBuffer);
                    header.Checksum = (uint)adler32.Checksum;
                    bw.Write(header.Checksum);
                    bw.Write(header.OffsetUnknownOffsets);
                    bw.Write(header.OffsetUnknownLengths);
                    bw.Write(header.OffsetUnknownData);
                }
            }
        }