wxFile removed (rFile -> rfile_t)

This commit is contained in:
Nekotekina 2015-04-19 16:19:24 +03:00
parent 2cafa84b75
commit ab405901ee
43 changed files with 814 additions and 973 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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)