Partial commit: Crypto

This commit is contained in:
Nekotekina 2016-02-02 00:52:27 +03:00
parent edd0965c1a
commit b85fc50854
13 changed files with 133 additions and 183 deletions

View File

@ -29,7 +29,6 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/ */
#include "stdafx.h"
#include "aes.h" #include "aes.h"
/* /*
@ -972,4 +971,4 @@ void aes_cmac(aes_context *ctx, int length, unsigned char *input, unsigned char
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
output[i] = X[i]; output[i] = X[i];
} }

View File

@ -2,7 +2,6 @@
// Licensed under the terms of the GNU GPL, version 2 // Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include "stdafx.h"
#include "utils.h" #include "utils.h"
void bn_print(char *name, u8 *a, u32 n) void bn_print(char *name, u8 *a, u32 n)
@ -545,4 +544,4 @@ int ecdsa_verify(u8 *hash, u8 *R, u8 *S)
void ecdsa_sign(u8 *hash, u8 *R, u8 *S) void ecdsa_sign(u8 *hash, u8 *R, u8 *S)
{ {
generate_ecdsa(R, S, ec_k, hash); generate_ecdsa(R, S, ec_k, hash);
} }

View File

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "utils.h" #include "utils.h"
#include "aes.h" #include "aes.h"
#include "key_vault.h" #include "key_vault.h"

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <string>
#include <vector>
enum SELF_KEY_TYPE { enum SELF_KEY_TYPE {
KEY_LV0 = 1, KEY_LV0 = 1,
KEY_LV1, KEY_LV1,

View File

@ -281,4 +281,4 @@ int decompress(unsigned char *out, unsigned char *in, unsigned int size)
} }
delete[] tmp; delete[] tmp;
return result; return result;
} }

View File

@ -12,4 +12,4 @@ void decode_range(unsigned int *range, unsigned int *code, unsigned char **src);
int decode_bit(unsigned int *range, unsigned int *code, int *index, unsigned char **src, unsigned char *c); int decode_bit(unsigned int *range, unsigned int *code, int *index, unsigned char **src, unsigned char *c);
int decode_number(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src); int decode_number(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src);
int decode_word(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src); int decode_word(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src);
int decompress(unsigned char *out, unsigned char *in, unsigned int size); int decompress(unsigned char *out, unsigned char *in, unsigned int size);

View File

@ -28,7 +28,6 @@
* http://www.itl.nist.gov/fipspubs/fip180-1.htm * http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/ */
#include "stdafx.h"
#include "sha1.h" #include "sha1.h"
/* /*
@ -394,4 +393,4 @@ void sha1_hmac( const unsigned char *key, size_t keylen,
sha1_hmac_finish( &ctx, output ); sha1_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) ); memset( &ctx, 0, sizeof( sha1_context ) );
} }

View File

@ -170,7 +170,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
{ {
metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size; metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size;
CHECK_ASSERTION(in->seek(metadata_sec_offset) != -1); in->seek(metadata_sec_offset);
unsigned char metadata[0x20]; unsigned char metadata[0x20];
memset(metadata, 0, 0x20); memset(metadata, 0, 0x20);
@ -199,7 +199,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
{ {
// If FLAG 0x20, the metadata precedes each data block. // If FLAG 0x20, the metadata precedes each data block.
metadata_sec_offset = metadata_offset + (unsigned long long) i * (metadata_section_size + length); metadata_sec_offset = metadata_offset + (unsigned long long) i * (metadata_section_size + length);
CHECK_ASSERTION(in->seek(metadata_sec_offset) != -1); in->seek(metadata_sec_offset);
unsigned char metadata[0x20]; unsigned char metadata[0x20];
memset(metadata, 0, 0x20); memset(metadata, 0, 0x20);
@ -220,7 +220,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
else else
{ {
metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size; metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size;
CHECK_ASSERTION(in->seek(metadata_sec_offset) != -1); 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; offset = metadata_offset + (unsigned long long) i * edat->block_size + (unsigned long long) block_num * metadata_section_size;
@ -242,8 +242,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
memset(hash, 0, 0x10); memset(hash, 0, 0x10);
memset(key_result, 0, 0x10); memset(key_result, 0, 0x10);
CHECK_ASSERTION(in->seek(offset) != -1); in->seek(offset);
in->read(enc_data, length); in->read(enc_data, length);
// Generate a key for the current block. // Generate a key for the current block.
@ -347,7 +346,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs::file* f, bool verbose) int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs::file* f, bool verbose)
{ {
CHECK_ASSERTION(f->seek(0) != -1); f->seek(0);
unsigned char header[0xA0]; unsigned char header[0xA0];
unsigned char empty_header[0xA0]; unsigned char empty_header[0xA0];
unsigned char header_hash[0x10]; unsigned char header_hash[0x10];
@ -392,8 +391,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
f->read(header, 0xA0); f->read(header, 0xA0);
// Read in the header and metadata section hashes. // Read in the header and metadata section hashes.
CHECK_ASSERTION(f->seek(0x90) != -1); f->seek(0x90);
f->read(metadata_hash, 0x10); f->read(metadata_hash, 0x10);
f->read(header_hash, 0x10); f->read(header_hash, 0x10);
@ -449,7 +447,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
while (bytes_to_read > 0) while (bytes_to_read > 0)
{ {
// Locate the metadata blocks. // Locate the metadata blocks.
CHECK_ASSERTION(f->seek(metadata_section_offset) != -1); f->seek(metadata_section_offset);
// Read in the metadata. // Read in the metadata.
f->read(metadata + bytes_read, metadata_section_size); f->read(metadata + bytes_read, metadata_section_size);
@ -496,9 +494,9 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
// Read in the metadata and header signatures. // Read in the metadata and header signatures.
CHECK_ASSERTION(f->seek(0xB0) != -1); f->seek(0xB0);
f->read(metadata_signature, 0x28); f->read(metadata_signature, 0x28);
CHECK_ASSERTION(f->seek(0xD8) != -1); f->seek(0xD8);
f->read(header_signature, 0x28); f->read(header_signature, 0x28);
// Checking metadata signature. // Checking metadata signature.
@ -514,7 +512,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
{ {
int metadata_buf_size = block_num * 0x10; int metadata_buf_size = block_num * 0x10;
unsigned char *metadata_buf = new unsigned char[metadata_buf_size]; unsigned char *metadata_buf = new unsigned char[metadata_buf_size];
CHECK_ASSERTION(f->seek(metadata_offset) != -1); f->seek(metadata_offset);
f->read(metadata_buf, metadata_buf_size); f->read(metadata_buf, metadata_buf_size);
sha1(metadata_buf, metadata_buf_size, signature_hash); sha1(metadata_buf, metadata_buf_size, signature_hash);
delete[] metadata_buf; delete[] metadata_buf;
@ -547,7 +545,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
// Setup header signature hash. // Setup header signature hash.
memset(signature_hash, 0, 20); memset(signature_hash, 0, 20);
unsigned char *header_buf = new unsigned char[0xD8]; unsigned char *header_buf = new unsigned char[0xD8];
CHECK_ASSERTION(f->seek(0x00) != -1); f->seek(0x00);
f->read(header_buf, 0xD8); f->read(header_buf, 0xD8);
sha1(header_buf, 0xD8, signature_hash ); sha1(header_buf, 0xD8, signature_hash );
delete[] header_buf; delete[] header_buf;
@ -819,7 +817,7 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
{ {
// Prepare the files. // Prepare the files.
fs::file input(input_file_name); fs::file input(input_file_name);
fs::file output(output_file_name, fom::rewrite); fs::file output(output_file_name, fs::rewrite);
// Set keys (RIF and DEVKLIC). // Set keys (RIF and DEVKLIC).
unsigned char rifkey[0x10]; unsigned char rifkey[0x10];
@ -893,7 +891,7 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
// Delete the bad output file if any errors arise. // Delete the bad output file if any errors arise.
if (extract_data(&input, &output, input_file_name.c_str(), devklic, rifkey, verbose)) if (extract_data(&input, &output, input_file_name.c_str(), devklic, rifkey, verbose))
{ {
output.close(); output.release();
fs::remove_file(output_file_name); fs::remove_file(output_file_name);
return -1; return -1;
} }

View File

@ -62,12 +62,12 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& pr
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
// Save current file offset (probably zero) // Save current file offset (probably zero)
const u64 start_offset = pkg_f.seek(0, fs::seek_cur); const u64 start_offset = pkg_f.pos();
// Get basic PKG information // Get basic PKG information
PKGHeader header; PKGHeader header;
if (pkg_f.read(&header, sizeof(PKGHeader)) != sizeof(PKGHeader)) if (!pkg_f.read(header))
{ {
LOG_ERROR(LOADER, "PKG: Package file is too short!"); LOG_ERROR(LOADER, "PKG: Package file is too short!");
return false; return false;
@ -84,7 +84,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& pr
// Define decryption subfunction (`psp` arg selects the key for specific block) // Define decryption subfunction (`psp` arg selects the key for specific block)
auto decrypt = [&](u64 offset, u64 size, bool psp) -> u64 auto decrypt = [&](u64 offset, u64 size, bool psp) -> u64
{ {
CHECK_ASSERTION(pkg_f.seek(start_offset + header.data_offset + offset) != -1); pkg_f.seek(start_offset + header.data_offset + offset);
// Read the data and set available size // Read the data and set available size
const u64 read = pkg_f.read(buf.get(), size); const u64 read = pkg_f.read(buf.get(), size);
@ -175,7 +175,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& pr
const bool did_overwrite = fs::is_file(path); const bool did_overwrite = fs::is_file(path);
if (fs::file out{ path, fom::write | fom::create | fom::trunc }) if (fs::file out{ path, fs::rewrite })
{ {
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE) for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
{ {

View File

@ -2,131 +2,90 @@
#include "aes.h" #include "aes.h"
#include "sha1.h" #include "sha1.h"
#include "utils.h" #include "utils.h"
#include "Emu/FS/vfsLocalFile.h"
#include "unself.h" #include "unself.h"
#pragma warning(push)
#pragma message("TODO: remove wx dependencies: See comment below.")
#pragma warning(disable : 4996)
// TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions? // TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions?
#include <zlib.h> #include <zlib.h>
#pragma warning(pop) force_inline u8 Read8(const fs::file& f)
force_inline u8 Read8(vfsStream& f)
{ {
u8 ret; u8 ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u16 Read16(vfsStream& f) force_inline u16 Read16(const fs::file& f)
{ {
be_t<u16> ret; be_t<u16> ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u32 Read32(vfsStream& f) force_inline u32 Read32(const fs::file& f)
{ {
be_t<u32> ret; be_t<u32> ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u64 Read64(vfsStream& f) force_inline u64 Read64(const fs::file& f)
{ {
be_t<u64> ret; be_t<u64> ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u16 Read16LE(vfsStream& f) force_inline u16 Read16LE(const fs::file& f)
{ {
u16 ret; u16 ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u32 Read32LE(vfsStream& f) force_inline u32 Read32LE(const fs::file& f)
{ {
u32 ret; u32 ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline u64 Read64LE(vfsStream& f) force_inline u64 Read64LE(const fs::file& f)
{ {
u64 ret; u64 ret;
f.Read(&ret, sizeof(ret)); f.read(&ret, sizeof(ret));
return ret; return ret;
} }
force_inline void Write8(vfsStream& f, const u8 data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write8(const fs::file& f, const u8 data) force_inline void Write8(const fs::file& f, const u8 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write16LE(vfsStream& f, const u16 data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write16LE(const fs::file& f, const u16 data) force_inline void Write16LE(const fs::file& f, const u16 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write32LE(vfsStream& f, const u32 data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write32LE(const fs::file& f, const u32 data) force_inline void Write32LE(const fs::file& f, const u32 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write64LE(vfsStream& f, const u64 data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write64LE(const fs::file& f, const u64 data) force_inline void Write64LE(const fs::file& f, const u64 data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write16(vfsStream& f, const be_t<u16> data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write16(const fs::file& f, const be_t<u16> data) force_inline void Write16(const fs::file& f, const be_t<u16> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write32(vfsStream& f, const be_t<u32> data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write32(const fs::file& f, const be_t<u32> data) force_inline void Write32(const fs::file& f, const be_t<u32> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
} }
force_inline void Write64(vfsStream& f, const be_t<u64> data)
{
f.Write(&data, sizeof(data));
}
force_inline void Write64(const fs::file& f, const be_t<u64> data) force_inline void Write64(const fs::file& f, const be_t<u64> data)
{ {
f.write(&data, sizeof(data)); f.write(&data, sizeof(data));
@ -231,7 +190,7 @@ void WriteShdr(const fs::file& f, Elf32_Shdr& shdr)
} }
void AppInfo::Load(vfsStream& f) void AppInfo::Load(const fs::file& f)
{ {
authid = Read64(f); authid = Read64(f);
vendor_id = Read32(f); vendor_id = Read32(f);
@ -248,7 +207,7 @@ void AppInfo::Show()
LOG_NOTICE(LOADER, "Version: 0x%llx", version); LOG_NOTICE(LOADER, "Version: 0x%llx", version);
} }
void SectionInfo::Load(vfsStream& f) void SectionInfo::Load(const fs::file& f)
{ {
offset = Read64(f); offset = Read64(f);
size = Read64(f); size = Read64(f);
@ -268,7 +227,7 @@ void SectionInfo::Show()
LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted); LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted);
} }
void SCEVersionInfo::Load(vfsStream& f) void SCEVersionInfo::Load(const fs::file& f)
{ {
subheader_type = Read32(f); subheader_type = Read32(f);
present = Read32(f); present = Read32(f);
@ -284,7 +243,7 @@ void SCEVersionInfo::Show()
LOG_NOTICE(LOADER, "Unknown: 0x%08x", unknown); LOG_NOTICE(LOADER, "Unknown: 0x%08x", unknown);
} }
void ControlInfo::Load(vfsStream& f) void ControlInfo::Load(const fs::file& f)
{ {
type = Read32(f); type = Read32(f);
size = Read32(f); size = Read32(f);
@ -305,13 +264,13 @@ void ControlInfo::Load(vfsStream& f)
{ {
if (size == 0x30) if (size == 0x30)
{ {
f.Read(file_digest_30.digest, 20); f.read(file_digest_30.digest, 20);
file_digest_30.unknown = Read64(f); file_digest_30.unknown = Read64(f);
} }
else if (size == 0x40) else if (size == 0x40)
{ {
f.Read(file_digest_40.digest1, 20); f.read(file_digest_40.digest1, 20);
f.Read(file_digest_40.digest2, 20); f.read(file_digest_40.digest2, 20);
file_digest_40.unknown = Read64(f); file_digest_40.unknown = Read64(f);
} }
} }
@ -321,10 +280,10 @@ void ControlInfo::Load(vfsStream& f)
npdrm.unknown1 = Read32(f); npdrm.unknown1 = Read32(f);
npdrm.license = Read32(f); npdrm.license = Read32(f);
npdrm.type = Read32(f); npdrm.type = Read32(f);
f.Read(npdrm.content_id, 48); f.read(npdrm.content_id, 48);
f.Read(npdrm.digest, 16); f.read(npdrm.digest, 16);
f.Read(npdrm.invdigest, 16); f.read(npdrm.invdigest, 16);
f.Read(npdrm.xordigest, 16); f.read(npdrm.xordigest, 16);
npdrm.unknown2 = Read64(f); npdrm.unknown2 = Read64(f);
npdrm.unknown3 = Read64(f); npdrm.unknown3 = Read64(f);
} }
@ -500,14 +459,14 @@ void MetadataSectionHeader::Show()
LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed); LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed);
} }
void SectionHash::Load(vfsStream& f) void SectionHash::Load(const fs::file& f)
{ {
f.Read(sha1, 20); f.read(sha1, 20);
f.Read(padding, 12); f.read(padding, 12);
f.Read(hmac_key, 64); f.read(hmac_key, 64);
} }
void CapabilitiesInfo::Load(vfsStream& f) void CapabilitiesInfo::Load(const fs::file& f)
{ {
type = Read32(f); type = Read32(f);
capabilities_size = Read32(f); capabilities_size = Read32(f);
@ -520,21 +479,21 @@ void CapabilitiesInfo::Load(vfsStream& f)
unknown5 = Read32(f); unknown5 = Read32(f);
} }
void Signature::Load(vfsStream& f) void Signature::Load(const fs::file& f)
{ {
f.Read(r, 21); f.read(r, 21);
f.Read(s, 21); f.read(s, 21);
f.Read(padding, 6); f.read(padding, 6);
} }
void SelfSection::Load(vfsStream& f) void SelfSection::Load(const fs::file& f)
{ {
*data = Read32(f); *data = Read32(f);
size = Read64(f); size = Read64(f);
offset = Read64(f); offset = Read64(f);
} }
void Elf32_Ehdr::Load(vfsStream& f) void Elf32_Ehdr::Load(const fs::file& f)
{ {
e_magic = Read32(f); e_magic = Read32(f);
e_class = Read8(f); e_class = Read8(f);
@ -578,7 +537,7 @@ void Elf32_Ehdr::Load(vfsStream& f)
} }
} }
void Elf32_Shdr::Load(vfsStream& f) void Elf32_Shdr::Load(const fs::file& f)
{ {
sh_name = Read32(f); sh_name = Read32(f);
sh_type = Read32(f); sh_type = Read32(f);
@ -592,12 +551,12 @@ void Elf32_Shdr::Load(vfsStream& f)
sh_entsize = Read32(f); sh_entsize = Read32(f);
} }
void Elf32_Shdr::LoadLE(vfsStream& f) void Elf32_Shdr::LoadLE(const fs::file& f)
{ {
f.Read(this, sizeof(*this)); f.read(this, sizeof(*this));
} }
void Elf32_Phdr::Load(vfsStream& f) void Elf32_Phdr::Load(const fs::file& f)
{ {
p_type = Read32(f); p_type = Read32(f);
p_offset = Read32(f); p_offset = Read32(f);
@ -609,12 +568,12 @@ void Elf32_Phdr::Load(vfsStream& f)
p_align = Read32(f); p_align = Read32(f);
} }
void Elf32_Phdr::LoadLE(vfsStream& f) void Elf32_Phdr::LoadLE(const fs::file& f)
{ {
f.Read(this, sizeof(*this)); f.read(this, sizeof(*this));
} }
void Elf64_Ehdr::Load(vfsStream& f) void Elf64_Ehdr::Load(const fs::file& f)
{ {
e_magic = Read32(f); e_magic = Read32(f);
e_class = Read8(f); e_class = Read8(f);
@ -637,7 +596,7 @@ void Elf64_Ehdr::Load(vfsStream& f)
e_shstrndx = Read16(f); e_shstrndx = Read16(f);
} }
void Elf64_Shdr::Load(vfsStream& f) void Elf64_Shdr::Load(const fs::file& f)
{ {
sh_name = Read32(f); sh_name = Read32(f);
sh_type = Read32(f); sh_type = Read32(f);
@ -651,7 +610,7 @@ void Elf64_Shdr::Load(vfsStream& f)
sh_entsize = Read64(f); sh_entsize = Read64(f);
} }
void Elf64_Phdr::Load(vfsStream& f) void Elf64_Phdr::Load(const fs::file& f)
{ {
p_type = Read32(f); p_type = Read32(f);
p_flags = Read32(f); p_flags = Read32(f);
@ -663,7 +622,7 @@ void Elf64_Phdr::Load(vfsStream& f)
p_align = Read64(f); p_align = Read64(f);
} }
void SceHeader::Load(vfsStream& f) void SceHeader::Load(const fs::file& f)
{ {
se_magic = Read32(f); se_magic = Read32(f);
se_hver = Read32(f); se_hver = Read32(f);
@ -674,7 +633,7 @@ void SceHeader::Load(vfsStream& f)
se_esize = Read64(f); se_esize = Read64(f);
} }
void SelfHeader::Load(vfsStream& f) void SelfHeader::Load(const fs::file& f)
{ {
se_htype = Read64(f); se_htype = Read64(f);
se_appinfooff = Read64(f); se_appinfooff = Read64(f);
@ -688,7 +647,7 @@ void SelfHeader::Load(vfsStream& f)
pad = Read64(f); pad = Read64(f);
} }
SELFDecrypter::SELFDecrypter(vfsStream& s) SELFDecrypter::SELFDecrypter(const fs::file& s)
: self_f(s) : self_f(s)
, key_v() , key_v()
, data_buf_length(0) , data_buf_length(0)
@ -698,7 +657,7 @@ SELFDecrypter::SELFDecrypter(vfsStream& s)
bool SELFDecrypter::LoadHeaders(bool isElf32) bool SELFDecrypter::LoadHeaders(bool isElf32)
{ {
// Read SCE header. // Read SCE header.
CHECK_ASSERTION(self_f.Seek(0) != -1); self_f.seek(0);
sce_hdr.Load(self_f); sce_hdr.Load(self_f);
// Check SCE magic. // Check SCE magic.
@ -712,11 +671,11 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
self_hdr.Load(self_f); self_hdr.Load(self_f);
// Read the APP INFO. // Read the APP INFO.
CHECK_ASSERTION(self_f.Seek(self_hdr.se_appinfooff) != -1); self_f.seek(self_hdr.se_appinfooff);
app_info.Load(self_f); app_info.Load(self_f);
// Read ELF header. // Read ELF header.
CHECK_ASSERTION(self_f.Seek(self_hdr.se_elfoff) != -1); self_f.seek(self_hdr.se_elfoff);
if (isElf32) if (isElf32)
elf32_hdr.Load(self_f); elf32_hdr.Load(self_f);
@ -732,7 +691,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
LOG_ERROR(LOADER, "SELF: ELF program header offset is null!"); LOG_ERROR(LOADER, "SELF: ELF program header offset is null!");
return false; return false;
} }
self_f.Seek(self_hdr.se_phdroff); self_f.seek(self_hdr.se_phdroff);
for(u32 i = 0; i < elf32_hdr.e_phnum; ++i) for(u32 i = 0; i < elf32_hdr.e_phnum; ++i)
{ {
phdr32_arr.emplace_back(); phdr32_arr.emplace_back();
@ -749,7 +708,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
return false; return false;
} }
CHECK_ASSERTION(self_f.Seek(self_hdr.se_phdroff) != -1); self_f.seek(self_hdr.se_phdroff);
for (u32 i = 0; i < elf64_hdr.e_phnum; ++i) for (u32 i = 0; i < elf64_hdr.e_phnum; ++i)
{ {
@ -761,7 +720,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
// Read section info. // Read section info.
secinfo_arr.clear(); secinfo_arr.clear();
CHECK_ASSERTION(self_f.Seek(self_hdr.se_secinfoff) != -1); self_f.seek(self_hdr.se_secinfoff);
for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i) for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i)
{ {
@ -770,12 +729,12 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
} }
// Read SCE version info. // Read SCE version info.
CHECK_ASSERTION(self_f.Seek(self_hdr.se_sceveroff) != -1); self_f.seek(self_hdr.se_sceveroff);
scev_info.Load(self_f); scev_info.Load(self_f);
// Read control info. // Read control info.
ctrlinfo_arr.clear(); ctrlinfo_arr.clear();
CHECK_ASSERTION(self_f.Seek(self_hdr.se_controloff) != -1); self_f.seek(self_hdr.se_controloff);
u32 i = 0; u32 i = 0;
while(i < self_hdr.se_controlsize) while(i < self_hdr.se_controlsize)
@ -797,7 +756,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
return true; return true;
} }
CHECK_ASSERTION(self_f.Seek(self_hdr.se_shdroff) != -1); self_f.seek(self_hdr.se_shdroff);
for(u32 i = 0; i < elf32_hdr.e_shnum; ++i) for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{ {
@ -814,7 +773,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
return true; return true;
} }
CHECK_ASSERTION(self_f.Seek(self_hdr.se_shdroff) != -1); self_f.seek(self_hdr.se_shdroff);
for(u32 i = 0; i < elf64_hdr.e_shnum; ++i) for(u32 i = 0; i < elf64_hdr.e_shnum; ++i)
{ {
@ -950,12 +909,12 @@ bool SELFDecrypter::LoadMetadata()
u8 *metadata_headers = (u8 *)malloc(metadata_headers_size); u8 *metadata_headers = (u8 *)malloc(metadata_headers_size);
// Locate and read the encrypted metadata info. // Locate and read the encrypted metadata info.
CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr)) != -1); self_f.seek(sce_hdr.se_meta + sizeof(sce_hdr));
self_f.Read(metadata_info, metadata_info_size); self_f.read(metadata_info, metadata_info_size);
// Locate and read the encrypted metadata header and section header. // Locate and read the encrypted metadata header and section header.
CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr) + metadata_info_size) != -1); self_f.seek(sce_hdr.se_meta + sizeof(sce_hdr) + metadata_info_size);
self_f.Read(metadata_headers, metadata_headers_size); self_f.read(metadata_headers, metadata_headers_size);
// Find the right keyset from the key vault. // Find the right keyset from the key vault.
SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version); SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version);
@ -1057,8 +1016,8 @@ bool SELFDecrypter::DecryptData()
u8 *buf = (u8 *)malloc(meta_shdr[i].data_size); u8 *buf = (u8 *)malloc(meta_shdr[i].data_size);
// Seek to the section data offset and read the encrypted data. // Seek to the section data offset and read the encrypted data.
CHECK_ASSERTION(self_f.Seek(meta_shdr[i].data_offset) != -1); self_f.seek(meta_shdr[i].data_offset);
self_f.Read(buf, meta_shdr[i].data_size); self_f.read(buf, meta_shdr[i].data_size);
// Zero out our ctr nonce. // Zero out our ctr nonce.
memset(ctr_stream_block, 0, sizeof(ctr_stream_block)); memset(ctr_stream_block, 0, sizeof(ctr_stream_block));
@ -1085,7 +1044,7 @@ bool SELFDecrypter::DecryptData()
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
{ {
// Create a new ELF file. // Create a new ELF file.
fs::file e(elf, fom::rewrite); fs::file e(elf, fs::rewrite);
if(!e) if(!e)
{ {
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str()); LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
@ -1112,8 +1071,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
if (meta_shdr[i].type == 2) if (meta_shdr[i].type == 2)
{ {
// Seek to the program header data offset and write the data. // Seek to the program header data offset and write the data.
CHECK_ASSERTION(e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset) != -1); e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
e.write(data_buf + data_buf_offset, meta_shdr[i].data_size); e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);
// Advance the data buffer offset by data size. // Advance the data buffer offset by data size.
@ -1124,7 +1082,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
// Write section headers. // Write section headers.
if (self_hdr.se_shdroff != 0) if (self_hdr.se_shdroff != 0)
{ {
CHECK_ASSERTION(e.seek(elf32_hdr.e_shoff) != -1); e.seek(elf32_hdr.e_shoff);
for (u32 i = 0; i < elf32_hdr.e_shnum; ++i) for (u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{ {
@ -1180,15 +1138,13 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
} }
// Seek to the program header data offset and write the data. // Seek to the program header data offset and write the data.
CHECK_ASSERTION(e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset) != -1); e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
e.write(decomp_buf.get(), phdr64_arr[meta_shdr[i].program_idx].p_filesz); e.write(decomp_buf.get(), phdr64_arr[meta_shdr[i].program_idx].p_filesz);
} }
else else
{ {
// Seek to the program header data offset and write the data. // Seek to the program header data offset and write the data.
CHECK_ASSERTION(e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset) != -1); e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
e.write(data_buf + data_buf_offset, meta_shdr[i].data_size); e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);
} }
@ -1200,7 +1156,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
// Write section headers. // Write section headers.
if (self_hdr.se_shdroff != 0) if (self_hdr.se_shdroff != 0)
{ {
CHECK_ASSERTION(e.seek(elf64_hdr.e_shoff) != -1); e.seek(elf64_hdr.e_shoff);
for (u32 i = 0; i < elf64_hdr.e_shnum; ++i) for (u32 i = 0; i < elf64_hdr.e_shnum; ++i)
{ {
@ -1250,10 +1206,9 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
bool IsSelf(const std::string& path) bool IsSelf(const std::string& path)
{ {
vfsLocalFile f(nullptr); fs::file f(path);
if(!f.Open(path)) if (!f) return false;
return false;
SceHeader hdr; SceHeader hdr;
hdr.Load(f); hdr.Load(f);
@ -1263,10 +1218,9 @@ bool IsSelf(const std::string& path)
bool IsSelfElf32(const std::string& path) bool IsSelfElf32(const std::string& path)
{ {
vfsLocalFile f(nullptr); fs::file f(path);
if(!f.Open(path)) if (!f) return false;
return false;
SceHeader hdr; SceHeader hdr;
SelfHeader sh; SelfHeader sh;
@ -1276,9 +1230,8 @@ bool IsSelfElf32(const std::string& path)
// Locate the class byte and check it. // Locate the class byte and check it.
u8 elf_class[0x8]; u8 elf_class[0x8];
CHECK_ASSERTION(f.Seek(sh.se_elfoff) != -1); f.seek(sh.se_elfoff);
f.read(elf_class, 0x8);
f.Read(elf_class, 0x8);
return (elf_class[4] == 1); return (elf_class[4] == 1);
} }
@ -1295,7 +1248,7 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
} }
// Get the key version. // Get the key version.
CHECK_ASSERTION(s.seek(0x08) != -1); s.seek(0x08);
u16 key_version; u16 key_version;
s.read(&key_version, sizeof(key_version)); s.read(&key_version, sizeof(key_version));
@ -1306,7 +1259,7 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header..."); LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
// Get the real elf offset. // Get the real elf offset.
CHECK_ASSERTION(s.seek(0x10) != -1); s.seek(0x10);
u64 elf_offset; u64 elf_offset;
s.read(&elf_offset, sizeof(elf_offset)); s.read(&elf_offset, sizeof(elf_offset));
@ -1314,10 +1267,10 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
// Start at the real elf offset. // Start at the real elf offset.
elf_offset = swap64(elf_offset); elf_offset = swap64(elf_offset);
CHECK_ASSERTION(s.seek(elf_offset) != -1); s.seek(elf_offset);
// Write the real ELF file back. // Write the real ELF file back.
fs::file e(elf, fom::rewrite); fs::file e(elf, fs::rewrite);
if (!e) if (!e)
{ {
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str()); LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
@ -1326,7 +1279,7 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
// Copy the data. // Copy the data.
char buf[2048]; char buf[2048];
while (u64 size = s.read(buf, 2048)) // read returns u64. while (u64 size = s.read(buf, 2048))
{ {
e.write(buf, size); e.write(buf, size);
} }
@ -1346,9 +1299,9 @@ bool DecryptSelf(const std::string& elf, const std::string& self)
if (!CheckDebugSelf(self, elf)) if (!CheckDebugSelf(self, elf))
{ {
// Set a virtual pointer to the SELF file. // Set a virtual pointer to the SELF file.
vfsLocalFile self_vf(nullptr); fs::file self_vf(self);
if (!self_vf.Open(self)) if (!self_vf)
return false; return false;
// Check the ELF file class (32 or 64 bit). // Check the ELF file class (32 or 64 bit).

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "key_vault.h"
struct vfsStream; #include "key_vault.h"
struct AppInfo struct AppInfo
{ {
@ -11,7 +10,7 @@ struct AppInfo
u64 version; u64 version;
u64 padding; u64 padding;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(); void Show();
}; };
@ -24,7 +23,7 @@ struct SectionInfo
u32 unknown2; u32 unknown2;
u32 encrypted; u32 encrypted;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(); void Show();
}; };
@ -35,7 +34,7 @@ struct SCEVersionInfo
u32 size; u32 size;
u32 unknown; u32 unknown;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(); void Show();
}; };
@ -95,7 +94,7 @@ struct ControlInfo
} npdrm; } npdrm;
}; };
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(); void Show();
}; };
@ -148,7 +147,7 @@ struct SectionHash
u8 padding[12]; u8 padding[12];
u8 hmac_key[64]; u8 hmac_key[64];
void Load(vfsStream& f); void Load(const fs::file& f);
}; };
struct CapabilitiesInfo struct CapabilitiesInfo
@ -163,7 +162,7 @@ struct CapabilitiesInfo
u32 unknown4; u32 unknown4;
u32 unknown5; u32 unknown5;
void Load(vfsStream& f); void Load(const fs::file& f);
}; };
struct Signature struct Signature
@ -172,7 +171,7 @@ struct Signature
u8 s[21]; u8 s[21];
u8 padding[6]; u8 padding[6];
void Load(vfsStream& f); void Load(const fs::file& f);
}; };
struct SelfSection struct SelfSection
@ -181,7 +180,7 @@ struct SelfSection
u64 size; u64 size;
u64 offset; u64 offset;
void Load(vfsStream& f); void Load(const fs::file& f);
}; };
struct Elf32_Ehdr struct Elf32_Ehdr
@ -206,7 +205,7 @@ struct Elf32_Ehdr
u16 e_shnum; u16 e_shnum;
u16 e_shstrndx; u16 e_shstrndx;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show() {} void Show() {}
bool IsLittleEndian() const { return e_data == 1; } bool IsLittleEndian() const { return e_data == 1; }
bool CheckMagic() const { return e_magic == 0x7F454C46; } bool CheckMagic() const { return e_magic == 0x7F454C46; }
@ -226,8 +225,8 @@ struct Elf32_Shdr
u32 sh_addralign; u32 sh_addralign;
u32 sh_entsize; u32 sh_entsize;
void Load(vfsStream& f); void Load(const fs::file& f);
void LoadLE(vfsStream& f); void LoadLE(const fs::file& f);
void Show() {} void Show() {}
}; };
@ -242,8 +241,8 @@ struct Elf32_Phdr
u32 p_flags; u32 p_flags;
u32 p_align; u32 p_align;
void Load(vfsStream& f); void Load(const fs::file& f);
void LoadLE(vfsStream& f); void LoadLE(const fs::file& f);
void Show() {} void Show() {}
}; };
@ -269,7 +268,7 @@ struct Elf64_Ehdr
u16 e_shnum; u16 e_shnum;
u16 e_shstrndx; u16 e_shstrndx;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show() {} void Show() {}
bool CheckMagic() const { return e_magic == 0x7F454C46; } bool CheckMagic() const { return e_magic == 0x7F454C46; }
u64 GetEntry() const { return e_entry; } u64 GetEntry() const { return e_entry; }
@ -288,7 +287,7 @@ struct Elf64_Shdr
u64 sh_addralign; u64 sh_addralign;
u64 sh_entsize; u64 sh_entsize;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(){} void Show(){}
}; };
@ -303,7 +302,7 @@ struct Elf64_Phdr
u64 p_memsz; u64 p_memsz;
u64 p_align; u64 p_align;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(){} void Show(){}
}; };
@ -317,7 +316,7 @@ struct SceHeader
u64 se_hsize; u64 se_hsize;
u64 se_esize; u64 se_esize;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(){} void Show(){}
bool CheckMagic() const { return se_magic == 0x53434500; } bool CheckMagic() const { return se_magic == 0x53434500; }
}; };
@ -335,14 +334,14 @@ struct SelfHeader
u64 se_controlsize; u64 se_controlsize;
u64 pad; u64 pad;
void Load(vfsStream& f); void Load(const fs::file& f);
void Show(){} void Show(){}
}; };
class SELFDecrypter class SELFDecrypter
{ {
// Main SELF file stream. // Main SELF file stream.
vfsStream& self_f; const fs::file& self_f;
// SCE, SELF and APP headers. // SCE, SELF and APP headers.
SceHeader sce_hdr; SceHeader sce_hdr;
@ -379,7 +378,7 @@ class SELFDecrypter
KeyVault key_v; KeyVault key_v;
public: public:
SELFDecrypter(vfsStream& s); SELFDecrypter(const fs::file& s);
bool MakeElf(const std::string& elf, bool isElf32); bool MakeElf(const std::string& elf, bool isElf32);
bool LoadHeaders(bool isElf32); bool LoadHeaders(bool isElf32);
void ShowHeaders(bool isElf32); void ShowHeaders(bool isElf32);

View File

@ -2,7 +2,6 @@
// Licensed under the terms of the GNU GPL, version 3 // Licensed under the terms of the GNU GPL, version 3
// http://www.gnu.org/licenses/gpl-3.0.txt // http://www.gnu.org/licenses/gpl-3.0.txt
#include "stdafx.h"
#include "utils.h" #include "utils.h"
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -208,4 +207,4 @@ char* extract_file_name(const char* file_path, char real_file_name[MAX_PATH])
strncpy(real_file_name, p ? (p + 1) : file_path, file_path_len + 1); strncpy(real_file_name, p ? (p + 1) : file_path, file_path_len + 1);
return real_file_name; return real_file_name;
} }

View File

@ -4,6 +4,8 @@
// Licensed under the terms of the GNU GPL, version 3 // Licensed under the terms of the GNU GPL, version 3
// http://www.gnu.org/licenses/gpl-3.0.txt // http://www.gnu.org/licenses/gpl-3.0.txt
#include "../../Utilities/types.h"
#define MAX_PATH 4096 #define MAX_PATH 4096
#include <stdlib.h> #include <stdlib.h>
@ -32,4 +34,4 @@ void aesecb128_encrypt(unsigned char *key, unsigned char *in, unsigned char *out
bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len); bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len);
void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash); void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash);
bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len); bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len);
void cmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash); void cmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash);