1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

Merge pull request #63 from O1L/master

Improved UnPkg.
This commit is contained in:
DHrpcs3 2014-02-07 00:40:45 +02:00
commit ce88a4fc9a
3 changed files with 84 additions and 106 deletions

View File

@ -66,47 +66,6 @@ wxString GetPaneName()
return wxString::Format("Pane_%d", pane_num++); return wxString::Format("Pane_%d", pane_num++);
} }
bool wxMoveDir(wxString sFrom, wxString sTo)
{
if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH;
if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH;
if (!::wxDirExists(sFrom)) {
::wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str());
return false;
}
if (!wxDirExists(sTo)) {
if (!wxFileName::Mkdir(sTo, 0777, wxPATH_MKDIR_FULL)) {
::wxLogError(wxT("%s could not be created!"), sTo.c_str());
return false;
}
}
wxDir fDir(sFrom);
wxString sNext = wxEmptyString;
bool bIsFile = fDir.GetFirst(&sNext);
while (bIsFile) {
const wxString sFileFrom = sFrom + sNext;
const wxString sFileTo = sTo + sNext;
if (::wxDirExists(sFileFrom)) {
wxMoveDir(sFileFrom, sFileTo);
::wxRmdir(sFileFrom);
}
else {
if (!::wxFileExists(sFileTo)) {
if (!::wxCopyFile(sFileFrom, sFileTo)) {
::wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str());
return false;
}
}
::wxRemoveFile(sFileFrom);
}
bIsFile = fDir.GetNext(&sNext);
}
::wxRmdir(sFrom);
return true;
}
MainFrame::MainFrame() MainFrame::MainFrame()
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600)) : FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600))
, m_aui_mgr(this) , m_aui_mgr(this)
@ -267,47 +226,38 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
Emu.Stop(); Emu.Stop();
wxString fileName = ctrl.GetPath(); wxString fileName = ctrl.GetPath();
if (!pkg_unpack((const char *)fileName.mb_str()))
{ ConLog.Error("Could not unpack PKG!");
wxProgressDialog pdlg("Please wait", "Installing PKG...", 0, this, wxPD_APP_MODAL); else ConLog.Success("PKG: extract done.");
pkg_unpack((const char *)fileName.mb_str());
}
if (!wxRemoveFile(ctrl.GetPath()+".dec")) if (!wxRemoveFile(ctrl.GetPath()+".dec"))
ConLog.Warning("Could not delete the decoded DEC file"); ConLog.Warning("Could not delete the decoded DEC file");
// Copy the PKG to dev_hdd0 and format the path to be identical to the PS3.
wxString gamePath = "\\dev_hdd0\\game\\";
pkg_header *header; pkg_header *header;
pkg_info((const char *)fileName.mb_str(), &header); pkg_info((const char *)fileName.mb_str(), &header);
// Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO).
wxString titleID_full (header->title_id); wxString titleID_full (header->title_id);
wxString titleID = titleID_full.SubString(7, 15); wxString titleID = titleID_full.SubString(7, 15);
// Travel to bin folder.
wxSetWorkingDirectory(wxGetCwd() + "\\..\\");
// Save the main dir.
wxString mainDir = wxGetCwd(); wxString mainDir = wxGetCwd();
wxString gamePath = "\\dev_hdd0\\game\\";
// Set PKG dir. wxString pkgDir = wxT(mainDir + gamePath + titleID);
wxString oldPkgDir = wxT(mainDir + "\\" + titleID_full);
wxString newPkgDir = wxT(mainDir + gamePath + titleID);
// Move the final folder.
wxMoveDir(oldPkgDir, newPkgDir);
// Save the title ID. // Save the title ID.
Emu.SetTitleID(titleID); Emu.SetTitleID(titleID);
ConLog.Success("PKG: extract done."); //Refresh game list
// Travel to the main dir.
wxSetWorkingDirectory(mainDir);
m_game_viewer->Refresh(); m_game_viewer->Refresh();
Emu.BootGame(newPkgDir.c_str());
if(Emu.BootGame(pkgDir.c_str()))
{
ConLog.Success("Game: boot done.");
}
else
{
ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.c_str());
}
} }
void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))

View File

@ -65,13 +65,15 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn
case PKG_RELEASE_TYPE_DEBUG: case PKG_RELEASE_TYPE_DEBUG:
{ {
ConLog.Warning ("UnPkg: Debug PKG detected."); ConLog.Warning ("UnPkg: Debug PKG detected.");
wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, recrypting...", 0, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
u8* data; u8* data;
u8 sha_key[0x40]; u8 sha_key[0x40];
int i; int i;
f= fopen(fname, "rb"); f= fopen(fname, "rb");
fseek(f, 0, SEEK_END); _fseeki64(f, 0, SEEK_END);
int nlen = ftell(f); int nlen = _ftelli64(f);
fseek(f, 0, SEEK_SET); _fseeki64(f, 0, SEEK_SET);
data = (u8*)malloc(nlen); data = (u8*)malloc(nlen);
fread(data, 1, nlen, f); fread(data, 1, nlen, f);
fclose(f); fclose(f);
@ -93,6 +95,7 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn
u8 hash[0x14]; u8 hash[0x14];
sha1(sha_crap, 0x40, hash); sha1(sha_crap, 0x40, hash);
for(i=0;i<0x10;i++) data[dptr+i] ^= hash[i]; for(i=0;i<0x10;i++) data[dptr+i] ^= hash[i];
set_u64(sha_crap+0x38, get_u64(sha_crap+0x38)+1); set_u64(sha_crap+0x38, get_u64(sha_crap+0x38)+1);
} }
@ -114,20 +117,21 @@ static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fn
// add hash // add hash
sha1(data, nlen-0x20, &data[nlen-0x20]); sha1(data, nlen-0x20, &data[nlen-0x20]);
fwrite(data, 1, nlen, g); fwrite(data, 1, nlen, g);
//fclose(g); // not close the file for continuing //fclose(g); // not close the file for continuing
fseek(g, 0, SEEK_END); _fseeki64(g, 0, SEEK_END);
tmp = ftell(g); tmp = _ftelli64(g);
} }
break; break;
case PKG_RELEASE_TYPE_RELEASE: case PKG_RELEASE_TYPE_RELEASE:
{ {
ConLog.Warning ("UnPkg: Retail PKG detected."); ConLog.Warning ("UnPkg: Retail PKG detected.");
fseek(f, 0, SEEK_END); _fseeki64(f, 0, SEEK_END);
tmp = ftell(f); tmp = _ftelli64(f);
} }
break; break;
@ -188,19 +192,19 @@ static void print_pkg_header(pkg_header *header)
hash_tostring(qa, header->qa_digest, sizeof(header->qa_digest)); hash_tostring(qa, header->qa_digest, sizeof(header->qa_digest));
hash_tostring(kl, header->klicensee, sizeof(header->klicensee)); hash_tostring(kl, header->klicensee, sizeof(header->klicensee));
ConLog.Write("Magic: %x\n", ntohl(header->magic)); ConLog.Write("Magic: 0x%x", ntohl(header->magic));
ConLog.Write("Release Type: %x\n", ntohl(header->rel_type) >> 16 & (0xffff)); ConLog.Write("Release Type: 0x%x", ntohl(header->rel_type) >> 16 & (0xffff));
ConLog.Write("Platform Type: %x\n", ntohl(header->rel_type) & (0xffff)); ConLog.Write("Platform Type: 0x%x", ntohl(header->rel_type) & (0xffff));
ConLog.Write("Header size: %x\n", ntohl(header->header_size)); ConLog.Write("Header size: 0x%x", ntohl(header->header_size));
ConLog.Write("Unk1: %x\n", ntohl(header->unk1)); ConLog.Write("Unk1: 0x%x", ntohl(header->unk1));
ConLog.Write("Metadata size: %x\n", ntohl(header->meta_size)); ConLog.Write("Metadata size: 0x%x", ntohl(header->meta_size));
ConLog.Write("File count: %u\n", ntohl(header->file_count)); ConLog.Write("File count: %u", ntohl(header->file_count));
ConLog.Write("Pkg size: %llu\n", ntohll(header->pkg_size)); ConLog.Write("Pkg size: %llu", ntohll(header->pkg_size));
ConLog.Write("Data offset: %llx\n", ntohll(header->data_offset)); ConLog.Write("Data offset: 0x%llx", ntohll(header->data_offset));
ConLog.Write("Data size: %llu\n", ntohll(header->data_size)); ConLog.Write("Data size: 0x%llu", ntohll(header->data_size));
ConLog.Write("TitleID: %s\n", header->title_id); ConLog.Write("TitleID: %s", header->title_id);
ConLog.Write("QA Digest: %s\n", qa); ConLog.Write("QA Digest: %s", qa);
ConLog.Write( "KLicensee: %s\n", kl); ConLog.Write( "KLicensee: %s", kl);
} }
static void *pkg_info(const char *fname, pkg_header **h_ptr) static void *pkg_info(const char *fname, pkg_header **h_ptr)
@ -244,6 +248,9 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f,
u32 l; u32 l;
u64 hi, lo; u64 hi, lo;
int max = len / BUF_SIZE;
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
parts = len / BUF_SIZE; parts = len / BUF_SIZE;
if (len % BUF_SIZE != 0) if (len % BUF_SIZE != 0)
parts++; parts++;
@ -278,18 +285,19 @@ static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f,
} }
fwrite(out_buf, 1, l, out); fwrite(out_buf, 1, l, out);
pdlg.Update(i);
} }
pdlg.Update(max);
} }
static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec) static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec)
{ {
FILE *out = NULL; FILE *out = NULL;
u64 size; u64 size;
u32 tmp; u32 tmp;
u8 buf[BUF_SIZE]; u8 buf[BUF_SIZE];
fseek(dec, fentry->name_offset, SEEK_SET); _fseeki64(dec, fentry->name_offset, SEEK_SET);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
fread(buf, fentry->name_size, 1, dec); fread(buf, fentry->name_size, 1, dec);
@ -301,7 +309,7 @@ static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec)
case PKG_FILE_ENTRY_SDAT: case PKG_FILE_ENTRY_SDAT:
case PKG_FILE_ENTRY_REGULAR: case PKG_FILE_ENTRY_REGULAR:
out = fopen((char *)buf, "wb"); out = fopen((char *)buf, "wb");
fseek(dec, fentry->file_offset, SEEK_SET); _fseeki64(dec, fentry->file_offset, SEEK_SET);
for (size = 0; size < fentry->file_size; ) for (size = 0; size < fentry->file_size; )
{ {
size += fread(buf, sizeof(u8), BUF_SIZE, dec); size += fread(buf, sizeof(u8), BUF_SIZE, dec);
@ -320,14 +328,18 @@ static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec)
mkdir ((char *)buf); mkdir ((char *)buf);
break; break;
} }
return true;
} }
static void pkg_unpack_data(u32 file_count, FILE *dec) static void pkg_unpack_data(u32 file_count, FILE *dec)
{ {
int max = file_count;
wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
u32 i; u32 i;
pkg_file_entry *file_table = NULL; pkg_file_entry *file_table = NULL;
fseek(dec, 0, SEEK_SET); _fseeki64(dec, 0, SEEK_SET);
file_table = (pkg_file_entry *)malloc(sizeof(pkg_file_entry)*file_count); file_table = (pkg_file_entry *)malloc(sizeof(pkg_file_entry)*file_count);
i = fread(file_table, sizeof(pkg_file_entry), file_count, dec); i = fread(file_table, sizeof(pkg_file_entry), file_count, dec);
@ -346,27 +358,39 @@ static void pkg_unpack_data(u32 file_count, FILE *dec)
(file_table+i)->file_size = ntohll((file_table+i)->file_size); (file_table+i)->file_size = ntohll((file_table+i)->file_size);
(file_table+i)->type = ntohl((file_table+i)->type); (file_table+i)->type = ntohl((file_table+i)->type);
pkg_unpack_file(file_table+i, dec); if(pkg_unpack_file(file_table+i, dec)) pdlg.Update(i);
} }
free(file_table); free(file_table);
pdlg.Update(max);
} }
static void pkg_unpack(const char *fname) bool pkg_unpack(const char *fname)
{ {
FILE *f, *dec; FILE *f, *dec;
char *dec_fname; char *dec_fname;
pkg_header *header; pkg_header *header;
int ret;
struct stat sb; struct stat sb;
f = (FILE*) pkg_info(fname, &header); f = (FILE*) pkg_info(fname, &header);
if (f == NULL) if (f == NULL)
return; return false;
// Save the main dir.
wxString mainDir = wxGetCwd();
// Set the working directory.
wxSetWorkingDirectory(wxGetCwd() + "\\dev_hdd0\\game\\");
fseek(f, ntohll(header->data_offset), SEEK_SET); std::string gamePath = "\\dev_hdd0\\game\\";
// Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO).
std::string titleID_full (header->title_id);
std::string titleID = titleID_full.substr(7, 9);
std::string pkgDir = mainDir + gamePath + titleID;
_fseeki64(f, ntohll(header->data_offset), SEEK_SET);
dec_fname = (char*)malloc(strlen(fname)+4); dec_fname = (char*)malloc(strlen(fname)+4);
memset(dec_fname, 0, strlen(fname)+4); memset(dec_fname, 0, strlen(fname)+4);
@ -377,29 +401,33 @@ static void pkg_unpack(const char *fname)
{ {
ConLog.Error("UnPkg: Could not create temp file for decrypted data."); ConLog.Error("UnPkg: Could not create temp file for decrypted data.");
free(header); free(header);
return; return false;
} }
unlink(dec_fname); unlink(dec_fname);
pkg_crypt(PKG_AES_KEY, header->klicensee, f, ntohll(header->data_size), pkg_crypt(PKG_AES_KEY, header->klicensee, f, ntohll(header->data_size),
dec); dec);
fseek(dec, 0, SEEK_SET); _fseeki64(dec, 0, SEEK_SET);
fclose(f); fclose(f);
if (stat(header->title_id, &sb) != 0) if (stat(header->title_id, &sb) != 0)
{ {
ret = mkdir(header->title_id); if (mkdir(titleID.c_str()) < 0)
if (ret < 0)
{ {
ConLog.Error("UnPkg: Could not mkdir."); ConLog.Error("UnPkg: Could not mkdir.");
ConLog.Error("UnPkg: Possibly, folder already exists in dev_hdd0\\game : %s", titleID.c_str());
wxSetWorkingDirectory(mainDir);
free(header); free(header);
return; return false;
} }
} }
chdir(header->title_id); chdir(titleID.c_str());
pkg_unpack_data(ntohl(header->file_count), dec); pkg_unpack_data(ntohl(header->file_count), dec);
fclose(dec); fclose(dec);
wxSetWorkingDirectory(mainDir);
return true;
} }

View File

@ -164,11 +164,11 @@ static void *pkg_info(const char *fname, pkg_header **h_ptr);
static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f,
u64 len, FILE *out); u64 len, FILE *out);
static void pkg_unpack(const char *fname); bool pkg_unpack(const char *fname);
static void pkg_unpack_data(u32 file_count, FILE *dec); static void pkg_unpack_data(u32 file_count, FILE *dec);
static void pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);; static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);;
static int pkg_pack_data(file_table_tr *ftr, pkg_file_entry *table, static int pkg_pack_data(file_table_tr *ftr, pkg_file_entry *table,
int file_count, sha1_context *ctx, FILE *out); int file_count, sha1_context *ctx, FILE *out);