Skip to content

Commit

Permalink
Remove protect_lock
Browse files Browse the repository at this point in the history
  • Loading branch information
Sirius902 committed Dec 30, 2022
1 parent b3d0d5d commit a445455
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 49 deletions.
65 changes: 20 additions & 45 deletions src/MemoryLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,6 @@ class MemoryLib {
static inline PROCESS_INFORMATION _pInfo;
static inline bool _bigEndian = false;

class protect_lock {
private:
std::uintptr_t address;
std::size_t size;
DWORD protection;
bool is_acquired;

public:
protect_lock(std::uintptr_t address, std::size_t size)
: address(address), size(size), protection(0), is_acquired(false) {
if (VirtualProtect((void*)address, size, PAGE_READWRITE, &protection) != 0) is_acquired = true;
}

~protect_lock() {
if (good()) VirtualProtect((void*)address, size, protection, &protection);
}

bool good() const noexcept { return is_acquired; }
};

public:
static inline std::uint64_t ExecAddress;
static inline std::uint64_t BaseAddress;
Expand Down Expand Up @@ -136,9 +116,7 @@ class MemoryLib {

template <typename T, std::enable_if_t<std::is_trivially_constructible_v<T>, int> = 0>
static T readScalarAbsolute(std::uint64_t Address) {
protect_lock lock(Address, sizeof(T));
if (!lock.good()) return 0;

if (Address == 0) return 0;
return *reinterpret_cast<T*>(Address);
}

Expand All @@ -163,25 +141,20 @@ class MemoryLib {
static inline bool ReadBoolAbsolute(std::uint64_t Address) { return ReadByteAbsolute(Address) != 0; }

static std::vector<std::uint8_t> ReadBytesAbsolute(std::uint64_t Address, int Length) {
std::vector<std::uint8_t> _buffer;
if (Address == 0) return {};

protect_lock lock(Address, static_cast<std::size_t>(Length));
if (lock.good()) {
_buffer.resize(Length);
std::memcpy(_buffer.data(), (void*)Address, Length);
}
std::vector<std::uint8_t> _buffer(Length);
std::memcpy(_buffer.data(), (void*)Address, Length);

return _buffer;
}

static std::string ReadStringAbsolute(std::uint64_t Address, int Length) {
std::string _output;
if (Address == 0) return {};

protect_lock lock(Address, static_cast<std::size_t>(Length));
if (lock.good()) {
_output.resize(Length);
std::memcpy(_output.data(), (void*)Address, Length);
}
std::string _output;
_output.resize(Length);
std::memcpy(_output.data(), (void*)Address, Length);

return _output;
}
Expand Down Expand Up @@ -237,10 +210,9 @@ class MemoryLib {

template <typename T, std::enable_if_t<std::is_trivially_copy_assignable_v<T>, int> = 0>
static void writeScalarAbsolute(std::uint64_t Address, T t) {
protect_lock lock(Address, sizeof(T));
if (!lock.good()) return;

*reinterpret_cast<T*>(Address) = t;
if (Address != 0) {
*reinterpret_cast<T*>(Address) = t;
}
}

static inline void WriteByteAbsolute(std::uint64_t Address, std::uint8_t Input) {
Expand Down Expand Up @@ -268,13 +240,15 @@ class MemoryLib {
}

static void WriteBytesAbsolute(std::uint64_t Address, std::vector<std::uint8_t> Input) {
protect_lock lock(Address, Input.size());
if (lock.good()) std::memcpy((void*)Address, Input.data(), Input.size());
if (Address != 0) {
std::memcpy((void*)Address, Input.data(), Input.size());
}
}

static void WriteStringAbsolute(std::uint64_t Address, std::string Input) {
protect_lock lock(Address, Input.size());
if (lock.good()) std::memcpy((void*)Address, Input.data(), Input.size());
if (Address != 0) {
std::memcpy((void*)Address, Input.data(), Input.size());
}
}

template <typename T>
Expand Down Expand Up @@ -327,8 +301,9 @@ class MemoryLib {
}

static void WriteExec(std::uint64_t Address, std::vector<std::uint8_t> Input) {
protect_lock lock(Address, Input.size());
if (lock.good()) std::memcpy((void*)(Address + ExecAddress), Input.data(), Input.size());
if (Address != 0) {
std::memcpy((void*)(Address + ExecAddress), Input.data(), Input.size());
}
}

static inline std::uint64_t GetPointer(std::uint64_t Address, std::uint64_t Offset, bool absolute = false) {
Expand Down
32 changes: 28 additions & 4 deletions src/main_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ GameFrameProc frameProc = nullptr;
std::optional<Config> config;
std::optional<GameInfo> gameInfo;

HMODULE gameModule = nullptr;
std::uint64_t moduleAddress = 0;

template <ranges::bidirectional_range R>
Expand Down Expand Up @@ -104,11 +105,33 @@ bool hookGame() {

if (*frameProcPtr == nullptr) return false;

DWORD originalProt = 0;
VirtualProtect(frameProcPtr, sizeof(frameProcPtr), PAGE_READWRITE, &originalProt);
// Method for changing memory region permissions adapted from Panacea's implementation
// https://github.com/OpenKH/OpenKh/blob/5878a3b/OpenKh.Research.Panacea/Panacea.cpp#L256-L277
ULONG_PTR baseImage = (ULONG_PTR)gameModule;

PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)baseImage;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(baseImage + dosHeaders->e_lfanew);

PIMAGE_SECTION_HEADER section =
(PIMAGE_SECTION_HEADER)((std::intptr_t)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader);
MEMORY_BASIC_INFORMATION meminf;
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
VirtualQuery((const void*)(baseImage + section[i].VirtualAddress), &meminf, sizeof(meminf));
DWORD oldprot;
switch (meminf.Protect & 0xFF) {
case PAGE_EXECUTE:
case PAGE_EXECUTE_READ:
VirtualProtect(meminf.BaseAddress, meminf.RegionSize, PAGE_EXECUTE_WRITECOPY, &oldprot);
break;
case PAGE_NOACCESS:
case PAGE_READONLY:
VirtualProtect(meminf.BaseAddress, meminf.RegionSize, PAGE_WRITECOPY, &oldprot);
break;
}
}

frameProc = *frameProcPtr;
*frameProcPtr = frameHook;
VirtualProtect(frameProcPtr, sizeof(frameProcPtr), originalProt, &originalProt);

SetUnhandledExceptionFilter(crashDumpHandler);

Expand Down Expand Up @@ -137,7 +160,8 @@ DWORD WINAPI entry(LPVOID lpParameter) {
return 0;
}

moduleAddress = (std::uint64_t)GetModuleHandleW(nullptr);
gameModule = GetModuleHandleW(nullptr);
moduleAddress = (std::uint64_t)gameModule;
std::uint64_t baseAddress = moduleAddress + gameInfo->baseAddress;

fs::path gameDocsRoot = [&]() {
Expand Down

0 comments on commit a445455

Please sign in to comment.