Reimplement/fix PRX patches

This commit is contained in:
Eladash 2021-02-08 17:04:50 +02:00 committed by Ivan
parent 48296c2ba6
commit e26ae9899c
4 changed files with 56 additions and 60 deletions

View file

@ -505,39 +505,26 @@ void patch_engine::append_title_patches(const std::string& title_id)
load(m_map, get_patches_path() + title_id + "_patch.yml");
}
std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst)
{
return apply_patch<false>(name, dst, 0, 0);
}
std::basic_string<u32> patch_engine::apply_with_ls_check(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
{
return apply_patch<true>(name, dst, filesz, ls_addr);
}
template <bool CheckLS>
static std::basic_string<u32> apply_modification(const patch_engine::patch_info& patch, u8* dst, u32 filesz, u32 ls_addr)
static std::basic_string<u32> apply_modification(const patch_engine::patch_info& patch, u8* dst, u32 filesz, u32 min_addr)
{
std::basic_string<u32> applied;
for (const auto& p : patch.data_list)
{
u32 offset = p.offset;
u32 resval = 0;
if constexpr (CheckLS)
if (offset < min_addr || offset - min_addr >= filesz)
{
if (offset < ls_addr || offset >= (ls_addr + filesz))
{
// This patch is out of range for this segment
continue;
}
offset -= ls_addr;
// This patch is out of range for this segment
continue;
}
offset -= min_addr;
auto ptr = dst + offset;
u32 resval = -1;
switch (p.type)
{
case patch_type::invalid:
@ -584,10 +571,7 @@ static std::basic_string<u32> apply_modification(const patch_engine::patch_info&
case patch_type::be32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
// Possibly an executable instruction
if constexpr (!CheckLS)
resval = offset;
if (offset % 4 == 0) resval = offset;
break;
}
case patch_type::bef32:
@ -598,6 +582,14 @@ static std::basic_string<u32> apply_modification(const patch_engine::patch_info&
case patch_type::be64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
if (offset % 4)
{
break;
}
resval = offset;
applied.push_back((offset + 7) & -4); // Two 32-bit locations
break;
}
case patch_type::bef64:
@ -607,14 +599,14 @@ static std::basic_string<u32> apply_modification(const patch_engine::patch_info&
}
}
// Possibly an executable instruction
applied.push_back(resval);
}
return applied;
}
template <bool CheckLS>
std::basic_string<u32> patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst, u32 filesz, u32 min_addr)
{
if (m_map.find(name) == m_map.cend())
{
@ -719,7 +711,7 @@ std::basic_string<u32> patch_engine::apply_patch(const std::string& name, u8* ds
m_applied_groups.insert(patch.patch_group);
}
auto applied = apply_modification<CheckLS>(patch, dst, filesz, ls_addr);
auto applied = apply_modification(patch, dst, filesz, min_addr);
applied_total += applied;