mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
decrypt_self() function
Fixed SPU self decryption Fixed PSV debug self load
This commit is contained in:
parent
be5f780977
commit
e8bfce4ebd
9 changed files with 81 additions and 118 deletions
|
@ -1038,15 +1038,10 @@ bool SELFDecrypter::DecryptData()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
fs::file SELFDecrypter::MakeElf(bool isElf32)
|
||||||
{
|
{
|
||||||
// Create a new ELF file.
|
// Create a new ELF file.
|
||||||
fs::file e(elf, fs::rewrite);
|
fs::file e = fs::make_stream<std::vector<u8>>();
|
||||||
if(!e)
|
|
||||||
{
|
|
||||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial offset.
|
// Set initial offset.
|
||||||
u32 data_buf_offset = 0;
|
u32 data_buf_offset = 0;
|
||||||
|
@ -1162,7 +1157,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
|
bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
|
||||||
|
@ -1201,23 +1196,11 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSelf(const std::string& path)
|
static bool IsSelfElf32(const fs::file& f)
|
||||||
{
|
{
|
||||||
fs::file f(path);
|
|
||||||
|
|
||||||
if (!f) return false;
|
if (!f) return false;
|
||||||
|
|
||||||
SceHeader hdr;
|
f.seek(0);
|
||||||
hdr.Load(f);
|
|
||||||
|
|
||||||
return hdr.CheckMagic();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSelfElf32(const std::string& path)
|
|
||||||
{
|
|
||||||
fs::file f(path);
|
|
||||||
|
|
||||||
if (!f) return false;
|
|
||||||
|
|
||||||
SceHeader hdr;
|
SceHeader hdr;
|
||||||
SelfHeader sh;
|
SelfHeader sh;
|
||||||
|
@ -1233,46 +1216,31 @@ bool IsSelfElf32(const std::string& path)
|
||||||
return (elf_class[4] == 1);
|
return (elf_class[4] == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
static bool CheckDebugSelf(fs::file& s)
|
||||||
{
|
{
|
||||||
// Open the SELF file.
|
if (s.size() < 0x18)
|
||||||
fs::file s(self);
|
|
||||||
|
|
||||||
if (!s)
|
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Could not open SELF file! (%s)", self.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the key version.
|
// Get the key version.
|
||||||
s.seek(0x08);
|
s.seek(0x08);
|
||||||
|
|
||||||
u16 key_version;
|
const u16 key_version = s.read<le_t<u16>>();
|
||||||
s.read(&key_version, sizeof(key_version));
|
|
||||||
|
|
||||||
// Check for DEBUG version.
|
// Check for DEBUG version.
|
||||||
if (swap16(key_version) == 0x8000)
|
if (key_version == 0x80 || key_version == 0xc0)
|
||||||
{
|
{
|
||||||
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.
|
||||||
s.seek(0x10);
|
s.seek(0x10);
|
||||||
|
|
||||||
u64 elf_offset;
|
|
||||||
s.read(&elf_offset, sizeof(elf_offset));
|
|
||||||
|
|
||||||
// Start at the real elf offset.
|
// Start at the real elf offset.
|
||||||
elf_offset = swap64(elf_offset);
|
s.seek(key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>());
|
||||||
|
|
||||||
s.seek(elf_offset);
|
|
||||||
|
|
||||||
// Write the real ELF file back.
|
// Write the real ELF file back.
|
||||||
fs::file e(elf, fs::rewrite);
|
fs::file e = fs::make_stream<std::vector<u8>>();
|
||||||
if (!e)
|
|
||||||
{
|
|
||||||
LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the data.
|
// Copy the data.
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
|
@ -1281,6 +1249,7 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
||||||
e.write(buf, size);
|
e.write(buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = std::move(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,53 +1257,43 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DecryptSelf(const std::string& elf, const std::string& self)
|
extern fs::file decrypt_self(fs::file elf_or_self)
|
||||||
{
|
{
|
||||||
LOG_NOTICE(LOADER, "Decrypting %s", self);
|
elf_or_self.seek(0);
|
||||||
|
|
||||||
// Check for a debug SELF first.
|
// Check SELF header first. Check for a debug SELF.
|
||||||
if (!CheckDebugSelf(self, elf))
|
if (elf_or_self.size() >= 4 && elf_or_self.read<u32>() == "SCE\0"_u32 && !CheckDebugSelf(elf_or_self))
|
||||||
{
|
{
|
||||||
// Set a virtual pointer to the SELF file.
|
|
||||||
fs::file self_vf(self);
|
|
||||||
|
|
||||||
if (!self_vf)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check the ELF file class (32 or 64 bit).
|
// Check the ELF file class (32 or 64 bit).
|
||||||
bool isElf32 = IsSelfElf32(self);
|
bool isElf32 = IsSelfElf32(elf_or_self);
|
||||||
|
|
||||||
// Start the decrypter on this SELF file.
|
// Start the decrypter on this SELF file.
|
||||||
SELFDecrypter self_dec(self_vf);
|
SELFDecrypter self_dec(elf_or_self);
|
||||||
|
|
||||||
// Load the SELF file headers.
|
// Load the SELF file headers.
|
||||||
if (!self_dec.LoadHeaders(isElf32))
|
if (!self_dec.LoadHeaders(isElf32))
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "SELF: Failed to load SELF file headers!");
|
LOG_ERROR(LOADER, "SELF: Failed to load SELF file headers!");
|
||||||
return false;
|
return fs::file{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and decrypt the SELF file metadata.
|
// Load and decrypt the SELF file metadata.
|
||||||
if (!self_dec.LoadMetadata())
|
if (!self_dec.LoadMetadata())
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "SELF: Failed to load SELF file metadata!");
|
LOG_ERROR(LOADER, "SELF: Failed to load SELF file metadata!");
|
||||||
return false;
|
return fs::file{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the SELF file data.
|
// Decrypt the SELF file data.
|
||||||
if (!self_dec.DecryptData())
|
if (!self_dec.DecryptData())
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "SELF: Failed to decrypt SELF file data!");
|
LOG_ERROR(LOADER, "SELF: Failed to decrypt SELF file data!");
|
||||||
return false;
|
return fs::file{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a new ELF file from this SELF.
|
// Make a new ELF file from this SELF.
|
||||||
if (!self_dec.MakeElf(elf, isElf32))
|
return self_dec.MakeElf(isElf32);
|
||||||
{
|
|
||||||
LOG_ERROR(LOADER, "SELF: Failed to make ELF file from SELF!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return elf_or_self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,7 +379,7 @@ class SELFDecrypter
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SELFDecrypter(const fs::file& s);
|
SELFDecrypter(const fs::file& s);
|
||||||
bool MakeElf(const std::string& elf, bool isElf32);
|
fs::file MakeElf(bool isElf32);
|
||||||
bool LoadHeaders(bool isElf32);
|
bool LoadHeaders(bool isElf32);
|
||||||
void ShowHeaders(bool isElf32);
|
void ShowHeaders(bool isElf32);
|
||||||
bool LoadMetadata();
|
bool LoadMetadata();
|
||||||
|
@ -388,7 +388,4 @@ public:
|
||||||
bool GetKeyFromRap(u8 *content_id, u8 *npdrm_key);
|
bool GetKeyFromRap(u8 *content_id, u8 *npdrm_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool IsSelf(const std::string& path);
|
extern fs::file decrypt_self(fs::file elf_or_self);
|
||||||
extern bool IsSelfElf32(const std::string& path);
|
|
||||||
extern bool CheckDebugSelf(const std::string& self, const std::string& elf);
|
|
||||||
extern bool DecryptSelf(const std::string& elf, const std::string& self);
|
|
||||||
|
|
|
@ -67,25 +67,16 @@ s32 sys_raw_spu_load(s32 id, vm::cptr<char> path, vm::ptr<u32> entry)
|
||||||
{
|
{
|
||||||
sysPrxForUser.warning("sys_raw_spu_load(id=%d, path=%s, entry=*0x%x)", id, path, entry);
|
sysPrxForUser.warning("sys_raw_spu_load(id=%d, path=%s, entry=*0x%x)", id, path, entry);
|
||||||
|
|
||||||
const fs::file f(vfs::get(path.get_ptr()));
|
const fs::file elf_file = decrypt_self(fs::file(vfs::get(path.get_ptr())));
|
||||||
if (!f)
|
|
||||||
|
if (!elf_file)
|
||||||
{
|
{
|
||||||
sysPrxForUser.error("sys_raw_spu_load() error: %s not found!", path);
|
sysPrxForUser.error("sys_raw_spu_load() error: %s not found!", path);
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceHeader hdr;
|
|
||||||
hdr.Load(f);
|
|
||||||
|
|
||||||
if (hdr.CheckMagic())
|
|
||||||
{
|
|
||||||
fmt::throw_exception("sys_raw_spu_load() error: %s is encrypted! Try to decrypt it manually and try again.", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
f.seek(0);
|
|
||||||
|
|
||||||
u32 _entry;
|
u32 _entry;
|
||||||
LoadSpuImage(f, _entry, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id);
|
LoadSpuImage(elf_file, _entry, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id);
|
||||||
|
|
||||||
*entry = _entry | 1;
|
*entry = _entry | 1;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Utilities/Config.h"
|
#include "Utilities/Config.h"
|
||||||
#include "Utilities/AutoPause.h"
|
#include "Utilities/AutoPause.h"
|
||||||
#include "Crypto/sha1.h"
|
#include "Crypto/sha1.h"
|
||||||
|
#include "Crypto/unself.h"
|
||||||
#include "Loader/ELF.h"
|
#include "Loader/ELF.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
|
@ -1120,7 +1121,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||||
|
|
||||||
if (g_cfg_load_liblv2)
|
if (g_cfg_load_liblv2)
|
||||||
{
|
{
|
||||||
const ppu_prx_object obj = fs::file(lle_dir + "/liblv2.sprx");
|
const ppu_prx_object obj = decrypt_self(fs::file(lle_dir + "/liblv2.sprx"));
|
||||||
|
|
||||||
if (obj == elf_error::ok)
|
if (obj == elf_error::ok)
|
||||||
{
|
{
|
||||||
|
@ -1135,7 +1136,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||||
{
|
{
|
||||||
for (const auto& name : g_cfg_load_libs.get_set())
|
for (const auto& name : g_cfg_load_libs.get_set())
|
||||||
{
|
{
|
||||||
const ppu_prx_object obj = fs::file(lle_dir + '/' + name);
|
const ppu_prx_object obj = decrypt_self(fs::file(lle_dir + '/' + name));
|
||||||
|
|
||||||
if (obj == elf_error::ok)
|
if (obj == elf_error::ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ s32 prx_load_module(std::string path, u64 flags, vm::ptr<sys_prx_load_module_opt
|
||||||
{
|
{
|
||||||
sys_prx.warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt);
|
sys_prx.warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt);
|
||||||
|
|
||||||
const ppu_prx_object obj = fs::file(vfs::get(path));
|
const ppu_prx_object obj = decrypt_self(fs::file(vfs::get(path)));
|
||||||
|
|
||||||
if (obj != elf_error::ok)
|
if (obj != elf_error::ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,25 +60,16 @@ error_code sys_spu_image_open(vm::ptr<sys_spu_image_t> img, vm::cptr<char> path)
|
||||||
{
|
{
|
||||||
sys_spu.warning("sys_spu_image_open(img=*0x%x, path=%s)", img, path);
|
sys_spu.warning("sys_spu_image_open(img=*0x%x, path=%s)", img, path);
|
||||||
|
|
||||||
const fs::file f(vfs::get(path.get_ptr()));
|
const fs::file elf_file = decrypt_self(fs::file(vfs::get(path.get_ptr())));
|
||||||
if (!f)
|
|
||||||
|
if (!elf_file)
|
||||||
{
|
{
|
||||||
sys_spu.error("sys_spu_image_open() error: %s not found!", path);
|
sys_spu.error("sys_spu_image_open() error: %s not found!", path);
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceHeader hdr;
|
|
||||||
hdr.Load(f);
|
|
||||||
|
|
||||||
if (hdr.CheckMagic())
|
|
||||||
{
|
|
||||||
fmt::throw_exception("sys_spu_image_open() error: %s is encrypted! Try to decrypt it manually and try again.", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
f.seek(0);
|
|
||||||
|
|
||||||
u32 entry;
|
u32 entry;
|
||||||
u32 offset = LoadSpuImage(f, entry);
|
u32 offset = LoadSpuImage(elf_file, entry);
|
||||||
|
|
||||||
img->type = SYS_SPU_IMAGE_TYPE_USER;
|
img->type = SYS_SPU_IMAGE_TYPE_USER;
|
||||||
img->entry_point = entry;
|
img->entry_point = entry;
|
||||||
|
|
|
@ -84,6 +84,8 @@ void Emulator::Init()
|
||||||
|
|
||||||
// Reload global configuration
|
// Reload global configuration
|
||||||
cfg::root.from_string(fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::create).to_string());
|
cfg::root.from_string(fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::create).to_string());
|
||||||
|
|
||||||
|
SetCPUThreadStop(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::SetPath(const std::string& path, const std::string& elf_path)
|
void Emulator::SetPath(const std::string& path, const std::string& elf_path)
|
||||||
|
@ -152,44 +154,55 @@ void Emulator::Load()
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
if (!fs::is_file(m_path))
|
// Open SELF or ELF
|
||||||
|
fs::file elf_file(m_path);
|
||||||
|
|
||||||
|
LOG_NOTICE(LOADER, "Path: %s", m_path);
|
||||||
|
|
||||||
|
if (!elf_file)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "File not found: %s", m_path);
|
LOG_ERROR(LOADER, "Failed to open file: %s", m_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& elf_dir = fs::get_parent_dir(m_path);
|
const std::string& elf_dir = fs::get_parent_dir(m_path);
|
||||||
|
|
||||||
if (IsSelf(m_path))
|
// Check SELF header
|
||||||
|
if (elf_file.size() >= 4 && elf_file.read<u32>() == "SCE\0"_u32)
|
||||||
{
|
{
|
||||||
|
// Decrypt SELF
|
||||||
|
elf_file = decrypt_self(std::move(elf_file));
|
||||||
|
|
||||||
const std::size_t elf_ext_pos = m_path.find_last_of('.');
|
const std::size_t elf_ext_pos = m_path.find_last_of('.');
|
||||||
const std::string& elf_ext = fmt::to_upper(m_path.substr(elf_ext_pos != -1 ? elf_ext_pos : m_path.size()));
|
const std::string& elf_ext = fmt::to_upper(m_path.substr(elf_ext_pos != -1 ? elf_ext_pos : m_path.size()));
|
||||||
const std::string& elf_name = m_path.substr(elf_dir.size());
|
const std::string& elf_name = m_path.substr(elf_dir.size());
|
||||||
|
|
||||||
|
// Save ELF (TODO: configuration, cache and different file location)
|
||||||
|
std::string new_path = m_path;
|
||||||
|
|
||||||
if (elf_name.compare(elf_name.find_last_of("/\\", -1, 2) + 1, 9, "EBOOT.BIN", 9) == 0)
|
if (elf_name.compare(elf_name.find_last_of("/\\", -1, 2) + 1, 9, "EBOOT.BIN", 9) == 0)
|
||||||
{
|
{
|
||||||
m_path.erase(m_path.size() - 9, 1); // change EBOOT.BIN to BOOT.BIN
|
new_path.erase(new_path.size() - 9, 1); // change EBOOT.BIN to BOOT.BIN
|
||||||
}
|
}
|
||||||
else if (elf_ext == ".SELF" || elf_ext == ".SPRX")
|
else if (elf_ext == ".SELF" || elf_ext == ".SPRX")
|
||||||
{
|
{
|
||||||
m_path.erase(m_path.size() - 4, 1); // change *.self to *.elf, *.sprx to *.prx
|
new_path.erase(new_path.size() - 4, 1); // change *.self to *.elf, *.sprx to *.prx
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_path += ".decrypted.elf";
|
new_path += ".decrypted.elf";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DecryptSelf(m_path, elf_dir + elf_name))
|
if (fs::file elf_out{new_path, fs::rewrite})
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Failed to decrypt %s", elf_dir + elf_name);
|
elf_out.write(elf_file.to_vector<u8>());
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "Failed to save file: %s", new_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCPUThreadStop(0);
|
|
||||||
|
|
||||||
LOG_NOTICE(LOADER, "Path: %s", m_path);
|
|
||||||
|
|
||||||
// Load custom config
|
// Load custom config
|
||||||
if (fs::file cfg_file{ m_path + ".yml" })
|
if (fs::file cfg_file{ m_path + ".yml" })
|
||||||
{
|
{
|
||||||
|
@ -197,7 +210,6 @@ void Emulator::Load()
|
||||||
cfg::root.from_string(cfg_file.to_string());
|
cfg::root.from_string(cfg_file.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
const fs::file elf_file(m_path);
|
|
||||||
ppu_exec_object ppu_exec;
|
ppu_exec_object ppu_exec;
|
||||||
ppu_prx_object ppu_prx;
|
ppu_prx_object ppu_prx;
|
||||||
spu_exec_object spu_exec;
|
spu_exec_object spu_exec;
|
||||||
|
@ -205,7 +217,7 @@ void Emulator::Load()
|
||||||
|
|
||||||
if (!elf_file)
|
if (!elf_file)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "Failed to open %s", m_path);
|
LOG_ERROR(LOADER, "Failed to decrypt SELF: %s", m_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (ppu_exec.open(elf_file) == elf_error::ok)
|
else if (ppu_exec.open(elf_file) == elf_error::ok)
|
||||||
|
|
|
@ -374,19 +374,30 @@ void MainFrame::DecryptSPRXLibraries(wxCommandEvent& WXUNUSED(event))
|
||||||
std::string prx_path = fmt::ToUTF8(module);
|
std::string prx_path = fmt::ToUTF8(module);
|
||||||
const std::string& prx_dir = fs::get_parent_dir(prx_path);
|
const std::string& prx_dir = fs::get_parent_dir(prx_path);
|
||||||
|
|
||||||
if (IsSelf(prx_path))
|
fs::file elf_file(prx_path);
|
||||||
|
|
||||||
|
if (elf_file && elf_file.size() >= 4 && elf_file.read<u32>() == "SCE\0"_u32)
|
||||||
{
|
{
|
||||||
const std::size_t prx_ext_pos = prx_path.find_last_of('.');
|
const std::size_t prx_ext_pos = prx_path.find_last_of('.');
|
||||||
const std::string& prx_ext = fmt::to_upper(prx_path.substr(prx_ext_pos != -1 ? prx_ext_pos : prx_path.size()));
|
const std::string& prx_ext = fmt::to_upper(prx_path.substr(prx_ext_pos != -1 ? prx_ext_pos : prx_path.size()));
|
||||||
const std::string& prx_name = prx_path.substr(prx_dir.size());
|
const std::string& prx_name = prx_path.substr(prx_dir.size());
|
||||||
|
|
||||||
|
elf_file = decrypt_self(std::move(elf_file));
|
||||||
|
|
||||||
prx_path.erase(prx_path.size() - 4, 1); // change *.sprx to *.prx
|
prx_path.erase(prx_path.size() - 4, 1); // change *.sprx to *.prx
|
||||||
|
|
||||||
if (DecryptSelf(prx_path, prx_dir + prx_name))
|
if (elf_file)
|
||||||
{
|
{
|
||||||
LOG_SUCCESS(GENERAL, "Decrypted %s", prx_dir + prx_name);
|
if (fs::file new_file{prx_path, fs::rewrite})
|
||||||
|
{
|
||||||
|
new_file.write(elf_file.to_string());
|
||||||
|
LOG_SUCCESS(GENERAL, "Decrypted %s", prx_dir + prx_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR(GENERAL, "Failed to create %s", prx_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR(GENERAL, "Failed to decrypt %s", prx_dir + prx_name);
|
LOG_ERROR(GENERAL, "Failed to decrypt %s", prx_dir + prx_name);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "stdafx_gui.h"
|
#include "stdafx_gui.h"
|
||||||
#include "Utilities/Config.h"
|
#include "Utilities/Config.h"
|
||||||
|
#include "Crypto/unself.h"
|
||||||
#include "Loader/ELF.h"
|
#include "Loader/ELF.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
|
||||||
|
@ -340,7 +341,7 @@ SettingsDialog::SettingsDialog(wxWindow* parent)
|
||||||
for (const auto& prxf : fs::dir(lle_dir))
|
for (const auto& prxf : fs::dir(lle_dir))
|
||||||
{
|
{
|
||||||
// List found unselected modules
|
// List found unselected modules
|
||||||
if (!prxf.is_directory && ppu_prx_object(fs::file(lle_dir + prxf.name)) == elf_error::ok && !set.count(prxf.name))
|
if (!prxf.is_directory && ppu_prx_object(decrypt_self(fs::file(lle_dir + prxf.name))) == elf_error::ok && !set.count(prxf.name))
|
||||||
{
|
{
|
||||||
lle_module_list_unselected.push_back(prxf.name);
|
lle_module_list_unselected.push_back(prxf.name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue