mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactored SafeWrite.cpp.
This commit is contained in:
+64
-21
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user