[AntiCheat] More process security and debug priviledge acquisition
This commit is contained in:
parent
b2b20e5a1c
commit
1b4393f095
@ -357,12 +357,13 @@ namespace Components
|
|||||||
unsigned long AntiCheat::ProtectProcess()
|
unsigned long AntiCheat::ProtectProcess()
|
||||||
{
|
{
|
||||||
#ifdef PROCTECT_PROCESS
|
#ifdef PROCTECT_PROCESS
|
||||||
|
|
||||||
Utils::Memory::Allocator allocator;
|
Utils::Memory::Allocator allocator;
|
||||||
|
|
||||||
HANDLE hToken = nullptr;
|
HANDLE hToken = nullptr;
|
||||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken))
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_READ, &hToken))
|
||||||
{
|
{
|
||||||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &hToken))
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_READ, TRUE, &hToken))
|
||||||
{
|
{
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
@ -384,6 +385,8 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AntiCheat::AcquireDebugPriviledge(hToken);
|
||||||
|
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
PVOID pTokenInfo = nullptr;
|
PVOID pTokenInfo = nullptr;
|
||||||
if (GetTokenInformation(hToken, TokenUser, nullptr, 0, &dwSize) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return GetLastError();
|
if (GetTokenInformation(hToken, TokenUser, nullptr, 0, &dwSize) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return GetLastError();
|
||||||
@ -438,23 +441,13 @@ namespace Components
|
|||||||
PACL pDacl = reinterpret_cast<PACL>(allocator.allocate(dwSize));
|
PACL pDacl = reinterpret_cast<PACL>(allocator.allocate(dwSize));
|
||||||
if (!pDacl || !InitializeAcl(pDacl, dwSize, ACL_REVISION)) return GetLastError();
|
if (!pDacl || !InitializeAcl(pDacl, dwSize, ACL_REVISION)) return GetLastError();
|
||||||
|
|
||||||
// Mimic Protected Process
|
// Just give access to what steam needs
|
||||||
// http://www.microsoft.com/whdc/system/vista/process_vista.mspx
|
static const DWORD dwPoison = 0UL | ~(SYNCHRONIZE | GENERIC_EXECUTE | GENERIC_ALL);
|
||||||
// Protected processes allow PROCESS_TERMINATE, which is
|
|
||||||
// probably not appropriate for high integrity software.
|
|
||||||
static const DWORD dwPoison =
|
|
||||||
/*READ_CONTROL |*/ WRITE_DAC | WRITE_OWNER |
|
|
||||||
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
|
||||||
PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION |
|
|
||||||
PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
|
||||||
PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE |
|
|
||||||
// In addition to protected process
|
|
||||||
PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE;
|
|
||||||
|
|
||||||
if (!AddAccessDeniedAce(pDacl, ACL_REVISION, dwPoison, psidArray[0])) return GetLastError();
|
if (!AddAccessDeniedAce(pDacl, ACL_REVISION, dwPoison, psidArray[0])) return GetLastError();
|
||||||
|
|
||||||
// Standard and specific rights not explicitly denied
|
// Standard and specific rights not explicitly denied
|
||||||
static const DWORD dwAllowed = (~dwPoison & 0x1FFF) | SYNCHRONIZE;
|
static const DWORD dwAllowed = 0UL | SYNCHRONIZE;
|
||||||
if (!AddAccessAllowedAce(pDacl, ACL_REVISION, dwAllowed, psidArray[1])) return GetLastError();
|
if (!AddAccessAllowedAce(pDacl, ACL_REVISION, dwAllowed, psidArray[1])) return GetLastError();
|
||||||
|
|
||||||
// Because of ACE ordering, System will effectively have dwAllowed even
|
// Because of ACE ordering, System will effectively have dwAllowed even
|
||||||
@ -495,6 +488,19 @@ namespace Components
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void AntiCheat::AcquireDebugPriviledge(HANDLE hToken)
|
||||||
|
{
|
||||||
|
LUID luid;
|
||||||
|
TOKEN_PRIVILEGES tp = { 0 };
|
||||||
|
DWORD cb = sizeof(TOKEN_PRIVILEGES);
|
||||||
|
if (!LookupPrivilegeValueW(nullptr, SE_DEBUG_NAME, &luid)) return;
|
||||||
|
|
||||||
|
tp.PrivilegeCount = 1;
|
||||||
|
tp.Privileges[0].Luid = luid;
|
||||||
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
AdjustTokenPrivileges(hToken, FALSE, &tp, cb, nullptr, nullptr);
|
||||||
|
//if (GetLastError() != ERROR_SUCCESS) return;
|
||||||
|
}
|
||||||
|
|
||||||
AntiCheat::AntiCheat()
|
AntiCheat::AntiCheat()
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,8 @@ namespace Components
|
|||||||
static void ScanIntegrityCheck();
|
static void ScanIntegrityCheck();
|
||||||
static void FlagIntegrityCheck();
|
static void FlagIntegrityCheck();
|
||||||
|
|
||||||
|
static unsigned long ProtectProcess();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum IntergrityFlag
|
enum IntergrityFlag
|
||||||
{
|
{
|
||||||
@ -50,8 +52,6 @@ namespace Components
|
|||||||
static void PerformScan();
|
static void PerformScan();
|
||||||
static void PatchWinAPI();
|
static void PatchWinAPI();
|
||||||
|
|
||||||
static unsigned long ProtectProcess();
|
|
||||||
|
|
||||||
static void NullSub();
|
static void NullSub();
|
||||||
|
|
||||||
static void AssertCalleeModule(void* callee);
|
static void AssertCalleeModule(void* callee);
|
||||||
@ -75,6 +75,8 @@ namespace Components
|
|||||||
static void DObjGetWorldTagPosStub();
|
static void DObjGetWorldTagPosStub();
|
||||||
static void AimTargetGetTagPosStub();
|
static void AimTargetGetTagPosStub();
|
||||||
|
|
||||||
|
static void AcquireDebugPriviledge(HANDLE hToken);
|
||||||
|
|
||||||
static Utils::Hook LoadLibHook[4];
|
static Utils::Hook LoadLibHook[4];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ namespace Components
|
|||||||
|
|
||||||
void Stats::UpdateClasses(UIScript::Token)
|
void Stats::UpdateClasses(UIScript::Token)
|
||||||
{
|
{
|
||||||
SendStats();
|
Stats::SendStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stats::Stats()
|
Stats::Stats()
|
||||||
|
@ -61,6 +61,13 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_ANTICHEAT
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
Utils::Hook::Interceptor::Install(_AddressOfReturnAddress(), Components::AntiCheat::ProtectProcess);
|
||||||
|
}();
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD oldProtect;
|
DWORD oldProtect;
|
||||||
std::uint8_t* module = reinterpret_cast<std::uint8_t*>(GetModuleHandle(nullptr));
|
std::uint8_t* module = reinterpret_cast<std::uint8_t*>(GetModuleHandle(nullptr));
|
||||||
//VirtualProtect(module, 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect); // Unprotect the entire process
|
//VirtualProtect(module, 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect); // Unprotect the entire process
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include <Aclapi.h>
|
#include <Aclapi.h>
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -44,6 +44,11 @@ namespace Utils
|
|||||||
Hook::Signature::signatures.push_back(container);
|
Hook::Signature::signatures.push_back(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hook::Interceptor::Install(void* place, void* stub)
|
||||||
|
{
|
||||||
|
return Hook::Interceptor::Install(place, static_cast<void(*)()>(stub));
|
||||||
|
}
|
||||||
|
|
||||||
void Hook::Interceptor::Install(void* place, void(*stub)())
|
void Hook::Interceptor::Install(void* place, void(*stub)())
|
||||||
{
|
{
|
||||||
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
||||||
|
@ -34,6 +34,7 @@ namespace Utils
|
|||||||
class Interceptor
|
class Interceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static void Install(void* place, void* stub);
|
||||||
static void Install(void* place, void(*stub)());
|
static void Install(void* place, void(*stub)());
|
||||||
static void Install(void** place, void(*stub)());
|
static void Install(void** place, void(*stub)());
|
||||||
|
|
||||||
|
@ -47,4 +47,28 @@ namespace Utils
|
|||||||
|
|
||||||
return (GetProcAddress(hntdll, "wine_get_version") != nullptr);
|
return (GetProcAddress(hntdll, "wine_get_version") != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long GetParentProcessId()
|
||||||
|
{
|
||||||
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
|
||||||
|
|
||||||
|
Utils::Memory::Allocator allocator;
|
||||||
|
allocator.reference(hSnapshot, [](void* handle) { CloseHandle(handle); });
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe32;
|
||||||
|
ZeroMemory(&pe32, sizeof(pe32));
|
||||||
|
pe32.dwSize = sizeof(pe32);
|
||||||
|
|
||||||
|
DWORD pid = GetCurrentProcessId();
|
||||||
|
while (Process32Next(hSnapshot, &pe32))
|
||||||
|
{
|
||||||
|
if (pe32.th32ProcessID == pid)
|
||||||
|
{
|
||||||
|
return pe32.th32ParentProcessID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ namespace Utils
|
|||||||
|
|
||||||
bool IsWineEnvironment();
|
bool IsWineEnvironment();
|
||||||
|
|
||||||
|
unsigned long GetParentProcessId();
|
||||||
|
|
||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user