Refactored SafeWrite.cpp.

This commit is contained in:
NovaRain
2018-12-19 07:19:34 +08:00
parent a2a24918a6
commit 10c557ad59
+64 -21
View File
@@ -8,10 +8,63 @@
namespace sfall
{
enum CodeType : BYTE {
Call = 0xE8,
Jump = 0xE9,
Nop = 0x90
};
#ifndef NDEBUG
std::list<long> writeAddress;
static void CheckConflict(DWORD addr) {
bool exist = false;
for (const auto &wa : writeAddress) {
if (addr == wa) {
exist = true;
char buf[256];
sprintf_s(buf, "Memory writing conflict at address 0x%x. The address has already been overwritten by other code.", addr);
MessageBoxA(0, buf, "Conflict Detected", MB_TASKMODAL);
}
}
if (!exist) writeAddress.push_back(addr);
}
#endif
static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) {
DWORD oldProtect, data = (DWORD)func - (addr + 5);
VirtualProtect((void *)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
*((BYTE*)addr) = code;
*((DWORD*)(addr + 1)) = data;
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
#ifndef NDEBUG
CheckConflict(addr);
#endif
}
static _declspec(noinline) void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func, DWORD len) {
DWORD oldProtect,
protectLen = len + 5,
addrMem = addr + 5,
data = (DWORD)func - addrMem;
VirtualProtect((void *)addr, protectLen, PAGE_EXECUTE_READWRITE, &oldProtect);
*((BYTE*)addr) = code;
*((DWORD*)(addr + 1)) = data;
for (unsigned int i = 0; i < len; i++) {
*((BYTE*)(addrMem + i)) = CodeType::Nop;
}
VirtualProtect((void *)addr, protectLen, oldProtect, &oldProtect);
#ifndef NDEBUG
CheckConflict(addr);
#endif
}
void SafeWriteBytes(DWORD addr, BYTE* data, int count) {
DWORD oldProtect;
@@ -54,38 +107,25 @@ void _stdcall SafeWriteStr(DWORD addr, const char* data) {
void HookCall(DWORD addr, void* func) {
SafeWrite32(addr + 1, (DWORD)func - (addr + 5));
#ifndef NDEBUG
bool exist = false;
for (const auto &wa : writeAddress) {
if (addr == wa) {
exist = true;
char buf[256];
sprintf_s(buf, "Memory writing conflict at address 0x%x. The address has already been overwritten by other code.", addr);
MessageBoxA(0, buf, "Conflict Detected", MB_TASKMODAL);
}
}
if (!exist) writeAddress.push_back(addr);
#endif
#ifndef NDEBUG
CheckConflict(addr);
#endif
}
void MakeCall(DWORD addr, void* func) {
SafeWrite8(addr, 0xE8);
HookCall(addr, func);
SafeWriteFunc(CodeType::Call, addr, func);
}
void MakeCall(DWORD addr, void* func, int len) {
SafeMemSet(addr + 5, 0x90, len);
MakeCall(addr, func);
SafeWriteFunc(CodeType::Call, addr, func, len);
}
void MakeJump(DWORD addr, void* func) {
SafeWrite8(addr, 0xE9);
HookCall(addr, func);
SafeWriteFunc(CodeType::Jump, addr, func);
}
void MakeJump(DWORD addr, void* func, int len) {
SafeMemSet(addr + 5, 0x90, len);
MakeJump(addr, func);
SafeWriteFunc(CodeType::Jump, addr, func, len);
}
void HookCalls(void* func, std::initializer_list<DWORD> addrs) {
@@ -109,7 +149,10 @@ void SafeMemSet(DWORD addr, BYTE val, int len) {
}
void BlockCall(DWORD addr) {
SafeMemSet(addr, 0x90, 5);
SafeMemSet(addr, CodeType::Nop, 5);
#ifndef NDEBUG
CheckConflict(addr);
#endif
}
}