From 42dc5356388ad4c5a92c5a9cb36ab083ca8f63e6 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 10 Jul 2023 14:52:14 +0300 Subject: [PATCH] some more work on linker and added some more needed (but not currently used) memory functions --- src/Core/Memory.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ src/Core/Memory.h | 3 +++ src/Core/PS4/Linker.cpp | 13 ++++++----- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/Core/Memory.cpp b/src/Core/Memory.cpp index 39449176..0855df7f 100644 --- a/src/Core/Memory.cpp +++ b/src/Core/Memory.cpp @@ -42,6 +42,17 @@ namespace Memory return PAGE_NOACCESS; } } + static MemoryMode convertMemoryMode(u32 mode) { + switch (mode) { + case PAGE_NOACCESS: return MemoryMode::NoAccess; + case PAGE_READONLY: return MemoryMode::Read; + case PAGE_READWRITE: return MemoryMode::ReadWrite; + case PAGE_EXECUTE: return MemoryMode::Execute; + case PAGE_EXECUTE_READ: return MemoryMode::ExecuteRead; + case PAGE_EXECUTE_READWRITE: return MemoryMode::ExecuteReadWrite; + default: return MemoryMode::NoAccess; + } + } u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { @@ -71,5 +82,46 @@ namespace Memory #endif return ptr; } + bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode) { + DWORD old_protect = 0; + if (VirtualProtect(reinterpret_cast(static_cast(address)), size, convertMemoryMode(mode), &old_protect) == 0) { + auto err = static_cast(GetLastError()); + LOG_ERROR_IF(true, "VirtualProtect() failed: 0x{:X}\n", err); + return false; + } + if (old_mode != nullptr) { + *old_mode = convertMemoryMode(old_protect); + } + return true; + } + + bool memory_flush(u64 address, u64 size) { + if (::FlushInstructionCache(GetCurrentProcess(), reinterpret_cast(static_cast(address)), size) == 0) { + auto err = static_cast(GetLastError()); + LOG_ERROR_IF(true, "FlushInstructionCache() failed: 0x{:X}\n", err); + return false; + } + return true; + } + bool memory_patch(u64 vaddr, u64 value) { + MemoryMode old_mode{}; + memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode); + + auto* ptr = reinterpret_cast(vaddr); + + bool ret = (*ptr != value); + + *ptr = value; + + memory_protect(vaddr, 8, old_mode, nullptr); + + //if mode is executable flush it so insure that cpu finds it + if ((old_mode == MemoryMode::Execute || old_mode == MemoryMode::ExecuteRead || old_mode == MemoryMode::ExecuteWrite || + old_mode == MemoryMode::ExecuteReadWrite)) { + memory_flush(vaddr, 8); + } + + return ret; + } } } diff --git a/src/Core/Memory.h b/src/Core/Memory.h index 7bc5ba0f..00b9d2ba 100644 --- a/src/Core/Memory.h +++ b/src/Core/Memory.h @@ -20,5 +20,8 @@ namespace Memory namespace VirtualMemory { u64 memory_alloc(u64 address, u64 size, MemoryMode mode); + bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode); + bool memory_flush(u64 address, u64 size); + bool memory_patch(u64 vaddr, u64 value); } } \ No newline at end of file diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index efa3bc15..d1922c52 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -511,6 +511,7 @@ static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) bool rel_isResolved = false; u08 rel_sym_type = 0; std::string rel_name; + u08 rel_bind_type = -1;//-1 means it didn't resolve switch (type) { @@ -544,12 +545,12 @@ static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) switch (sym_bind) { case STB_GLOBAL: - if (type == R_X86_64_64) { - LOG_INFO_IF(debug_loader, "R_X86_64_64 sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type,symbol); - } - if (type == R_X86_64_JUMP_SLOT) { - LOG_INFO_IF(debug_loader, "R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type,symbol); - } + rel_bind_type = STB_GLOBAL; + rel_name = namesTlb + sym.st_name; + if (type == R_X86_64_JUMP_SLOT) { + addend = 0; + } + LOG_INFO_IF(debug_loader, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol); break; default: LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);