mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Implement runtime PPU executable code modification via Cheat Manager
This commit is contained in:
parent
93a6e9e4e4
commit
8427af8886
@ -165,6 +165,7 @@ extern void ppu_initialize();
|
||||
extern void ppu_initialize(const ppu_module& info);
|
||||
static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name);
|
||||
extern void ppu_execute_syscall(ppu_thread& ppu, u64 code);
|
||||
static bool ppu_break(ppu_thread& ppu, ppu_opcode_t op);
|
||||
|
||||
// Get pointer to executable cache
|
||||
template<typename T = u64>
|
||||
@ -308,11 +309,11 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_function_t ptr)
|
||||
}
|
||||
|
||||
// Initialize interpreter cache
|
||||
const u32 fallback = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(ppu_fallback));
|
||||
const u32 _break = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(ppu_break));
|
||||
|
||||
while (size)
|
||||
{
|
||||
if (ppu_ref<u32>(addr) == fallback)
|
||||
if (ppu_ref<u32>(addr) != _break)
|
||||
{
|
||||
ppu_ref(addr) = ppu_cache(addr);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUAnalyser.h"
|
||||
#include "Emu/Cell/PPUFunction.h"
|
||||
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
@ -332,7 +333,7 @@ std::vector<u32> cheat_engine::search(const T value, const std::vector<u32>& to_
|
||||
{
|
||||
for (const auto& off : to_filter)
|
||||
{
|
||||
if (vm::check_addr(off))
|
||||
if (vm::check_addr(off, sizeof(T)))
|
||||
{
|
||||
if (*vm::get_super_ptr<T>(off) == value_swapped)
|
||||
results.push_back(off);
|
||||
@ -370,7 +371,7 @@ T cheat_engine::get_value(const u32 offset, bool& success)
|
||||
|
||||
cpu_thread::suspend_all cpu_lock(nullptr);
|
||||
|
||||
if (!vm::check_addr(offset))
|
||||
if (!vm::check_addr(offset, sizeof(T)))
|
||||
{
|
||||
success = false;
|
||||
return 0;
|
||||
@ -391,12 +392,52 @@ bool cheat_engine::set_value(const u32 offset, const T value)
|
||||
|
||||
cpu_thread::suspend_all cpu_lock(nullptr);
|
||||
|
||||
if (!vm::check_addr(offset))
|
||||
if (!vm::check_addr(offset, sizeof(T)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*vm::get_super_ptr<T>(offset) = value;
|
||||
|
||||
const bool exec_code_at_start = vm::check_addr(offset, 1, vm::page_executable);
|
||||
const bool exec_code_at_end = [&]()
|
||||
{
|
||||
if constexpr (sizeof(T) == 1)
|
||||
{
|
||||
return exec_code_at_start;
|
||||
}
|
||||
else
|
||||
{
|
||||
return vm::check_addr(offset + sizeof(T) - 1, 1, vm::page_executable);
|
||||
}
|
||||
}();
|
||||
|
||||
if (exec_code_at_end || exec_code_at_start)
|
||||
{
|
||||
extern void ppu_register_function_at(u32, u32, ppu_function_t);
|
||||
|
||||
u32 addr = offset, size = sizeof(T);
|
||||
|
||||
if (exec_code_at_end && exec_code_at_start)
|
||||
{
|
||||
size = align<u32>(addr + size, 4) - (addr & -4);
|
||||
addr &= -4;
|
||||
}
|
||||
else if (exec_code_at_end)
|
||||
{
|
||||
size -= align<u32>(size - 4096 + (addr & 4095), 4);
|
||||
addr = align<u32>(addr, 4096);
|
||||
}
|
||||
else if (exec_code_at_start)
|
||||
{
|
||||
size = align<u32>(4096 - (addr & 4095), 4);
|
||||
addr &= -4;
|
||||
}
|
||||
|
||||
// Reinitialize executable code
|
||||
ppu_register_function_at(addr, size, nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user