enderalse/source/fs.dll/skse64/skse64_common/SafeWrite.cpp

67 lines
1.2 KiB
C++

#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);
}