protected byte[] DecryptPRX2(byte[] _pbIn, bool ShowInfo = false)
{
int size = (int)_pbIn.Length;
var _pbOut = new byte[size];
_pbIn.CopyTo(_pbOut, 0);
var _tmp1 = new byte[0x150];
var _tmp2 = new byte[0x90 + 0x14];
var _tmp3 = new byte[0x60 + 0x14];
fixed (byte* inbuf = _pbIn)
fixed (byte* outbuf = _pbOut)
fixed (byte* tmp1 = _tmp1)
fixed (byte* tmp2 = _tmp2)
fixed (byte* tmp3 = _tmp3)
{
var HeaderPointer = (HeaderStruct*)inbuf;
this.Header = *(HeaderStruct*)inbuf;
var pti = GetTagInfo2(this.Header.Tag);
Console.WriteLine("{0}", pti);
int retsize = *(int *)&inbuf[0xB0];
PointerUtils.Memset(_tmp1, 0, 0x150);
PointerUtils.Memset(_tmp2, 0, 0x90 + 0x14);
PointerUtils.Memset(_tmp3, 0, 0x60 + 0x14);
PointerUtils.Memcpy(outbuf, inbuf, size);
if (size < 0x160)
{
throw (new InvalidDataException("buffer not big enough, "));
}
if ((size - 0x150) < retsize)
{
throw (new InvalidDataException("not enough data, "));
}
PointerUtils.Memcpy(tmp1, outbuf, 0x150);
int i, j;
//byte *p = tmp2+0x14;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 0x10; j++)
{
_tmp2[0x14 + (i << 4) + j] = pti.key[j];
}
_tmp2[0x14 + (i << 4)] = (byte)i;
}
if (Scramble((uint *)tmp2, 0x90, pti.code) < 0)
{
throw (new InvalidDataException("error in Scramble#1, "));
}
PointerUtils.Memcpy(outbuf, tmp1 + 0xD0, 0x5C);
PointerUtils.Memcpy(outbuf + 0x5C, tmp1 + 0x140, 0x10);
PointerUtils.Memcpy(outbuf + 0x6C, tmp1 + 0x12C, 0x14);
PointerUtils.Memcpy(outbuf + 0x80, tmp1 + 0x080, 0x30);
PointerUtils.Memcpy(outbuf + 0xB0, tmp1 + 0x0C0, 0x10);
PointerUtils.Memcpy(outbuf + 0xC0, tmp1 + 0x0B0, 0x10);
PointerUtils.Memcpy(outbuf + 0xD0, tmp1 + 0x000, 0x80);
PointerUtils.Memcpy(tmp3 + 0x14, outbuf + 0x5C, 0x60);
if (Scramble((uint *)tmp3, 0x60, pti.code) < 0)
{
throw (new InvalidDataException("error in Scramble#2, "));
}
PointerUtils.Memcpy(outbuf + 0x5C, tmp3, 0x60);
PointerUtils.Memcpy(tmp3, outbuf + 0x6C, 0x14);
PointerUtils.Memcpy(outbuf + 0x70, outbuf + 0x5C, 0x10);
PointerUtils.Memset(outbuf + 0x18, 0, 0x58);
PointerUtils.Memcpy(outbuf + 0x04, outbuf, 0x04);
*((uint *)outbuf) = 0x014C;
PointerUtils.Memcpy(outbuf + 0x08, tmp2, 0x10);
/* sha-1 */
if (Kirk.hleUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, Core.Crypto.Kirk.CommandEnum.PSP_KIRK_CMD_SHA1_HASH) != Core.Crypto.Kirk.ResultEnum.OK)
{
throw (new InvalidDataException("error in sceUtilsBufferCopyWithRange 0xB, "));
}
if (PointerUtils.Memcmp(outbuf, tmp3, 0x14) != 0)
{
throw (new InvalidDataException("WARNING (SHA-1 incorrect), "));
}
int iXOR;
for (iXOR = 0; iXOR < 0x40; iXOR++) {
tmp3[iXOR+0x14] = (byte)(outbuf[iXOR+0x80] ^ _tmp2[iXOR+0x10]);
}
if (Scramble((uint *)tmp3, 0x40, pti.code) != 0)
{
throw (new InvalidDataException("error in Scramble#3, "));
}
for (iXOR = 0x3F; iXOR >= 0; iXOR--) {
outbuf[iXOR+0x40] = (byte)(_tmp3[iXOR] ^ _tmp2[iXOR+0x50]); // uns 8
}
PointerUtils.Memset(outbuf + 0x80, 0, 0x30);
*(uint *)&outbuf[0xA0] = 1;
PointerUtils.Memcpy(outbuf + 0xB0, outbuf + 0xC0, 0x10);
PointerUtils.Memset(outbuf + 0xC0, 0, 0x10);
// the real decryption
var ret = Kirk.hleUtilsBufferCopyWithRange(outbuf, size, outbuf + 0x40, size - 0x40, Core.Crypto.Kirk.CommandEnum.PSP_KIRK_CMD_DECRYPT_PRIVATE);
if (ret != 0)
{
throw (new InvalidDataException(String.Format("error in sceUtilsBufferCopyWithRange 0x1 (0x{0:X}), ", ret)));
}
if (retsize < 0x150)
{
// Fill with 0
PointerUtils.Memset(outbuf + retsize, 0, 0x150 - retsize);
}
return _pbOut.Slice(0, retsize).ToArray();
}
}