mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 22:19:02 +00:00
wxFile removed (rFile -> rfile_t)
This commit is contained in:
parent
2cafa84b75
commit
ab405901ee
43 changed files with 814 additions and 973 deletions
|
|
@ -136,7 +136,7 @@ unsigned char* get_block_key(int block, NPD_HEADER *npd)
|
|||
}
|
||||
|
||||
// EDAT/SDAT decryption.
|
||||
int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose)
|
||||
int decrypt_data(const rfile_t *in, const rfile_t *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose)
|
||||
{
|
||||
// Get metadata info and setup buffers.
|
||||
int block_num = (int)((edat->file_size + edat->block_size - 1) / edat->block_size);
|
||||
|
|
@ -170,11 +170,11 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
if ((edat->flags & EDAT_COMPRESSED_FLAG) != 0)
|
||||
{
|
||||
metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size;
|
||||
in->Seek(metadata_sec_offset);
|
||||
in->seek(metadata_sec_offset);
|
||||
|
||||
unsigned char metadata[0x20];
|
||||
memset(metadata, 0, 0x20);
|
||||
in->Read(metadata, 0x20);
|
||||
in->read(metadata, 0x20);
|
||||
|
||||
// If the data is compressed, decrypt the metadata.
|
||||
// NOTE: For NPD version 1 the metadata is not encrypted.
|
||||
|
|
@ -199,11 +199,11 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
{
|
||||
// If FLAG 0x20, the metadata precedes each data block.
|
||||
metadata_sec_offset = metadata_offset + (unsigned long long) i * (metadata_section_size + length);
|
||||
in->Seek(metadata_sec_offset);
|
||||
in->seek(metadata_sec_offset);
|
||||
|
||||
unsigned char metadata[0x20];
|
||||
memset(metadata, 0, 0x20);
|
||||
in->Read(metadata, 0x20);
|
||||
in->read(metadata, 0x20);
|
||||
memcpy(hash_result, metadata, 0x14);
|
||||
|
||||
// If FLAG 0x20 is set, apply custom xor.
|
||||
|
|
@ -220,9 +220,9 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
else
|
||||
{
|
||||
metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size;
|
||||
in->Seek(metadata_sec_offset);
|
||||
in->seek(metadata_sec_offset);
|
||||
|
||||
in->Read(hash_result, 0x10);
|
||||
in->read(hash_result, 0x10);
|
||||
offset = metadata_offset + (unsigned long long) i * edat->block_size + (unsigned long long) block_num * metadata_section_size;
|
||||
length = edat->block_size;
|
||||
|
||||
|
|
@ -242,8 +242,8 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
memset(hash, 0, 0x10);
|
||||
memset(key_result, 0, 0x10);
|
||||
|
||||
in->Seek(offset);
|
||||
in->Read(enc_data, length);
|
||||
in->seek(offset);
|
||||
in->read(enc_data, length);
|
||||
|
||||
// Generate a key for the current block.
|
||||
b_key = get_block_key(i, npd);
|
||||
|
|
@ -305,7 +305,7 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
LOG_NOTICE(LOADER, "EDAT: Decompressing data...");
|
||||
|
||||
int res = decompress(decomp_data, dec_data, decomp_size);
|
||||
out->Write(decomp_data, res);
|
||||
out->write(decomp_data, res);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
|
|
@ -330,7 +330,7 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
}
|
||||
else
|
||||
{
|
||||
out->Write(dec_data, pad_length);
|
||||
out->write(dec_data, pad_length);
|
||||
}
|
||||
|
||||
delete[] enc_data;
|
||||
|
|
@ -340,9 +340,9 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi
|
|||
return 0;
|
||||
}
|
||||
|
||||
int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, bool verbose)
|
||||
int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const rfile_t *f, bool verbose)
|
||||
{
|
||||
f->Seek(0);
|
||||
f->seek(0);
|
||||
unsigned char header[0xA0];
|
||||
unsigned char empty_header[0xA0];
|
||||
unsigned char header_hash[0x10];
|
||||
|
|
@ -384,12 +384,12 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f,
|
|||
}
|
||||
|
||||
// Read in the file header.
|
||||
f->Read(header, 0xA0);
|
||||
f->read(header, 0xA0);
|
||||
|
||||
// Read in the header and metadata section hashes.
|
||||
f->Seek(0x90);
|
||||
f->Read(metadata_hash, 0x10);
|
||||
f->Read(header_hash, 0x10);
|
||||
f->seek(0x90);
|
||||
f->read(metadata_hash, 0x10);
|
||||
f->read(header_hash, 0x10);
|
||||
|
||||
// Setup the hashing mode and the crypto mode used in the file.
|
||||
int crypto_mode = 0x1;
|
||||
|
|
@ -443,10 +443,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f,
|
|||
while (bytes_to_read > 0)
|
||||
{
|
||||
// Locate the metadata blocks.
|
||||
f->Seek(metadata_section_offset);
|
||||
f->seek(metadata_section_offset);
|
||||
|
||||
// Read in the metadata.
|
||||
f->Read(metadata + bytes_read, metadata_section_size);
|
||||
f->read(metadata + bytes_read, metadata_section_size);
|
||||
|
||||
// Adjust sizes.
|
||||
bytes_read += metadata_section_size;
|
||||
|
|
@ -490,10 +490,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f,
|
|||
|
||||
|
||||
// Read in the metadata and header signatures.
|
||||
f->Seek(0xB0);
|
||||
f->Read(metadata_signature, 0x28);
|
||||
f->Seek(0xD8);
|
||||
f->Read(header_signature, 0x28);
|
||||
f->seek(0xB0);
|
||||
f->read(metadata_signature, 0x28);
|
||||
f->seek(0xD8);
|
||||
f->read(header_signature, 0x28);
|
||||
|
||||
// Checking metadata signature.
|
||||
// Setup signature r and s.
|
||||
|
|
@ -508,8 +508,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f,
|
|||
{
|
||||
int metadata_buf_size = block_num * 0x10;
|
||||
unsigned char *metadata_buf = new unsigned char[metadata_buf_size];
|
||||
f->Seek(metadata_offset);
|
||||
f->Read(metadata_buf, metadata_buf_size);
|
||||
f->seek(metadata_offset);
|
||||
f->read(metadata_buf, metadata_buf_size);
|
||||
sha1(metadata_buf, metadata_buf_size, signature_hash);
|
||||
delete[] metadata_buf;
|
||||
}
|
||||
|
|
@ -541,8 +541,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f,
|
|||
// Setup header signature hash.
|
||||
memset(signature_hash, 0, 20);
|
||||
unsigned char *header_buf = new unsigned char[0xD8];
|
||||
f->Seek(0x00);
|
||||
f->Read(header_buf, 0xD8);
|
||||
f->seek(0x00);
|
||||
f->read(header_buf, 0xD8);
|
||||
sha1(header_buf, 0xD8, signature_hash );
|
||||
delete[] header_buf;
|
||||
|
||||
|
|
@ -639,7 +639,7 @@ int validate_npd_hashes(const char* file_name, unsigned char *klicensee, NPD_HEA
|
|||
return (title_hash_result && dev_hash_result);
|
||||
}
|
||||
|
||||
bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsigned char* devklic, unsigned char* rifkey, bool verbose)
|
||||
bool extract_data(const rfile_t *input, const rfile_t *output, const char* input_file_name, unsigned char* devklic, unsigned char* rifkey, bool verbose)
|
||||
{
|
||||
// Setup NPD and EDAT/SDAT structs.
|
||||
NPD_HEADER *NPD = new NPD_HEADER();
|
||||
|
|
@ -648,8 +648,8 @@ bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsi
|
|||
// Read in the NPD and EDAT/SDAT headers.
|
||||
char npd_header[0x80];
|
||||
char edat_header[0x10];
|
||||
input->Read(npd_header, sizeof(npd_header));
|
||||
input->Read(edat_header, sizeof(edat_header));
|
||||
input->read(npd_header, sizeof(npd_header));
|
||||
input->read(edat_header, sizeof(edat_header));
|
||||
|
||||
memcpy(NPD->magic, npd_header, 4);
|
||||
NPD->version = swap32(*(int*)&npd_header[4]);
|
||||
|
|
@ -812,9 +812,9 @@ bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsi
|
|||
int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose)
|
||||
{
|
||||
// Prepare the files.
|
||||
rFile input(input_file_name.c_str());
|
||||
rFile output(output_file_name.c_str(), rFile::write);
|
||||
rFile rap(rap_file_name.c_str());
|
||||
rfile_t input(input_file_name);
|
||||
rfile_t output(output_file_name, o_write | o_create | o_trunc);
|
||||
rfile_t rap(rap_file_name);
|
||||
|
||||
// Set keys (RIF and DEVKLIC).
|
||||
unsigned char rifkey[0x10];
|
||||
|
|
@ -866,36 +866,30 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
|
|||
}
|
||||
|
||||
// Check the input/output files.
|
||||
if (!input.IsOpened() || !output.IsOpened())
|
||||
if (!input || !output)
|
||||
{
|
||||
LOG_ERROR(LOADER, "EDAT: Failed to open files!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read the RAP file, if provided.
|
||||
if (rap.IsOpened())
|
||||
if (rap)
|
||||
{
|
||||
unsigned char rapkey[0x10];
|
||||
memset(rapkey, 0, 0x10);
|
||||
|
||||
rap.Read(rapkey, 0x10);
|
||||
rap.read(rapkey, 0x10);
|
||||
|
||||
rap_to_rif(rapkey, rifkey);
|
||||
|
||||
rap.Close();
|
||||
}
|
||||
|
||||
// Delete the bad output file if any errors arise.
|
||||
if (extract_data(&input, &output, input_file_name.c_str(), devklic, rifkey, verbose))
|
||||
{
|
||||
input.Close();
|
||||
output.Close();
|
||||
output.close();
|
||||
rRemoveFile(output_file_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
input.Close();
|
||||
output.Close();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,4 +33,4 @@ typedef struct
|
|||
unsigned long long file_size;
|
||||
} EDAT_HEADER;
|
||||
|
||||
int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose);
|
||||
int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose);
|
||||
|
|
|
|||
|
|
@ -13,54 +13,63 @@
|
|||
#include "Utilities/rFile.h"
|
||||
|
||||
// Decryption.
|
||||
bool CheckHeader(rFile& pkg_f, PKGHeader* m_header)
|
||||
bool CheckHeader(const rfile_t& pkg_f, PKGHeader* m_header)
|
||||
{
|
||||
if (m_header->pkg_magic != 0x7F504B47) {
|
||||
if (m_header->pkg_magic != 0x7F504B47)
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Not a package file!");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ((u32)m_header->pkg_type)
|
||||
switch (const u16 type = m_header->pkg_type)
|
||||
{
|
||||
case PKG_RELEASE_TYPE_DEBUG: break;
|
||||
case PKG_RELEASE_TYPE_RELEASE: break;
|
||||
default:
|
||||
LOG_ERROR(LOADER, "PKG: Unknown PKG type!");
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Unknown PKG type (0x%x)", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch ((u32)m_header->pkg_platform)
|
||||
switch (const u16 platform = m_header->pkg_platform)
|
||||
{
|
||||
case PKG_PLATFORM_TYPE_PS3: break;
|
||||
case PKG_PLATFORM_TYPE_PSP: break;
|
||||
default:
|
||||
LOG_ERROR(LOADER, "PKG: Unknown PKG type!");
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Unknown PKG platform (0x%x)", platform);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_header->header_size != PKG_HEADER_SIZE)
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Wrong header size (0x%x)", m_header->header_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_header->header_size != PKG_HEADER_SIZE) {
|
||||
LOG_ERROR(LOADER, "PKG: Wrong header size!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_header->pkg_size != pkg_f.Length()) {
|
||||
LOG_WARNING(LOADER, "PKG: File size mismatch.");
|
||||
if (m_header->pkg_size != pkg_f.size())
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: File size mismatch (pkg_size=0x%x)", m_header->pkg_size);
|
||||
//return false;
|
||||
}
|
||||
|
||||
if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.Length()) {
|
||||
LOG_WARNING(LOADER, "PKG: Data size mismatch.");
|
||||
if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.size())
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Data size mismatch (data_size=0x%x, offset=0x%x)", m_header->data_size, m_header->data_offset);
|
||||
//return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadHeader(rFile& pkg_f, PKGHeader* m_header)
|
||||
bool LoadHeader(const rfile_t& pkg_f, PKGHeader* m_header)
|
||||
{
|
||||
pkg_f.Seek(0);
|
||||
pkg_f.seek(0);
|
||||
|
||||
if (pkg_f.Read(m_header, sizeof(PKGHeader)) != sizeof(PKGHeader)) {
|
||||
if (pkg_f.read(m_header, sizeof(PKGHeader)) != sizeof(PKGHeader))
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Package file is too short!");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -71,10 +80,12 @@ bool LoadHeader(rFile& pkg_f, PKGHeader* m_header)
|
|||
return true;
|
||||
}
|
||||
|
||||
int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header)
|
||||
int Decrypt(const rfile_t& pkg_f, const rfile_t& dec_pkg_f, PKGHeader* m_header)
|
||||
{
|
||||
if (!LoadHeader(pkg_f, m_header))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
aes_context c;
|
||||
u8 iv[HASH_LEN];
|
||||
|
|
@ -89,7 +100,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header)
|
|||
memcpy(key+0x10, &m_header->qa_digest[8], 8); // &data[0x68]
|
||||
memcpy(key+0x18, &m_header->qa_digest[8], 8); // &data[0x68]
|
||||
|
||||
pkg_f.Seek(m_header->data_offset);
|
||||
pkg_f.seek(m_header->data_offset);
|
||||
u32 parts = (m_header->data_size + BUF_SIZE - 1) / BUF_SIZE;
|
||||
|
||||
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", parts, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
|
@ -100,7 +111,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header)
|
|||
for (u32 i=0; i<parts; i++)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
u32 length = pkg_f.Read(buf, BUF_SIZE);
|
||||
u32 length = pkg_f.read(buf, BUF_SIZE);
|
||||
u32 bits = (length + HASH_LEN - 1) / HASH_LEN;
|
||||
|
||||
if (m_header->pkg_type == PKG_RELEASE_TYPE_DEBUG)
|
||||
|
|
@ -136,7 +147,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header)
|
|||
buf[j] ^= ctr[j];
|
||||
}
|
||||
}
|
||||
dec_pkg_f.Write(buf, length);
|
||||
dec_pkg_f.write(buf, length);
|
||||
pdlg.Update(i);
|
||||
}
|
||||
pdlg.Update(parts);
|
||||
|
|
@ -144,12 +155,13 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header)
|
|||
}
|
||||
|
||||
// Unpacking.
|
||||
bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries)
|
||||
bool LoadEntries(const rfile_t& dec_pkg_f, PKGHeader* m_header, PKGEntry* m_entries)
|
||||
{
|
||||
dec_pkg_f.Seek(0);
|
||||
dec_pkg_f.Read(m_entries, sizeof(PKGEntry) * m_header->file_count);
|
||||
dec_pkg_f.seek(0);
|
||||
dec_pkg_f.read(m_entries, sizeof(PKGEntry) * m_header->file_count);
|
||||
|
||||
if (m_entries->name_offset / sizeof(PKGEntry) != m_header->file_count) {
|
||||
if (m_entries->name_offset / sizeof(PKGEntry) != m_header->file_count)
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG: Entries are damaged!");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -157,12 +169,12 @@ bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
||||
bool UnpackEntry(const rfile_t& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
dec_pkg_f.Seek(entry.name_offset);
|
||||
dec_pkg_f.Read(buf, entry.name_size);
|
||||
dec_pkg_f.seek(entry.name_offset);
|
||||
dec_pkg_f.read(buf, entry.name_size);
|
||||
buf[entry.name_size] = 0;
|
||||
|
||||
switch (entry.type.data() >> 24)
|
||||
|
|
@ -172,30 +184,33 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
|||
case PKG_FILE_ENTRY_SDAT:
|
||||
case PKG_FILE_ENTRY_REGULAR:
|
||||
{
|
||||
rFile out;
|
||||
auto path = dir + std::string(buf, entry.name_size);
|
||||
|
||||
if (rExists(path))
|
||||
{
|
||||
LOG_WARNING(LOADER, "PKG Loader: File is overwritten: %s", path.c_str());
|
||||
LOG_WARNING(LOADER, "PKG Loader: '%s' is overwritten", path);
|
||||
}
|
||||
|
||||
if (out.Create(path, true /* overwriting */))
|
||||
{
|
||||
dec_pkg_f.Seek(entry.file_offset);
|
||||
rfile_t out;
|
||||
|
||||
for (u64 size = 0; size < entry.file_size;) {
|
||||
size += dec_pkg_f.Read(buf, BUF_SIZE);
|
||||
if (out.open(path, o_write | o_create | o_trunc))
|
||||
{
|
||||
dec_pkg_f.seek(entry.file_offset);
|
||||
|
||||
for (u64 size = 0; size < entry.file_size;)
|
||||
{
|
||||
size += dec_pkg_f.read(buf, BUF_SIZE);
|
||||
if (size > entry.file_size)
|
||||
out.Write(buf, BUF_SIZE - (size - entry.file_size));
|
||||
out.write(buf, BUF_SIZE - (size - entry.file_size));
|
||||
else
|
||||
out.Write(buf, BUF_SIZE);
|
||||
out.write(buf, BUF_SIZE);
|
||||
}
|
||||
out.Close();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG Loader: Could not create file: %s", path.c_str());
|
||||
LOG_ERROR(LOADER, "PKG Loader: Could not create file '%s'", path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -220,41 +235,44 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
|
|||
}
|
||||
}
|
||||
|
||||
int Unpack(rFile& pkg_f, std::string src, std::string dst)
|
||||
int Unpack(const rfile_t& pkg_f, std::string src, std::string dst)
|
||||
{
|
||||
PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader));
|
||||
|
||||
rFile dec_pkg_f;
|
||||
// TODO: This shouldn't use current dir
|
||||
std::string decryptedFile = "./dev_hdd1/" + src + ".dec";
|
||||
|
||||
dec_pkg_f.Create(decryptedFile, true);
|
||||
rfile_t dec_pkg_f(decryptedFile, o_read | o_write | o_create | o_trunc);
|
||||
|
||||
if (Decrypt(pkg_f, dec_pkg_f, m_header) < 0)
|
||||
{
|
||||
return -1;
|
||||
|
||||
dec_pkg_f.Close();
|
||||
}
|
||||
|
||||
rFile n_dec_pkg_f(decryptedFile, rFile::read);
|
||||
dec_pkg_f.seek(0);
|
||||
|
||||
std::vector<PKGEntry> m_entries;
|
||||
m_entries.resize(m_header->file_count);
|
||||
|
||||
PKGEntry *m_entries_ptr = &m_entries[0];
|
||||
if (!LoadEntries(n_dec_pkg_f, m_header, m_entries_ptr))
|
||||
auto m_entries_ptr = m_entries.data();
|
||||
|
||||
if (!LoadEntries(dec_pkg_f, m_header, m_entries_ptr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, unpacking...", m_entries.size(), 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
for (const PKGEntry& entry : m_entries)
|
||||
for (const auto& entry : m_entries)
|
||||
{
|
||||
UnpackEntry(n_dec_pkg_f, entry, dst + src + "/");
|
||||
UnpackEntry(dec_pkg_f, entry, dst + src + "/");
|
||||
pdlg.Update(pdlg.GetValue() + 1);
|
||||
}
|
||||
|
||||
pdlg.Update(m_entries.size());
|
||||
|
||||
n_dec_pkg_f.Close();
|
||||
wxRemoveFile(decryptedFile);
|
||||
dec_pkg_f.close();
|
||||
rRemoveFile(decryptedFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
// Constants
|
||||
#define PKG_HEADER_SIZE 0xC0 //sizeof(pkg_header) + sizeof(pkg_unk_checksum)
|
||||
#define PKG_RELEASE_TYPE_RELEASE 0x8000
|
||||
#define PKG_RELEASE_TYPE_DEBUG 0x0000
|
||||
#define PKG_PLATFORM_TYPE_PS3 0x0001
|
||||
#define PKG_PLATFORM_TYPE_PSP 0x0002
|
||||
enum
|
||||
{
|
||||
HASH_LEN = 16,
|
||||
BUF_SIZE = 4096,
|
||||
PKG_HEADER_SIZE = 0xC0, //sizeof(pkg_header) + sizeof(pkg_unk_checksum)
|
||||
};
|
||||
|
||||
#define PKG_FILE_ENTRY_NPDRM 0x0001
|
||||
#define PKG_FILE_ENTRY_NPDRMEDAT 0x0002
|
||||
#define PKG_FILE_ENTRY_REGULAR 0x0003
|
||||
#define PKG_FILE_ENTRY_FOLDER 0x0004
|
||||
#define PKG_FILE_ENTRY_SDAT 0x0009
|
||||
#define PKG_FILE_ENTRY_OVERWRITE 0x80000000
|
||||
enum : u16
|
||||
{
|
||||
PKG_RELEASE_TYPE_RELEASE = 0x8000,
|
||||
PKG_RELEASE_TYPE_DEBUG = 0x0000,
|
||||
|
||||
#define HASH_LEN 16
|
||||
#define BUF_SIZE 4096
|
||||
PKG_PLATFORM_TYPE_PS3 = 0x0001,
|
||||
PKG_PLATFORM_TYPE_PSP = 0x0002,
|
||||
};
|
||||
|
||||
enum : u32
|
||||
{
|
||||
PKG_FILE_ENTRY_NPDRM = 1,
|
||||
PKG_FILE_ENTRY_NPDRMEDAT = 2,
|
||||
PKG_FILE_ENTRY_REGULAR = 3,
|
||||
PKG_FILE_ENTRY_FOLDER = 4,
|
||||
PKG_FILE_ENTRY_SDAT = 9,
|
||||
|
||||
PKG_FILE_ENTRY_OVERWRITE = 0x80000000,
|
||||
};
|
||||
|
||||
// Structs
|
||||
struct PKGHeader
|
||||
|
|
@ -45,6 +56,6 @@ struct PKGEntry
|
|||
be_t<u32> pad; // Padding (zeros)
|
||||
};
|
||||
|
||||
class rFile;
|
||||
struct rfile_t;
|
||||
|
||||
extern int Unpack(rFile& dec_pkg_f, std::string src, std::string dst);
|
||||
int Unpack(const rfile_t& dec_pkg_f, std::string src, std::string dst);
|
||||
|
|
|
|||
|
|
@ -11,53 +11,56 @@
|
|||
#include <wx/zstream.h>
|
||||
|
||||
|
||||
void WriteEhdr(rFile& f, Elf64_Ehdr& ehdr)
|
||||
void WriteEhdr(const rfile_t& f, Elf64_Ehdr& ehdr)
|
||||
{
|
||||
Write32(f, ehdr.e_magic);
|
||||
Write8(f, ehdr.e_class);
|
||||
Write8(f, ehdr.e_data);
|
||||
Write8(f, ehdr.e_curver);
|
||||
Write8(f, ehdr.e_os_abi);
|
||||
Write64(f, ehdr.e_abi_ver);
|
||||
Write16(f, ehdr.e_type);
|
||||
Write16(f, ehdr.e_machine);
|
||||
Write32(f, ehdr.e_version);
|
||||
Write64(f, ehdr.e_entry);
|
||||
Write64(f, ehdr.e_phoff);
|
||||
Write64(f, ehdr.e_shoff);
|
||||
Write32(f, ehdr.e_flags);
|
||||
Write16(f, ehdr.e_ehsize);
|
||||
Write16(f, ehdr.e_phentsize);
|
||||
Write16(f, ehdr.e_phnum);
|
||||
Write16(f, ehdr.e_shentsize);
|
||||
Write16(f, ehdr.e_shnum);
|
||||
Write16(f, ehdr.e_shstrndx);
|
||||
Write32(f, ehdr.e_magic);
|
||||
Write8(f, ehdr.e_class);
|
||||
Write8(f, ehdr.e_data);
|
||||
Write8(f, ehdr.e_curver);
|
||||
Write8(f, ehdr.e_os_abi);
|
||||
Write64(f, ehdr.e_abi_ver);
|
||||
Write16(f, ehdr.e_type);
|
||||
Write16(f, ehdr.e_machine);
|
||||
Write32(f, ehdr.e_version);
|
||||
Write64(f, ehdr.e_entry);
|
||||
Write64(f, ehdr.e_phoff);
|
||||
Write64(f, ehdr.e_shoff);
|
||||
Write32(f, ehdr.e_flags);
|
||||
Write16(f, ehdr.e_ehsize);
|
||||
Write16(f, ehdr.e_phentsize);
|
||||
Write16(f, ehdr.e_phnum);
|
||||
Write16(f, ehdr.e_shentsize);
|
||||
Write16(f, ehdr.e_shnum);
|
||||
Write16(f, ehdr.e_shstrndx);
|
||||
}
|
||||
void WritePhdr(rFile& f, Elf64_Phdr& phdr)
|
||||
|
||||
void WritePhdr(const rfile_t& f, Elf64_Phdr& phdr)
|
||||
{
|
||||
Write32(f, phdr.p_type);
|
||||
Write32(f, phdr.p_flags);
|
||||
Write64(f, phdr.p_offset);
|
||||
Write64(f, phdr.p_vaddr);
|
||||
Write64(f, phdr.p_paddr);
|
||||
Write64(f, phdr.p_filesz);
|
||||
Write64(f, phdr.p_memsz);
|
||||
Write64(f, phdr.p_align);
|
||||
Write32(f, phdr.p_type);
|
||||
Write32(f, phdr.p_flags);
|
||||
Write64(f, phdr.p_offset);
|
||||
Write64(f, phdr.p_vaddr);
|
||||
Write64(f, phdr.p_paddr);
|
||||
Write64(f, phdr.p_filesz);
|
||||
Write64(f, phdr.p_memsz);
|
||||
Write64(f, phdr.p_align);
|
||||
}
|
||||
void WriteShdr(rFile& f, Elf64_Shdr& shdr)
|
||||
|
||||
void WriteShdr(const rfile_t& f, Elf64_Shdr& shdr)
|
||||
{
|
||||
Write32(f, shdr.sh_name);
|
||||
Write32(f, shdr.sh_type);
|
||||
Write64(f, shdr.sh_flags);
|
||||
Write64(f, shdr.sh_addr);
|
||||
Write64(f, shdr.sh_offset);
|
||||
Write64(f, shdr.sh_size);
|
||||
Write32(f, shdr.sh_link);
|
||||
Write32(f, shdr.sh_info);
|
||||
Write64(f, shdr.sh_addralign);
|
||||
Write64(f, shdr.sh_entsize);
|
||||
Write32(f, shdr.sh_name);
|
||||
Write32(f, shdr.sh_type);
|
||||
Write64(f, shdr.sh_flags);
|
||||
Write64(f, shdr.sh_addr);
|
||||
Write64(f, shdr.sh_offset);
|
||||
Write64(f, shdr.sh_size);
|
||||
Write32(f, shdr.sh_link);
|
||||
Write32(f, shdr.sh_info);
|
||||
Write64(f, shdr.sh_addralign);
|
||||
Write64(f, shdr.sh_entsize);
|
||||
}
|
||||
void WriteEhdr(rFile& f, Elf32_Ehdr& ehdr)
|
||||
|
||||
void WriteEhdr(const rfile_t& f, Elf32_Ehdr& ehdr)
|
||||
{
|
||||
Write32(f, ehdr.e_magic);
|
||||
Write8(f, ehdr.e_class);
|
||||
|
|
@ -79,7 +82,8 @@ void WriteEhdr(rFile& f, Elf32_Ehdr& ehdr)
|
|||
Write16(f, ehdr.e_shnum);
|
||||
Write16(f, ehdr.e_shstrndx);
|
||||
}
|
||||
void WritePhdr(rFile& f, Elf32_Phdr& phdr)
|
||||
|
||||
void WritePhdr(const rfile_t& f, Elf32_Phdr& phdr)
|
||||
{
|
||||
Write32(f, phdr.p_type);
|
||||
Write32(f, phdr.p_offset);
|
||||
|
|
@ -90,7 +94,8 @@ void WritePhdr(rFile& f, Elf32_Phdr& phdr)
|
|||
Write32(f, phdr.p_flags);
|
||||
Write32(f, phdr.p_align);
|
||||
}
|
||||
void WriteShdr(rFile& f, Elf32_Shdr& shdr)
|
||||
|
||||
void WriteShdr(const rfile_t& f, Elf32_Shdr& shdr)
|
||||
{
|
||||
Write32(f, shdr.sh_name);
|
||||
Write32(f, shdr.sh_type);
|
||||
|
|
@ -794,8 +799,8 @@ bool SELFDecrypter::DecryptData()
|
|||
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
||||
{
|
||||
// Create a new ELF file.
|
||||
rFile e(elf.c_str(), rFile::write);
|
||||
if(!e.IsOpened())
|
||||
rfile_t e(elf, o_write | o_create | o_trunc);
|
||||
if(!e)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
||||
return false;
|
||||
|
|
@ -819,8 +824,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
|||
if (meta_shdr[i].type == 2)
|
||||
{
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.Seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.Write(data_buf + data_buf_offset, meta_shdr[i].data_size);
|
||||
e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);
|
||||
|
||||
// Advance the data buffer offset by data size.
|
||||
data_buf_offset += meta_shdr[i].data_size;
|
||||
|
|
@ -830,7 +835,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
|||
// Write section headers.
|
||||
if(self_hdr.se_shdroff != 0)
|
||||
{
|
||||
e.Seek(elf32_hdr.e_shoff);
|
||||
e.seek(elf32_hdr.e_shoff);
|
||||
|
||||
for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
|
||||
WriteShdr(e, shdr32_arr[i]);
|
||||
|
|
@ -870,8 +875,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
|||
decomp_stream_out.CopyTo(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz);
|
||||
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.Seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.Write(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz);
|
||||
e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz);
|
||||
|
||||
// Release the decompression buffer.
|
||||
free(decomp_buf);
|
||||
|
|
@ -879,8 +884,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
|||
else
|
||||
{
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.Seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.Write(data_buf + data_buf_offset, meta_shdr[i].data_size);
|
||||
e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);
|
||||
}
|
||||
|
||||
// Advance the data buffer offset by data size.
|
||||
|
|
@ -891,14 +896,13 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
|||
// Write section headers.
|
||||
if(self_hdr.se_shdroff != 0)
|
||||
{
|
||||
e.Seek(elf64_hdr.e_shoff);
|
||||
e.seek(elf64_hdr.e_shoff);
|
||||
|
||||
for(u32 i = 0; i < elf64_hdr.e_shnum; ++i)
|
||||
WriteShdr(e, shdr64_arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
e.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -921,17 +925,16 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
|
|||
}
|
||||
|
||||
// Open the RAP file and read the key.
|
||||
rFile rap_file(rap_path, rFile::read);
|
||||
rfile_t rap_file(rap_path);
|
||||
|
||||
if (!rap_file.IsOpened())
|
||||
if (!rap_file)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to load RAP file!");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_NOTICE(LOADER, "Loading RAP file %s", (ci_str + ".rap").c_str());
|
||||
rap_file.Read(rap_key, 0x10);
|
||||
rap_file.Close();
|
||||
LOG_NOTICE(LOADER, "Loading RAP file %s.rap", ci_str);
|
||||
rap_file.read(rap_key, 0x10);
|
||||
|
||||
// Convert the RAP key.
|
||||
rap_to_rif(rap_key, npdrm_key);
|
||||
|
|
@ -975,18 +978,18 @@ bool IsSelfElf32(const std::string& path)
|
|||
bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
||||
{
|
||||
// Open the SELF file.
|
||||
rFile s(self);
|
||||
rfile_t s(self);
|
||||
|
||||
if(!s.IsOpened())
|
||||
if(!s)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Could not open SELF file! (%s)", self.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the key version.
|
||||
s.Seek(0x08);
|
||||
s.seek(0x08);
|
||||
u16 key_version;
|
||||
s.Read(&key_version, sizeof(key_version));
|
||||
s.read(&key_version, sizeof(key_version));
|
||||
|
||||
// Check for DEBUG version.
|
||||
if(swap16(key_version) == 0x8000)
|
||||
|
|
@ -994,17 +997,17 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
|||
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
|
||||
|
||||
// Get the real elf offset.
|
||||
s.Seek(0x10);
|
||||
s.seek(0x10);
|
||||
u64 elf_offset;
|
||||
s.Read(&elf_offset, sizeof(elf_offset));
|
||||
s.read(&elf_offset, sizeof(elf_offset));
|
||||
|
||||
// Start at the real elf offset.
|
||||
elf_offset = swap64(elf_offset);
|
||||
s.Seek(elf_offset);
|
||||
s.seek(elf_offset);
|
||||
|
||||
// Write the real ELF file back.
|
||||
rFile e(elf, rFile::write);
|
||||
if(!e.IsOpened())
|
||||
rfile_t e(elf, o_write | o_create | o_trunc);
|
||||
if(!e)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
||||
return false;
|
||||
|
|
@ -1012,18 +1015,14 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
|||
|
||||
// Copy the data.
|
||||
char buf[2048];
|
||||
while (ssize_t size = s.Read(buf, 2048))
|
||||
e.Write(buf, size);
|
||||
while (ssize_t size = s.read(buf, 2048))
|
||||
e.write(buf, size);
|
||||
|
||||
e.Close();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave the file untouched.
|
||||
s.Seek(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leave the file untouched.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DecryptSelf(const std::string& elf, const std::string& self)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue