[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()
|
||||
{
|
||||
#ifdef PROCTECT_PROCESS
|
||||
|
||||
Utils::Memory::Allocator allocator;
|
||||
|
||||
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();
|
||||
}
|
||||
@ -384,6 +385,8 @@ namespace Components
|
||||
}
|
||||
});
|
||||
|
||||
AntiCheat::AcquireDebugPriviledge(hToken);
|
||||
|
||||
DWORD dwSize = 0;
|
||||
PVOID pTokenInfo = nullptr;
|
||||
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));
|
||||
if (!pDacl || !InitializeAcl(pDacl, dwSize, ACL_REVISION)) return GetLastError();
|
||||
|
||||
// Mimic Protected Process
|
||||
// http://www.microsoft.com/whdc/system/vista/process_vista.mspx
|
||||
// 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;
|
||||
// Just give access to what steam needs
|
||||
static const DWORD dwPoison = 0UL | ~(SYNCHRONIZE | GENERIC_EXECUTE | GENERIC_ALL);
|
||||
|
||||
if (!AddAccessDeniedAce(pDacl, ACL_REVISION, dwPoison, psidArray[0])) return GetLastError();
|
||||
|
||||
// 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();
|
||||
|
||||
// Because of ACE ordering, System will effectively have dwAllowed even
|
||||
@ -495,6 +488,19 @@ namespace Components
|
||||
return 0;
|
||||
#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()
|
||||
{
|
||||
|
@ -28,6 +28,8 @@ namespace Components
|
||||
static void ScanIntegrityCheck();
|
||||
static void FlagIntegrityCheck();
|
||||
|
||||
static unsigned long ProtectProcess();
|
||||
|
||||
private:
|
||||
enum IntergrityFlag
|
||||
{
|
||||
@ -50,8 +52,6 @@ namespace Components
|
||||
static void PerformScan();
|
||||
static void PatchWinAPI();
|
||||
|
||||
static unsigned long ProtectProcess();
|
||||
|
||||
static void NullSub();
|
||||
|
||||
static void AssertCalleeModule(void* callee);
|
||||
@ -75,6 +75,8 @@ namespace Components
|
||||
static void DObjGetWorldTagPosStub();
|
||||
static void AimTargetGetTagPosStub();
|
||||
|
||||
static void AcquireDebugPriviledge(HANDLE hToken);
|
||||
|
||||
static Utils::Hook LoadLibHook[4];
|
||||
};
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace Components
|
||||
|
||||
void Stats::UpdateClasses(UIScript::Token)
|
||||
{
|
||||
SendStats();
|
||||
Stats::SendStats();
|
||||
}
|
||||
|
||||
Stats::Stats()
|
||||
|
@ -61,6 +61,13 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_ANTICHEAT
|
||||
[]()
|
||||
{
|
||||
Utils::Hook::Interceptor::Install(_AddressOfReturnAddress(), Components::AntiCheat::ProtectProcess);
|
||||
}();
|
||||
#endif
|
||||
|
||||
DWORD oldProtect;
|
||||
std::uint8_t* module = reinterpret_cast<std::uint8_t*>(GetModuleHandle(nullptr));
|
||||
//VirtualProtect(module, 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect); // Unprotect the entire process
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <d3d9.h>
|
||||
#include <Aclapi.h>
|
||||
#include <Psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
@ -44,6 +44,11 @@ namespace Utils
|
||||
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)())
|
||||
{
|
||||
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
||||
|
@ -34,6 +34,7 @@ namespace Utils
|
||||
class Interceptor
|
||||
{
|
||||
public:
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
unsigned long GetParentProcessId();
|
||||
|
||||
template <typename T> inline void Merge(std::vector<T>* target, T* source, size_t length)
|
||||
{
|
||||
if (source)
|
||||
|
Loading…
Reference in New Issue
Block a user