Fix path bugs & wrap seeks in an if (#1154)

* Fix path bugs

* Wrap most seeks in an if
This commit is contained in:
Paris Oplopoios 2024-09-30 12:42:59 +03:00 committed by GitHub
parent c7ff0419ad
commit cbbf3505e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 105 additions and 47 deletions

View file

@ -44,7 +44,7 @@ PKG::PKG() = default;
PKG::~PKG() = default;
bool PKG::Open(const std::filesystem::path& filepath) {
bool PKG::Open(const std::filesystem::path& filepath, std::string& failreason) {
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
if (!file.IsOpen()) {
return false;
@ -70,7 +70,11 @@ bool PKG::Open(const std::filesystem::path& filepath) {
u32 offset = pkgheader.pkg_table_entry_offset;
u32 n_files = pkgheader.pkg_table_entry_count;
file.Seek(offset);
if (!file.Seek(offset)) {
failreason = "Failed to seek to PKG table entry offset";
return false;
}
for (int i = 0; i < n_files; i++) {
PKGEntry entry{};
file.Read(entry.id);
@ -85,7 +89,10 @@ bool PKG::Open(const std::filesystem::path& filepath) {
const auto name = GetEntryNameByType(entry.id);
if (name == "param.sfo") {
sfo.clear();
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to param.sfo offset";
return false;
}
sfo.resize(entry.size);
file.ReadRaw<u8>(sfo.data(), entry.size);
}
@ -127,7 +134,11 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
std::array<std::array<u8, 256>, 7> key1;
std::array<u8, 256> imgkeydata;
file.Seek(offset);
if (!file.Seek(offset)) {
failreason = "Failed to seek to PKG table entry offset";
return false;
}
for (int i = 0; i < n_files; i++) {
PKGEntry entry{};
file.Read(entry.id);
@ -149,7 +160,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
// Just print with id
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
Common::FS::FileAccessMode::Write);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -195,7 +209,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
}
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -207,7 +224,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
entry.id == 0x403) { // somehow 0x401 is not decrypting
decNp.resize(entry.size);
file.Seek(entry.offset);
if (!file.Seek(entry.offset)) {
failreason = "Failed to seek to PKG entry offset";
return false;
}
std::vector<u8> data;
data.resize(entry.size);
@ -237,7 +257,10 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
// Read the seed
std::array<u8, 16> seed;
file.Seek(pkgheader.pfs_image_offset + 0x370);
if (!file.Seek(pkgheader.pfs_image_offset + 0x370)) {
failreason = "Failed to seek to PFS image offset";
return false;
}
file.Read(seed);
// Get data and tweak keys.

View file

@ -103,7 +103,7 @@ public:
PKG();
~PKG();
bool Open(const std::filesystem::path& filepath);
bool Open(const std::filesystem::path& filepath, std::string& failreason);
void ExtractFiles(const int index);
bool Extract(const std::filesystem::path& filepath, const std::filesystem::path& extract,
std::string& failreason);

View file

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "common/path_util.h"
#include "trp.h"
@ -13,7 +14,10 @@ void TRP::GetNPcommID(const std::filesystem::path& trophyPath, int index) {
if (!npbindFile.IsOpen()) {
return;
}
npbindFile.Seek(0x84 + (index * 0x180));
if (!npbindFile.Seek(0x84 + (index * 0x180))) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to NPbind offset");
return;
}
npbindFile.ReadRaw<u8>(np_comm_id.data(), 12);
std::fill(np_comm_id.begin() + 12, np_comm_id.end(), 0); // fill with 0, we need 16 bytes.
}
@ -56,26 +60,38 @@ bool TRP::Extract(const std::filesystem::path& trophyPath) {
std::filesystem::create_directory(trpFilesPath / "Xml");
for (int i = 0; i < header.entry_num; i++) {
file.Seek(seekPos);
if (!file.Seek(seekPos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
seekPos += (s64)header.entry_size;
TrpEntry entry;
file.Read(entry);
std::string_view name(entry.entry_name);
if (entry.flag == 0 && name.find("TROP") != std::string::npos) { // PNG
file.Seek(entry.entry_pos);
if (file.Seek(entry.entry_pos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
std::vector<u8> icon(entry.entry_len);
file.Read(icon);
Common::FS::IOFile::WriteBytes(trpFilesPath / "Icons" / name, icon);
}
if (entry.flag == 3 && np_comm_id[0] == 'N' &&
np_comm_id[1] == 'P') { // ESFM, encrypted.
file.Seek(entry.entry_pos);
if (file.Seek(entry.entry_pos)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry offset");
return false;
}
file.Read(esfmIv); // get iv key.
// Skip the first 16 bytes which are the iv key on every entry as we want a
// clean xml file.
std::vector<u8> ESFM(entry.entry_len - iv_len);
std::vector<u8> XML(entry.entry_len - iv_len);
file.Seek(entry.entry_pos + iv_len);
if (file.Seek(entry.entry_pos + iv_len)) {
LOG_CRITICAL(Common_Filesystem, "Failed to seek to TRP entry + iv offset");
return false;
}
file.Read(ESFM);
crypto.decryptEFSM(np_comm_id, esfmIv, ESFM, XML); // decrypt
removePadding(XML);

View file

@ -229,7 +229,10 @@ s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) {
}
std::scoped_lock lk{file->m_mutex};
file->f.Seek(offset, origin);
if (!file->f.Seek(offset, origin)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelLseek: failed to seek");
return SCE_KERNEL_ERROR_EINVAL;
}
return file->f.Tell();
}
@ -380,7 +383,10 @@ s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset) {
SCOPE_EXIT {
file->f.Seek(pos);
};
file->f.Seek(offset);
if (!file->f.Seek(offset)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelPread: failed to seek");
return ORBIS_KERNEL_ERROR_EINVAL;
}
return file->f.ReadRaw<u8>(buf, nbytes);
}
@ -514,7 +520,10 @@ s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {
SCOPE_EXIT {
file->f.Seek(pos);
};
file->f.Seek(offset);
if (!file->f.Seek(offset)) {
LOG_CRITICAL(Kernel_Fs, "sceKernelPwrite: failed to seek");
return ORBIS_KERNEL_ERROR_EINVAL;
}
return file->f.WriteRaw<u8>(buf, nbytes);
}

View file

@ -204,7 +204,10 @@ void Elf::Open(const std::filesystem::path& file_name) {
}
out.resize(num);
m_f.Seek(offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to header tables");
return;
}
m_f.Read(out);
};
@ -465,7 +468,10 @@ std::string Elf::ElfPHeaderStr(u16 no) {
void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) {
if (!is_self) {
// It's elf file
m_f.Seek(file_offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(file_offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to ELF header");
return;
}
m_f.ReadRaw<u8>(reinterpret_cast<u8*>(virtual_addr), size);
return;
}
@ -479,7 +485,10 @@ void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) {
if (file_offset >= phdr.p_offset && file_offset < phdr.p_offset + phdr.p_filesz) {
auto offset = file_offset - phdr.p_offset;
m_f.Seek(offset + seg.file_offset, SeekOrigin::SetOrigin);
if (!m_f.Seek(offset + seg.file_offset, SeekOrigin::SetOrigin)) {
LOG_CRITICAL(Loader, "Failed to seek to segment");
return;
}
m_f.ReadRaw<u8>(reinterpret_cast<u8*>(virtual_addr), size);
return;
}