67 lines
1.2 KiB
C++
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);
|
||
|
}
|