示例#1
0
 /// <summary>
 /// Encode a psb byte array manually
 /// </summary>
 /// <param name="key"></param>
 /// <param name="inputBytes"></param>
 /// <param name="mode"></param>
 /// <param name="position"></param>
 /// <returns></returns>
 public static byte[] EncodeToBytes(uint key, byte[] inputBytes, EncodeMode mode = EncodeMode.Encrypt,
                                    EncodePosition position = EncodePosition.Auto)
 {
     using (var input = new MemoryStream(inputBytes))
     {
         using (var output = new MemoryStream((int)input.Length))
         {
             Encode(key, mode, position, input, output);
             return(output.ToArray());
         }
     }
 }
示例#2
0
 /// <summary>
 /// Encrypt or decrypt PSB and write to a file
 /// </summary>
 /// <param name="key"></param>
 /// <param name="savePath"></param>
 /// <param name="mode"></param>
 /// <param name="position"></param>
 public void EncodeToFile(uint key, string savePath, EncodeMode mode = EncodeMode.Encrypt,
                          EncodePosition position = EncodePosition.Auto)
 {
     using (var input = File.OpenRead(Path))
     {
         using (var output = File.Open(savePath, FileMode.Create, FileAccess.ReadWrite))
         {
             var header = Encode(key, mode, position, input, output);
             if (header != null)
             {
                 Header = header;
             }
         }
     }
 }
示例#3
0
        /// <summary>
        /// Encode (Encrypt/Decrypt) PSB file
        /// </summary>
        /// <param name="key"></param>
        /// <param name="mode"></param>
        /// <param name="position"></param>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <returns>Unencrypted Header for reference. Usually you shouldn't use it.</returns>
        public static PsbHeader Encode(uint key, EncodeMode mode, EncodePosition position, Stream input, Stream output)
        {
            input.Seek(0, SeekOrigin.Begin);
            output.Seek(0, SeekOrigin.Begin);
            PsbHeader        header  = new PsbHeader();
            PsbStreamContext context = new PsbStreamContext(key);
            BinaryReader     br      = new BinaryReader(input);
            BinaryWriter     bw      = new BinaryWriter(output);

            header.Signature = br.ReadChars(4);
            header.Version   = br.ReadUInt16();
            bw.Write(header.Signature);             //Signature
            bw.Write(header.Version);               //Version
            header.HeaderEncrypt = br.ReadUInt16(); //headerEncrypt, sometimes we don't believe it when encoding
            header.HeaderLength  = br.ReadUInt32();
            header.OffsetNames   = br.ReadUInt32();
            br.BaseStream.Seek(-8, SeekOrigin.Current);

            void WriteOriginal()
            {
                bw.Write(header.HeaderEncrypt);
                WriteOriginalPartialHeader(br, bw, header);
                WriteOriginalBody(br, bw);
            }

            switch (position)
            {
            case EncodePosition.Auto:
                bool headerEnc = TestHeaderEncrypted(br.BaseStream, header);
                bool bodyEnc   = TestBodyEncrypted(br, header);
                if (headerEnc && bodyEnc)     //MARK: is this possible?
                {
                    mode = EncodeMode.Decrypt;
                }

                if (!headerEnc && !bodyEnc)
                {
                    mode = EncodeMode.Encrypt;
                }

                switch (mode)
                {
                case EncodeMode.Encrypt:
                    if (header.Version > 2)         //Header Encrypted; Body Clean
                    {
                        bw.Write((ushort)1);
                        if (headerEnc)
                        {
                            WriteOriginalPartialHeader(br, bw, header);
                            WriteOriginalBody(br, bw);
                            break;
                        }

                        WriteEncryptPartialHeader(br, bw, context, header);
                        WriteOriginalBody(br, bw);
                        break;
                    }
                    else                     //Header Clean; Body Encrpyted
                    {
                        bw.Write((ushort)0); //
                        if (headerEnc)
                        {
                            WriteDecryptPartialHeader(br, bw, context, header);
                            context = new PsbStreamContext(key);
                            WriteEncodeBody(br, bw, context, header);
                        }
                        else
                        {
                            WriteOriginalPartialHeader(br, bw, header);
                            WriteEncodeBody(br, bw, context, header);
                        }
                    }

                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)0);          //
                    if (headerEnc)
                    {
                        WriteDecryptPartialHeader(br, bw, context, header);
                    }
                    else
                    {
                        WriteOriginalPartialHeader(br, bw, header);
                    }

                    if (bodyEnc)
                    {
                        WriteEncodeBody(br, bw, context, header);
                    }
                    else
                    {
                        WriteOriginalBody(br, bw);
                    }

                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Body:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                case EncodeMode.Decrypt:
                    bw.Write(header.HeaderEncrypt);
                    //We believe file is clean so write original header but encrypt body
                    WriteOriginalPartialHeader(br, bw, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Header:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                    bw.Write((ushort)1);
                    WriteEncryptPartialHeader(br, bw, context, header);
                    WriteOriginalBody(br, bw);
                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)0);          //
                    WriteDecryptPartialHeader(br, bw, context, header);
                    WriteOriginalBody(br, bw);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Full:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                    bw.Write((ushort)1);
                    WriteEncryptPartialHeader(br, bw, context, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)1);          //
                    WriteDecryptPartialHeader(br, bw, context, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            default:
                WriteOriginal();
                break;
            }

            bw.Flush();
            output.Seek(0, SeekOrigin.Begin);
            return(header);
        }