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); }
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); } }