[AntiCheat] Patch virtual protect

This commit is contained in:
momo5502 2017-03-26 20:41:37 +02:00
parent 0fa9186db5
commit aa20fc009d
5 changed files with 102 additions and 24 deletions

View File

@ -5,6 +5,7 @@ namespace Components
Utils::Time::Interval AntiCheat::LastCheck; Utils::Time::Interval AntiCheat::LastCheck;
std::string AntiCheat::Hash; std::string AntiCheat::Hash;
Utils::Hook AntiCheat::LoadLibHook[4]; Utils::Hook AntiCheat::LoadLibHook[4];
Utils::Hook AntiCheat::VirtualProtectHook[2];
unsigned long AntiCheat::Flags = NO_FLAG; unsigned long AntiCheat::Flags = NO_FLAG;
// This function does nothing, it only adds the two passed variables and returns the value // This function does nothing, it only adds the two passed variables and returns the value
@ -354,6 +355,49 @@ namespace Components
} }
} }
bool AntiCheat::IsPageChangeAllowed(void* callee, void* addr, size_t len)
{
HMODULE hModuleSelf = nullptr, hModuleTarget = nullptr, hModuleMain = GetModuleHandle(nullptr);
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(callee), &hModuleTarget);
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(AntiCheat::IsPageChangeAllowed), &hModuleSelf);
size_t mainSize = Utils::GetModuleSize(hModuleMain), selfSize = Utils::GetModuleSize(hModuleSelf);
DWORD self = DWORD(hModuleSelf), main = DWORD(hModuleMain), address = DWORD(addr);
// If the address that should be changed is within our module or the main binary, then we need to check if we are changing it or someone else
if(Utils::HasIntercection(self, selfSize, address, len) || Utils::HasIntercection(main, mainSize, address, len))
{
if (!hModuleSelf || !hModuleTarget || (hModuleTarget != hModuleSelf))
{
return false;
}
}
return true;
}
BOOL WINAPI AntiCheat::VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
{
if (!AntiCheat::IsPageChangeAllowed(_ReturnAddress(), lpAddress, dwSize)) return FALSE;
AntiCheat::VirtualProtectHook[0].uninstall(false);
BOOL result = VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
AntiCheat::VirtualProtectHook[0].install(false);
return result;
}
BOOL WINAPI AntiCheat::VirtualProtectExStub(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
{
if (GetCurrentProcess() == hProcess && !AntiCheat::IsPageChangeAllowed(_ReturnAddress(), lpAddress, dwSize)) return FALSE;
AntiCheat::VirtualProtectHook[1].uninstall(false);
BOOL result = VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect);
AntiCheat::VirtualProtectHook[1].install(false);
return result;
}
unsigned long AntiCheat::ProtectProcess() unsigned long AntiCheat::ProtectProcess()
{ {
#ifdef PROCTECT_PROCESS #ifdef PROCTECT_PROCESS
@ -497,6 +541,7 @@ namespace Components
return 0; return 0;
#endif #endif
} }
void AntiCheat::AcquireDebugPriviledge(HANDLE hToken) void AntiCheat::AcquireDebugPriviledge(HANDLE hToken)
{ {
LUID luid; LUID luid;
@ -511,6 +556,12 @@ namespace Components
//if (GetLastError() != ERROR_SUCCESS) return; //if (GetLastError() != ERROR_SUCCESS) return;
} }
void AntiCheat::PatchVirtualProtect(void* vp, void* vpex)
{
AntiCheat::VirtualProtectHook[1].initialize(vpex, AntiCheat::VirtualProtectExStub, HOOK_JUMP)->install(true, true);
AntiCheat::VirtualProtectHook[0].initialize(vp, AntiCheat::VirtualProtectStub, HOOK_JUMP)->install(true, true);
}
AntiCheat::AntiCheat() AntiCheat::AntiCheat()
{ {
time(nullptr); time(nullptr);

View File

@ -30,6 +30,8 @@ namespace Components
static unsigned long ProtectProcess(); static unsigned long ProtectProcess();
static void PatchVirtualProtect(void* vp, void* vpex);
private: private:
enum IntergrityFlag enum IntergrityFlag
{ {
@ -54,6 +56,7 @@ namespace Components
static void NullSub(); static void NullSub();
static bool IsPageChangeAllowed(void* callee, void* addr, size_t len);
static void AssertCalleeModule(void* callee); static void AssertCalleeModule(void* callee);
static void UninstallLibHook(); static void UninstallLibHook();
@ -67,6 +70,9 @@ namespace Components
static HANDLE WINAPI LoadLibaryExWStub(const wchar_t* library, HANDLE file, DWORD flags); static HANDLE WINAPI LoadLibaryExWStub(const wchar_t* library, HANDLE file, DWORD flags);
#endif #endif
static BOOL WINAPI VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
static BOOL WINAPI VirtualProtectExStub(HANDLE hProcess,LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect,PDWORD lpflOldProtect);
static void LostD3DStub(); static void LostD3DStub();
static void CinematicStub(); static void CinematicStub();
static void SoundInitStub(int a1, int a2, int a3); static void SoundInitStub(int a1, int a2, int a3);
@ -78,5 +84,6 @@ namespace Components
static void AcquireDebugPriviledge(HANDLE hToken); static void AcquireDebugPriviledge(HANDLE hToken);
static Utils::Hook LoadLibHook[4]; static Utils::Hook LoadLibHook[4];
static Utils::Hook VirtualProtectHook[2];
}; };
} }

View File

@ -280,6 +280,10 @@ namespace Components
} }
} }
}); });
#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT)
AntiCheat::PatchVirtualProtect(VirtualProtect, VirtualProtectEx);
#endif
} }
Localization::~Localization() Localization::~Localization()

View File

@ -71,4 +71,16 @@ namespace Utils
return 0; return 0;
} }
size_t GetModuleSize(HMODULE module)
{
PIMAGE_DOS_HEADER header = PIMAGE_DOS_HEADER(module);
PIMAGE_NT_HEADERS ntHeader = PIMAGE_NT_HEADERS(DWORD(module) + header->e_lfanew);
return ntHeader->OptionalHeader.SizeOfImage;
}
bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2)
{
return !((base1 + len1) < base2 || (base2 + len2) < base1);
}
} }

View File

@ -11,6 +11,10 @@ namespace Utils
unsigned long GetParentProcessId(); unsigned long GetParentProcessId();
size_t GetModuleSize(HMODULE module);
bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2);
template <typename T> inline void Merge(std::vector<T>* target, T* source, size_t length) template <typename T> inline void Merge(std::vector<T>* target, T* source, size_t length)
{ {
if (source) if (source)