CSPspEmu.Hle.Formats.EncryptedPrx.DecryptPRX1 C# (CSharp) Method

DecryptPRX1() protected method

protected DecryptPRX1 ( byte _pbIn, bool ShowInfo = false ) : byte[]
_pbIn byte
ShowInfo bool
return byte[]
        protected byte[] DecryptPRX1(byte[] _pbIn, bool ShowInfo = false)
        {
            int cbTotal = (int)_pbIn.Length;
            var _pbOut = new byte[cbTotal];
            _pbIn.CopyTo(_pbOut, 0);

            fixed (byte* pbIn = _pbIn)
            fixed (byte* pbOut = _pbOut)
            {
                var HeaderPointer = (HeaderStruct*)pbIn;
                this.Header = *(HeaderStruct*)pbIn;
                var pti = GetTagInfo(this.Header.Tag);

                if (ShowInfo)
                {
                    Console.WriteLine("TAG_INFO: {0}", pti);
                }

                // build conversion into pbOut
                PointerUtils.Memcpy(pbOut, pbIn, _pbIn.Length);
                PointerUtils.Memset(pbOut, 0, 0x150);
                PointerUtils.Memset(pbOut, 0x55, 0x40);

                // step3 demangle in place
                var h7_header = (Kirk.KIRK_AES128CBC_HEADER*)&pbOut[0x2C];
                h7_header->Mode = Core.Crypto.Kirk.KirkMode.DecryptCbc;
                h7_header->Unknown4 = 0;
                h7_header->Unknown8 = 0;
                h7_header->KeySeed = pti.code; // initial seed for PRX
                h7_header->Datasize = 0x70; // size

                // redo part of the SIG check (step2)
                var _buffer1 = new byte[0x150];
                fixed (byte* buffer1 = _buffer1)
                {
                    PointerUtils.Memcpy(buffer1 + 0x00, pbIn + 0xD0, 0x80);
                    PointerUtils.Memcpy(buffer1 + 0x80, pbIn + 0x80, 0x50);
                    PointerUtils.Memcpy(buffer1 + 0xD0, pbIn + 0x00, 0x80);

                    if (pti.codeExtra != 0)
                    {
                        ExtraV2Mangle(buffer1 + 0x10, pti.codeExtra);
                    }

                    PointerUtils.Memcpy(pbOut + 0x40 /* 0x2C+20 */, buffer1 + 0x40, 0x40);
                }

                for (int iXOR = 0; iXOR < 0x70; iXOR++)
                {
                    pbOut[0x40 + iXOR] = (byte)(pbOut[0x40 + iXOR] ^ pti.key[0x14 + iXOR]);
                }

                var ret = Kirk.hleUtilsBufferCopyWithRange(
                    pbOut + 0x2C,
                    20 + 0x70,
                    pbOut + 0x2C,
                    20 + 0x70,
                    Kirk.CommandEnum.PSP_KIRK_CMD_DECRYPT
                );

                if (ret != 0)
                {
                    throw (new Exception(CStringFormater.Sprintf("mangle#7 returned 0x%08X, ", ret)));
                }

                for (int iXOR = 0x6F; iXOR >= 0; iXOR--)
                {
                    pbOut[0x40 + iXOR] = (byte)(pbOut[0x2C + iXOR] ^ pti.key[0x20 + iXOR]);
                }

                PointerUtils.Memset(pbOut + 0x80, 0, 0x30); // $40 bytes kept, clean up

                pbOut[0xA0] = 1;
                // copy unscrambled parts from header
                PointerUtils.Memcpy(pbOut + 0xB0, pbIn + 0xB0, 0x20); // file size + lots of zeros
                PointerUtils.Memcpy(pbOut + 0xD0, pbIn + 0x00, 0x80); // ~PSP header

                // step4: do the actual decryption of code block
                //  point 0x40 bytes into the buffer to key info
                ret = Kirk.hleUtilsBufferCopyWithRange(
                    pbOut,
                    cbTotal,
                    pbOut + 0x40,
                    cbTotal - 0x40,
                    Kirk.CommandEnum.PSP_KIRK_CMD_DECRYPT_PRIVATE
                );

                if (ret != 0)
                {
                    throw (new Exception(CStringFormater.Sprintf("mangle#1 returned 0x%08X", ret)));
                }

                //File.WriteAllBytes("../../../TestInput/temp.bin", _pbOut);

                var OutputSize = *(int*)&pbIn[0xB0];

                return _pbOut.Slice(0, OutputSize).ToArray();
            }
        }