Example #1
0
        private byte[] DecryptData(int dataSize, long dataRelativeOffset, long pkgEncryptedFileStartOffset, byte[] AesKey, Stream encrPKGReadStream, BinaryReader brEncrPKG)
        {
            int size = dataSize % 16;

            if (size > 0)
            {
                size = ((dataSize / 16) + 1) * 16;
            }
            else
            {
                size = dataSize;
            }

            byte[] EncryptedData    = new byte[size];
            byte[] DecryptedData    = new byte[size];
            byte[] PKGFileKeyConsec = new byte[size];
            byte[] PKGXorKeyConsec  = new byte[size];
            byte[] incPKGFileKey    = new byte[PKGFileKey.Length];
            Array.Copy(PKGFileKey, incPKGFileKey, PKGFileKey.Length);

            encrPKGReadStream.Seek(dataRelativeOffset + pkgEncryptedFileStartOffset, SeekOrigin.Begin);
            EncryptedData = brEncrPKG.ReadBytes(size);

            for (int pos = 0; pos < dataRelativeOffset; pos += 16)
            {
                IncrementArray(ref incPKGFileKey, PKGFileKey.Length - 1);
            }

            for (int pos = 0; pos < size; pos += 16)
            {
                Array.Copy(incPKGFileKey, 0, PKGFileKeyConsec, pos, PKGFileKey.Length);

                IncrementArray(ref incPKGFileKey, PKGFileKey.Length - 1);
            }

            //the incremented "file" key have to be encrypted with a "global AES key" to generate the "xor" key
            //PSP uses CipherMode.ECB, PaddingMode.None that doesn't need IV
            PKGXorKeyConsec = AESEngine.Encrypt(PKGFileKeyConsec, AesKey, AesKey, CipherMode.ECB, PaddingMode.None);

            //XOR Decrypt and save every 16 bytes of data:
            DecryptedData = XOREngine.XOR(EncryptedData, 0, PKGXorKeyConsec.Length, PKGXorKeyConsec);

            return(DecryptedData);
        }
Example #2
0
        private string DecryptPKGFile(string PKGFileName)
        {
            try
            {
                int    moltiplicator = 65536;
                byte[] EncryptedData = new byte[AesKey.Length * moltiplicator];
                byte[] DecryptedData = new byte[AesKey.Length * moltiplicator];

                byte[] PKGXorKey = new byte[AesKey.Length];
                byte[] EncryptedFileStartOffset = new byte[4];
                byte[] EncryptedFileLenght      = new byte[4];

                Stream       PKGReadStream = new FileStream(PKGFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                BinaryReader brPKG         = new BinaryReader(PKGReadStream);

                PKGReadStream.Seek(0x00, SeekOrigin.Begin);
                byte[] pkgMagic = brPKG.ReadBytes(4);
                if (pkgMagic[0x00] != 0x7F || pkgMagic[0x01] != 0x50 || pkgMagic[0x02] != 0x4B || pkgMagic[0x03] != 0x47)
                {
                    txtResults.Text += "ERROR: Selected file isn't a Pkg file.";
                    SystemSounds.Beep.Play();
                    return(string.Empty);
                }

                //Finalized byte
                PKGReadStream.Seek(0x04, SeekOrigin.Begin);
                byte pkgFinalized = brPKG.ReadByte();

                if (pkgFinalized != 0x80)
                {
                    MessageBox.Show("Detected Debug PKG. Currently fixing tool. Please be patient");
                    SystemSounds.Beep.Play();
                    SystemSounds.Beep.Play();
                }

                //PKG Type PSP/PS3
                PKGReadStream.Seek(0x07, SeekOrigin.Begin);
                byte pkgType = brPKG.ReadByte();

                switch (pkgType)
                {
                case 0x01:
                    //PS3
                    AesKey = PS3AesKey;
                    break;

                case 0x02:
                    //PSP
                    AesKey = PSPAesKey;
                    break;

                default:
                    txtResults.Text += "ERROR: Selected pkg isn't Valid.";
                    SystemSounds.Beep.Play();
                    return(string.Empty);
                }

                //0x24 Store the start Address of the encrypted file to decrypt
                PKGReadStream.Seek(0x24, SeekOrigin.Begin);
                EncryptedFileStartOffset = brPKG.ReadBytes((int)EncryptedFileStartOffset.Length);
                Array.Reverse(EncryptedFileStartOffset);
                uiEncryptedFileStartOffset = BitConverter.ToUInt32(EncryptedFileStartOffset, 0);

                //0x1C Store the length of the whole pkg file

                //0x2C Store the length of the encrypted file to decrypt
                PKGReadStream.Seek(0x2C, SeekOrigin.Begin);
                EncryptedFileLenght = brPKG.ReadBytes((int)EncryptedFileLenght.Length);
                Array.Reverse(EncryptedFileLenght);
                uint uiEncryptedFileLenght = BitConverter.ToUInt32(EncryptedFileLenght, 0);

                //0x70 Store the PKG file Key.
                PKGReadStream.Seek(0x70, SeekOrigin.Begin);
                PKGFileKey = brPKG.ReadBytes(16);
                byte[] incPKGFileKey = new byte[16];
                Array.Copy(PKGFileKey, incPKGFileKey, PKGFileKey.Length);

                //the "file" key at 0x70 have to be encrypted with a "global AES key" to generate the "xor" key
                //PSP uses CipherMode.ECB, PaddingMode.None that doesn't need IV
                PKGXorKey = AESEngine.Encrypt(PKGFileKey, AesKey, AesKey, CipherMode.ECB, PaddingMode.None);

                // Pieces calculation
                double division = (double)uiEncryptedFileLenght / (double)AesKey.Length;
                UInt64 pieces   = (UInt64)Math.Floor(division);
                UInt64 mod      = (UInt64)uiEncryptedFileLenght / (UInt64)AesKey.Length;
                if (mod > 0)
                {
                    pieces += 1;
                }

                if (File.Exists(PKGFileName + ".Dec"))
                {
                    File.Delete(PKGFileName + ".Dec");
                }

                //Write File
                FileStream   DecryptedFileWriteStream = new FileStream(PKGFileName + ".Dec", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
                BinaryWriter bwDecryptedFile          = new BinaryWriter(DecryptedFileWriteStream);

                //Put the read pointer on the encrypted starting point.
                PKGReadStream.Seek((int)uiEncryptedFileStartOffset, SeekOrigin.Begin);

                // Pieces calculation
                double filedivision = (double)uiEncryptedFileLenght / (double)(AesKey.Length * moltiplicator);
                UInt64 filepieces   = (UInt64)Math.Floor(filedivision);
                UInt64 filemod      = (UInt64)uiEncryptedFileLenght % (UInt64)(AesKey.Length * moltiplicator);
                if (filemod > 0)
                {
                    filepieces += 1;
                }

                progressBar.Value   = 0;
                progressBar.Maximum = (int)filepieces - 1;
                progressBar.Step    = 1;
                Application.DoEvents();

                for (UInt64 i = 0; i < filepieces; i++)
                {
                    //If we have a mod and this is the last piece then...
                    if ((filemod > 0) && (i == (filepieces - 1)))
                    {
                        EncryptedData = new byte[filemod];
                        DecryptedData = new byte[filemod];
                    }

                    //Read 16 bytes of Encrypted data
                    EncryptedData = brPKG.ReadBytes(EncryptedData.Length);

                    //In order to retrieve a fast AES Encryption we pre-Increment the array
                    byte[] PKGFileKeyConsec = new byte[EncryptedData.Length];
                    byte[] PKGXorKeyConsec  = new byte[EncryptedData.Length];

                    for (int pos = 0; pos < EncryptedData.Length; pos += AesKey.Length)
                    {
                        Array.Copy(incPKGFileKey, 0, PKGFileKeyConsec, pos, PKGFileKey.Length);

                        IncrementArray(ref incPKGFileKey, PKGFileKey.Length - 1);
                    }

                    //the incremented "file" key have to be encrypted with a "global AES key" to generate the "xor" key
                    //PSP uses CipherMode.ECB, PaddingMode.None that doesn't need IV
                    PKGXorKeyConsec = AESEngine.Encrypt(PKGFileKeyConsec, AesKey, AesKey, CipherMode.ECB, PaddingMode.None);

                    //XOR Decrypt and save every 16 bytes of data:
                    DecryptedData = XOREngine.XOR(EncryptedData, 0, PKGXorKeyConsec.Length, PKGXorKeyConsec);

                    progressBar.PerformStep();
                    Application.DoEvents();

                    bwDecryptedFile.Write(DecryptedData);
                }
                Application.DoEvents();

                DecryptedFileWriteStream.Close();
                bwDecryptedFile.Close();

                return(PKGFileName + ".Dec");
            }
            catch (Exception ex)
            {
                txtResults.Text += "ERROR: An error occured during the decrypting process ";
                SystemSounds.Beep.Play();
                return(string.Empty);
            }
        }