#include "SafeWrite.h" void SafeWriteBuf(uintptr_t addr, void * data, size_t len) { UInt32 oldProtect; VirtualProtect((void *)addr, len, PAGE_EXECUTE_READWRITE, &oldProtect); memcpy((void *)addr, data, len); VirtualProtect((void *)addr, len, oldProtect, &oldProtect); } void SafeWrite8(uintptr_t addr, UInt8 data) { SafeWriteBuf(addr, &data, sizeof(data)); } void SafeWrite16(uintptr_t addr, UInt16 data) { SafeWriteBuf(addr, &data, sizeof(data)); } void SafeWrite32(uintptr_t addr, UInt32 data) { SafeWriteBuf(addr, &data, sizeof(data)); } void SafeWrite64(uintptr_t addr, UInt64 data) { SafeWriteBuf(addr, &data, sizeof(data)); } static bool SafeWriteJump_Internal(uintptr_t src, uintptr_t dst, UInt8 op) { #pragma pack(push, 1) struct Code { UInt8 op; SInt32 displ; }; #pragma pack(pop) STATIC_ASSERT(sizeof(Code) == 5); ptrdiff_t delta = dst - (src + sizeof(Code)); if((delta < INT_MIN) || (delta > INT_MAX)) return false; Code code; code.op = op; code.displ = delta; SafeWriteBuf(src, &code, sizeof(code)); return true; } bool SafeWriteJump(uintptr_t src, uintptr_t dst) { return SafeWriteJump_Internal(src, dst, 0xE9); } bool SafeWriteCall(uintptr_t src, uintptr_t dst) { return SafeWriteJump_Internal(src, dst, 0xE8); }