Skip to content

Commit

Permalink
Add a standalone --ipl-decrypt option
Browse files Browse the repository at this point in the history
  • Loading branch information
artart78 committed Feb 23, 2021
1 parent 4653f49 commit 3dd4863
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 49 deletions.
2 changes: 1 addition & 1 deletion PsarDecrypter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ int pspDecryptPSAR(u8 *dataPSAR, u32 size, std::string outdir, bool extractOnly,

else if (strncmp(name, "ipl:", 4) == 0 && !extractOnly)
{
decryptIPL(data2, cbExpanded, intVersion, szFileBase, outdir);
decryptIPL(data2, cbExpanded, intVersion, szFileBase, outdir + "/PSARDUMPER");
}
}
else
Expand Down
18 changes: 9 additions & 9 deletions ipl_decrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,18 +551,18 @@ int extractIPLStages(u8 *inData, u32 inDataSize, int version, u32 loadAddr, cons
if (debug) {
printf("decompressed %d bytes\n", decSize);
}
szDataPath = outdir + "/PSARDUMPER/stage2_" + std::string(filename) + ".gz" ;
szDataPath = outdir + "/stage2_" + std::string(filename) + ".gz" ;
WriteFile(szDataPath.c_str(), (u8*)inData+gzip_addr-loadAddr, realInSize);

szDataPath = outdir + "/PSARDUMPER/stage2_" + std::string(filename);
szDataPath = outdir + "/stage2_" + std::string(filename);
WriteFile(szDataPath.c_str(), decBuf, decSize);
printf(",stage2 decompressed");
decSize = pspDecryptIPL3((u8*)inData+img2_addr-loadAddr, outBuf, inDataSize - (img2_addr-loadAddr));
if (!decSize) {
printf("Failed decrypting stage3!\n");
} else {
printf(",stage3 decrypted");
szDataPath = outdir + "/PSARDUMPER/stage3_" + std::string(filename);
szDataPath = outdir + "/stage3_" + std::string(filename);
WriteFile(szDataPath.c_str(), outBuf, decSize);
if (debug) {
printf("decrypted %d bytes\n", decSize);
Expand Down Expand Up @@ -703,10 +703,10 @@ int extractIPLStages(u8 *inData, u32 inDataSize, int version, u32 loadAddr, cons
if (debug) {
printf("decompressed %d bytes\n", decSize);
}
szDataPath = outdir + "/PSARDUMPER/stage2_" + std::string(filename) + ".gz";
szDataPath = outdir + "/stage2_" + std::string(filename) + ".gz";
WriteFile(szDataPath.c_str(), (u8*)inData+img_off-loadAddr, realInSize);

szDataPath = outdir + "/PSARDUMPER/stage2_" + std::string(filename);
szDataPath = outdir + "/stage2_" + std::string(filename);
WriteFile(szDataPath.c_str(), decBuf, decSize);
printf(",stage2 unscrambled & decompressed");

Expand Down Expand Up @@ -807,7 +807,7 @@ int extractIPLStages(u8 *inData, u32 inDataSize, int version, u32 loadAddr, cons
printf("Failed decrypting kernel keys!\n");
} else {
printf(",kernel keys decrypted");
szDataPath = outdir + "/PSARDUMPER/kkeys_" + std::string(filename);
szDataPath = outdir + "/kkeys_" + std::string(filename);
WriteFile(szDataPath.c_str(), outBuf, decSize);
}
}
Expand All @@ -833,15 +833,15 @@ int extractIPLStages(u8 *inData, u32 inDataSize, int version, u32 loadAddr, cons
if (debug) {
printf("decompressed %d bytes\n", decompSize);
}
szDataPath = outdir + "/PSARDUMPER/stage3_" + std::string(filename)+ ".gz";
szDataPath = outdir + "/stage3_" + std::string(filename)+ ".gz";
WriteFile(szDataPath.c_str(), outBuf, realInSize);

szDataPath = outdir + "/PSARDUMPER/stage3_" + std::string(filename);
szDataPath = outdir + "/stage3_" + std::string(filename);
WriteFile(szDataPath.c_str(), decBuf, decompSize);
printf(",stage3 decrypted & decompressed");
} else {
printf(",stage3 decrypted");
szDataPath = outdir + "/PSARDUMPER/stage3_" + std::string(filename);
szDataPath = outdir + "/stage3_" + std::string(filename);
WriteFile(szDataPath.c_str(), outBuf, decSize);
}
}
Expand Down
99 changes: 61 additions & 38 deletions pspdecrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <getopt.h>
#include "PsarDecrypter.h"
#include "PrxDecrypter.h"
#include "pspdecrypt_lib.h"
#include "common.h"

using namespace std;
Expand All @@ -24,12 +25,13 @@ void help(const char* exeName) {
cout << "General options:" << endl;
cout << " -v, --verbose enable verbose mode (mostly for debugging)" << endl;
cout << "PSP(/PBP)-only options:" << endl;
cout << " -o, --outfile output file for the decrypted binary (default: [FILE.PSP].dec)" << endl;
cout << " -o, --outfile=FILE output file for the decrypted binary (default: [FILE.PSP].dec)" << endl;
cout << "PSAR(/PBP)-only options:" << endl;
cout << " -e, --extract-only do not decrypt files contained in the PSAR" << endl;
cout << "IPL decryption & PSAR(/PBP) options:" << endl;
cout << " -O, --outdir output path for the PSAR's or IPL's contents (default: current directory)" << endl;
cout << " -O, --outdir=DIR output path for the PSAR's or IPL's contents (default: current directory)" << endl;
cout << " -i, --ipl-decrypt decrypt the IPL given as an argument" << endl;
cout << " -V, --version=VER the firmware version (eg 660) used for extracting the IPL stages" << endl;
cout << " -p, --preipl preipl image used for decrypting the later IPL stages" << endl;
}

Expand All @@ -43,6 +45,7 @@ int main(int argc, char *argv[]) {
{"outdir", required_argument, 0, 'O'},
{"ipl-decrypt", no_argument, 0, 'i'},
{"preipl", required_argument, 0, 'p'},
{"version", required_argument, 0, 'V'},
{0, 0, 0, 0 }
};
int long_index;
Expand All @@ -54,8 +57,9 @@ int main(int argc, char *argv[]) {
bool verbose = false;
bool extractOnly = false;
bool iplDecrypt = false;
int version = -1;
int c = 0;
while ((c = getopt_long(argc, argv, "hvo:eO:ip:", long_options, &long_index)) != -1) {
while ((c = getopt_long(argc, argv, "hvo:eO:ip:V:", long_options, &long_index)) != -1) {
switch (c) {
case 'h':
help(argv[0]);
Expand All @@ -78,6 +82,9 @@ int main(int argc, char *argv[]) {
case 'p':
preipl = string(optarg);
break;
case 'V':
version = atoi(optarg);
break;
default:
help(argv[0]);
return 1;
Expand Down Expand Up @@ -117,44 +124,60 @@ int main(int argc, char *argv[]) {
return 1;
}

switch (*(u32*)inData) {
case PSP_MAGIC:
{
int outSize = pspDecryptPRX((const u8*)inData, (u8 *)outData, size, nullptr, true);
WriteFile(outFile.c_str(), outData, outSize);
}
break;
case PBP_MAGIC:
{
u32 pspOff = *(u32*)&inData[0x20];
u32 psarOff = *(u32*)&inData[0x24];
if (pspOff < size) {
if (*(u32*)&inData[pspOff] == ELF_MAGIC) {
cout << "Non-encrypted PSP file, writing to " << outFile << endl;
WriteFile(outFile.c_str(), &inData[pspOff], psarOff - pspOff);
} else {
cout << "Decrypting PSP file to " << outFile << endl;
int outSize = pspDecryptPRX((const u8 *)&inData[pspOff], (u8 *)outData, psarOff - pspOff, nullptr, true);
WriteFile(outFile.c_str(), outData, outSize);
}
if (iplDecrypt) {
if (version < 0) {
cerr << "You need to set --version to extract later stages of a standalone IPL." << endl;
return 1;
}
cout << "Decrypting standalone IPL";
if (decryptIPL((u8*)inData, size, version, "ipl", outDir) < 0) {
cerr << endl << "Failed!" << endl;
return 1;
}
cout << endl;
} else {
switch (*(u32*)inData) {
case PSP_MAGIC:
{
int outSize = pspDecryptPRX((const u8*)inData, (u8 *)outData, size, nullptr, true);
WriteFile(outFile.c_str(), outData, outSize);
}
if (psarOff < size) {
cout << "Extracting PSAR to " << outDir << endl;
pspDecryptPSAR((u8*)&inData[psarOff], (u32)size - psarOff, outDir, extractOnly, verbose);
break;
case PBP_MAGIC:
{
u32 pspOff = *(u32*)&inData[0x20];
u32 psarOff = *(u32*)&inData[0x24];
if (pspOff < size) {
if (*(u32*)&inData[pspOff] == ELF_MAGIC) {
cout << "Non-encrypted PSP file, writing to " << outFile << endl;
WriteFile(outFile.c_str(), &inData[pspOff], psarOff - pspOff);
} else {
cout << "Decrypting PSP file to " << outFile << endl;
int outSize = pspDecryptPRX((const u8 *)&inData[pspOff], (u8 *)outData, psarOff - pspOff, nullptr, true);
WriteFile(outFile.c_str(), outData, outSize);
}
}
if (psarOff < size) {
cout << "Extracting PSAR to " << outDir << endl;
pspDecryptPSAR((u8*)&inData[psarOff], (u32)size - psarOff, outDir, extractOnly, verbose);
}
}
}
break;
case PSAR_MAGIC:
pspDecryptPSAR((u8*)inData, size, outDir, extractOnly, verbose);
break;
case ELF_MAGIC:
cout << "Non-encrypted file, copying to " << outFile << endl;
WriteFile(outFile.c_str(), inData, size);
break;
default:
cout << "Unknown input file format!" << endl;
return 1;
break;
case PSAR_MAGIC:
pspDecryptPSAR((u8*)inData, size, outDir, extractOnly, verbose);
break;
case ELF_MAGIC:
cout << "Non-encrypted file, copying to " << outFile << endl;
WriteFile(outFile.c_str(), inData, size);
break;
default:
cout << "Unknown input file format!" << endl;
return 1;
}
}

delete[] inData;
delete[] outData;

return 0;
}
3 changes: 2 additions & 1 deletion pspdecrypt_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,14 @@ int pspLinearizeIPL2(const u8* pbIn, u8* pbOut, int cbIn, u32 *startAddr)
int decryptIPL(u8 *inData, u32 inDataSize, int version, const char *filename, std::string outdir)
{
u8 *tmpData = new u8[inDataSize];
kirk_init();
int cb1 = pspDecryptIPL1(inData, tmpData, inDataSize);
if (cb1 > 0)
{
printf(",decrypted IPL");
u32 addr;
int cb2 = pspLinearizeIPL2(tmpData, inData, cb1, &addr);
std::string szDataPath = outdir + "/PSARDUMPER/stage1_" + filename;
std::string szDataPath = outdir + "/stage1_" + filename;
if (cb2 > 0 && WriteFile(szDataPath.c_str(), inData, cb2))
{
printf(",linearized at %08x", addr);
Expand Down

0 comments on commit 3dd4863

Please sign in to comment.