Skip to content

Commit 7b9f099

Browse files
committed
Decrypt The File
1 parent 3ce915b commit 7b9f099

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

src/data/FF7Save.cpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ FF7SaveInfo::FORMAT FF7Save::fileDataFormat(QFile &file)
7575
if(ps4binfile.size() == FF7SaveInfo::get()->fileSize(FF7SaveInfo::FORMAT::PS4BIN) && (ps4binfile.peek(FF7SaveInfo::fileHeaderSize(FF7SaveInfo::FORMAT::PS4BIN)) == FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT::PS4BIN))) {
7676
auto ps4bin = ps4binfile.readAll();
7777
m_ps4_iv = ps4bin.mid(0x10, 0x10);
78-
m_ps4_key = ps4bin.mid(0x20, 0x10);
78+
m_ps4_key = ps4bin.mid(0x20, 0x20);
7979
QTextStream(stdout)
8080
<< "[FF7Save::loadFile] PS4 BIN File Size: " << FF7SaveInfo::get()->fileSize(FF7SaveInfo::FORMAT::PS4BIN) << "\n"
8181
<< "[FF7Save::loadFile] PS4 BIN pfsSKKey IV: " << m_ps4_iv.toHex() << "\n"
8282
<< "[FF7Save::loadFile] PS4 BIN pfsSKKey KEY: " << m_ps4_key.toHex() << "\n";
83-
setFormat(FF7SaveInfo::FORMAT::PS4);
83+
return FF7SaveInfo::FORMAT::PS4;
8484
}
8585
}
8686
}
@@ -114,13 +114,28 @@ bool FF7Save::loadFile(const QString &fileName)
114114
return false;
115115

116116
setFormat(fileFormat);
117-
/*~~~~~~~~~~Start Load~~~~~~~~~~*/
118-
setFileHeader(file.read(FF7SaveInfo::fileHeaderSize(fileFormat)));
119-
for (int i = 0; i < FF7SaveInfo::slotCount(fileFormat); i++) {
120-
setSlotHeader(i, file.read(FF7SaveInfo::slotHeaderSize(fileFormat)));
121-
setSlotFF7Data(i, file.read(FF7SaveInfo::slotSize()));
122-
setSlotFooter(i, file.read(FF7SaveInfo::slotFooterSize(fileFormat)));
117+
118+
119+
if(fileFormat == FF7SaveInfo::FORMAT::PS4) {
120+
qDebug() << "Trying to Decrypt";
121+
QFile ofile("outdata.dat");
122+
ofile.open(QFile::WriteOnly);
123+
ofile.write(decryptPS4Save(file.readAll()));
124+
for (int i = 0; i < FF7SaveInfo::slotCount(fileFormat); i++) {
125+
setSlotHeader(i, QByteArray());
126+
setSlotFF7Data(i, decryptPS4Save(file.readAll()));
127+
setSlotFooter(i, QByteArray());
128+
}
129+
} else {
130+
/*~~~~~~~~~~Start Load~~~~~~~~~~*/
131+
setFileHeader(file.read(FF7SaveInfo::fileHeaderSize(fileFormat)));
132+
for (int i = 0; i < FF7SaveInfo::slotCount(fileFormat); i++) {
133+
setSlotHeader(i, file.read(FF7SaveInfo::slotHeaderSize(fileFormat)));
134+
setSlotFF7Data(i, file.read(FF7SaveInfo::slotSize()));
135+
setSlotFooter(i, file.read(FF7SaveInfo::slotFooterSize(fileFormat)));
136+
}
123137
}
138+
124139
/*~~~~~~~End Load~~~~~~~~~~~~~~*/
125140
if (FF7SaveInfo::isTypePC(fileFormat)) {
126141
for (int i = 0; i < 15; i++) {
@@ -2776,6 +2791,16 @@ bool FF7Save::fixMetaData(QString fileName, QString UserID)
27762791
return 1;
27772792
}
27782793

2794+
QByteArray FF7Save::decryptPS4Save(QByteArray in)
2795+
{
2796+
QByteArray buffer = in;
2797+
struct AES_ctx ctx;
2798+
AES_init_ctx_iv(&ctx, reinterpret_cast<uint8_t*>(m_ps4_key.data()), reinterpret_cast<uint8_t*>(m_ps4_iv.data()));
2799+
AES_CBC_decrypt_buffer(&ctx, reinterpret_cast<uint8_t*>(buffer.data()), 256);
2800+
qDebug() << "Decrypted Size" << buffer.size();
2801+
return buffer;
2802+
2803+
}
27792804
QByteArray FF7Save::generatePsSaveSignature(QByteArray data, QByteArray keySeed)
27802805
{
27812806
FF7SaveInfo::FORMAT saveFormat = format();

src/data/FF7Save.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,8 @@ class FF7TKDATA_EXPORT FF7Save: public QObject
10201020
*/
10211021
QString md5sum(QString fileName, QString UserID);
10221022

1023+
1024+
QByteArray decryptPS4Save(QByteArray in);
10231025
QString fileblock(const QString &fileName);
10241026
QString filetimestamp(QString fileName);
10251027
void checksumSlots();
@@ -1047,7 +1049,6 @@ class FF7TKDATA_EXPORT FF7Save: public QObject
10471049
QString filename;//opened file
10481050
QVector< SubContainer > parseXML(const QString &fileName, const QString &metadataPath, const QString &UserID);
10491051
QVector< SubContainer > createMetadata(const QString &fileName, const QString &UserID);
1050-
10511052
inline static const auto allDigetRegEx = QRegularExpression(QStringLiteral("^\\d+$"));
10521053
inline static const QString invalidRegion = QStringLiteral("\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000");
10531054
};

src/data/crypto/aes.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,33 @@ void XorWithByte(uint8_t* buf, uint8_t byte, int length)
326326
buf[i] ^= byte;
327327
}
328328
}
329+
330+
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
331+
{
332+
size_t i;
333+
uint8_t *Iv = ctx->Iv;
334+
for (i = 0; i < length; i += AES_BLOCKLEN)
335+
{
336+
XorWithIv(buf, Iv);
337+
Cipher((state_t*)buf, ctx->RoundKey);
338+
Iv = buf;
339+
buf += AES_BLOCKLEN;
340+
}
341+
/* store Iv in ctx for next call */
342+
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
343+
}
344+
345+
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
346+
{
347+
size_t i;
348+
uint8_t storeNextIv[AES_BLOCKLEN];
349+
for (i = 0; i < length; i += AES_BLOCKLEN)
350+
{
351+
memcpy(storeNextIv, buf, AES_BLOCKLEN);
352+
InvCipher((state_t*)buf, ctx->RoundKey);
353+
XorWithIv(buf, ctx->Iv);
354+
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
355+
buf += AES_BLOCKLEN;
356+
}
357+
358+
}

src/data/crypto/aes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct AES_ctx
2525
};
2626

2727
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
28+
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
29+
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
2830
void XorWithIv(uint8_t* buf, const uint8_t* Iv);
2931
void XorWithByte(uint8_t* buf, uint8_t byte, int length);
3032

@@ -34,6 +36,13 @@ void XorWithByte(uint8_t* buf, uint8_t byte, int length);
3436
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
3537
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
3638

39+
// buffer size MUST be mutile of AES_BLOCKLEN;
40+
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
41+
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
42+
// no IV should ever be reused with the same key
43+
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
44+
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
45+
3746
#ifdef __cplusplus
3847
}
3948
#endif

0 commit comments

Comments
 (0)