From 16f180d08d5d10717d01624158ecc702884e451c Mon Sep 17 00:00:00 2001 From: Diavolo Date: Fri, 15 Apr 2022 11:16:22 +0200 Subject: [PATCH] Remove anticheat (Gone FNAF) --- .github/workflows/build.yml | 2 +- README.md | 3 - generate.bat | 2 +- premake5.lua | 24 - src/Components/Loader.cpp | 1 - src/Components/Loader.hpp | 1 - src/Components/Modules/AntiCheat.cpp | 891 ------------------------ src/Components/Modules/AntiCheat.hpp | 120 ---- src/Components/Modules/CardTitles.cpp | 3 - src/Components/Modules/Changelog.cpp | 4 - src/Components/Modules/Discovery.cpp | 10 - src/Components/Modules/Exception.cpp | 8 - src/Components/Modules/Gametypes.cpp | 10 - src/Components/Modules/Localization.cpp | 7 - src/Components/Modules/Menus.cpp | 144 ++-- src/Components/Modules/ServerList.cpp | 5 - src/Game/Functions.cpp | 2 +- src/Game/Functions.hpp | 50 +- src/Main.cpp | 25 +- src/Utils/Utils.cpp | 4 - 20 files changed, 76 insertions(+), 1240 deletions(-) delete mode 100644 src/Components/Modules/AntiCheat.cpp delete mode 100644 src/Components/Modules/AntiCheat.hpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19cd75f0..e96a3398 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: uses: microsoft/setup-msbuild@v1.1 - name: Generate project files - run: tools/premake5 vs2022 --ac-disable + run: tools/premake5 vs2022 - name: Set up problem matching uses: ammaraskar/msvc-problem-matcher@master diff --git a/README.md b/README.md index fb5dc10a..9c9a36b6 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,6 @@ |:----------------------------|:-----------------------------------------------| | `--copy-to=PATH` | Optional, copy the DLL to a custom folder after build, define the path here if wanted. | | `--copy-pdb` | Copy debug information for binaries as well to the path given via --copy-to. | -| `--ac-disable` | Disable anticheat. | -| `--ac-debug-detections` | Log anticheat detections. | -| `--ac-debug-load-library` | Log libraries that get loaded. | | `--force-unit-tests` | Always compile unit tests. | | `--force-exception-handler` | Install custom unhandled exception handler even for Debug builds. | | `--force-minidump-upload` | Upload minidumps even for Debug builds. | diff --git a/generate.bat b/generate.bat index b3823287..2bad27bb 100644 --- a/generate.bat +++ b/generate.bat @@ -1,4 +1,4 @@ @echo off echo Updating submodules... call git submodule update --init --recursive -call tools\premake5 %* vs2022 --ac-disable +call tools\premake5 %* vs2022 diff --git a/premake5.lua b/premake5.lua index fd88521c..47c2b42f 100644 --- a/premake5.lua +++ b/premake5.lua @@ -71,21 +71,6 @@ newoption { description = "Copy debug information for binaries as well to the path given via --copy-to." } -newoption { - trigger = "ac-disable", - description = "Disable anticheat." -} - -newoption { - trigger = "ac-debug-detections", - description = "Log anticheat detections." -} - -newoption { - trigger = "ac-debug-load-library", - description = "Log libraries that get loaded." -} - newoption { trigger = "force-unit-tests", description = "Always compile unit tests." @@ -274,15 +259,6 @@ workspace "iw4x" } -- Debug flags - if _OPTIONS["ac-disable"] then - defines {"DISABLE_ANTICHEAT"} - end - if _OPTIONS["ac-debug-detections"] then - defines {"DEBUG_DETECTIONS"} - end - if _OPTIONS["ac-debug-load-library"] then - defines {"DEBUG_LOAD_LIBRARY"} - end if _OPTIONS["force-unit-tests"] then defines {"FORCE_UNIT_TESTS"} end diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 08ed4485..ae9bbde7 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -69,7 +69,6 @@ namespace Components Loader::Register(new Renderer()); Loader::Register(new UIFeeder()); Loader::Register(new UIScript()); - Loader::Register(new AntiCheat()); Loader::Register(new Changelog()); Loader::Register(new Dedicated()); Loader::Register(new Discovery()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 9d521bba..23f07b4e 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -99,7 +99,6 @@ namespace Components #include "Modules/RawFiles.hpp" #include "Modules/Renderer.hpp" #include "Modules/UIFeeder.hpp" -#include "Modules/AntiCheat.hpp" #include "Modules/Changelog.hpp" #include "Modules/Dedicated.hpp" #include "Modules/Discovery.hpp" diff --git a/src/Components/Modules/AntiCheat.cpp b/src/Components/Modules/AntiCheat.cpp deleted file mode 100644 index 35f128ae..00000000 --- a/src/Components/Modules/AntiCheat.cpp +++ /dev/null @@ -1,891 +0,0 @@ -#include - -namespace Components -{ - Utils::Time::Interval AntiCheat::LastCheck; - Utils::Hook AntiCheat::CreateThreadHook; - Utils::Hook AntiCheat::LoadLibHook[6]; - Utils::Hook AntiCheat::VirtualProtectHook[2]; - unsigned long AntiCheat::Flags = NO_FLAG; - - std::mutex AntiCheat::ThreadMutex; - std::vector AntiCheat::OwnThreadIds; - std::map> AntiCheat::ThreadHookMap; - - // This function does nothing, it only adds the two passed variables and returns the value - // The only important thing it does is to clean the first parameter, and then return - // By returning, the crash procedure will be called, as it hasn't been cleaned from the stack - __declspec(naked) void AntiCheat::NullSub() - { - __asm - { - push ebp - push ecx - mov ebp, esp - - xor eax, eax - mov eax, [ebp + 8h] - mov ecx, [ebp + 0Ch] - add eax, ecx - - pop ecx - pop ebp - retn 4 - } - } - - void AntiCheat::CrashClient() - { -#ifdef DEBUG_DETECTIONS - Logger::Flush(); - MessageBoxA(nullptr, "Check the log for more information!", "AntiCheat triggered", MB_ICONERROR); - ExitProcess(0xFFFFFFFF); -#else - static std::thread triggerThread; - if (!triggerThread.joinable()) - { - triggerThread = std::thread([]() - { - std::this_thread::sleep_for(43s); - Utils::Hook::Set(0x41BA2C, 0xEB); - }); - } -#endif - } - - void AntiCheat::AssertCalleeModule(void* callee) - { - HMODULE hModuleSelf = nullptr, hModuleTarget = nullptr, hModuleProcess = GetModuleHandleA(nullptr); - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(callee), &hModuleTarget); - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(AntiCheat::AssertCalleeModule), &hModuleSelf); - - if (!hModuleSelf || !hModuleTarget || !hModuleProcess || (hModuleTarget != hModuleSelf && hModuleTarget != hModuleProcess)) - { -#ifdef DEBUG_DETECTIONS - char buffer[MAX_PATH] = { 0 }; - GetModuleFileNameA(hModuleTarget, buffer, sizeof buffer); - - Logger::Print(Utils::String::VA("AntiCheat: Callee assertion failed: %X %s", reinterpret_cast(callee), buffer)); -#endif - - AntiCheat::CrashClient(); - } - } - - void AntiCheat::InitLoadLibHook() - { - static uint8_t kernel32Str[] = { 0xB4, 0x9A, 0x8D, 0xB1, 0x9A, 0x93, 0xCC, 0xCD, 0xD1, 0x9B, 0x93, 0x93 }; // KerNel32.dll - static uint8_t loadLibAStr[] = { 0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xBE }; // LoadLibraryA - static uint8_t loadLibWStr[] = { 0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xA8 }; // LoadLibraryW - - HMODULE kernel32 = GetModuleHandleA(Utils::String::XOR(std::string(reinterpret_cast(kernel32Str), sizeof kernel32Str), -1).data()); - if (kernel32) - { - FARPROC loadLibA = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast(loadLibAStr), sizeof loadLibAStr), -1).data()); - FARPROC loadLibW = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast(loadLibWStr), sizeof loadLibWStr), -1).data()); - - std::string libExA = Utils::String::XOR(std::string(reinterpret_cast(loadLibAStr), sizeof loadLibAStr), -1); - std::string libExW = Utils::String::XOR(std::string(reinterpret_cast(loadLibWStr), sizeof loadLibWStr), -1); - - libExA.insert(libExA.end() - 1, 'E'); - libExA.insert(libExA.end() - 1, 'x'); - - libExW.insert(libExW.end() - 1, 'E'); - libExW.insert(libExW.end() - 1, 'x'); - - FARPROC loadLibExA = GetProcAddress(kernel32, libExA.data()); - FARPROC loadLibExW = GetProcAddress(kernel32, libExW.data()); - - if (loadLibA && loadLibW && loadLibExA && loadLibExW) - { -#ifdef DEBUG_LOAD_LIBRARY - AntiCheat::LoadLibHook[0].initialize(loadLibA, LoadLibaryAStub, HOOK_JUMP); - AntiCheat::LoadLibHook[1].initialize(loadLibW, LoadLibaryWStub, HOOK_JUMP); - AntiCheat::LoadLibHook[2].initialize(loadLibExA, LoadLibaryExAStub, HOOK_JUMP); - AntiCheat::LoadLibHook[3].initialize(loadLibExW, LoadLibaryExWStub, HOOK_JUMP); -#else - static uint8_t loadLibStub[] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 }; // xor eax, eax; retn 04h - static uint8_t loadLibExStub[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00 }; // xor eax, eax; retn 0Ch - AntiCheat::LoadLibHook[0].initialize(loadLibA, loadLibStub, HOOK_JUMP); - AntiCheat::LoadLibHook[1].initialize(loadLibW, loadLibStub, HOOK_JUMP); - AntiCheat::LoadLibHook[2].initialize(loadLibExA, loadLibExStub, HOOK_JUMP); - AntiCheat::LoadLibHook[3].initialize(loadLibExW, loadLibExStub, HOOK_JUMP); -#endif - } - } - - static uint8_t ldrLoadDllStub[] = { 0x33, 0xC0, 0xC2, 0x10, 0x00 }; - static uint8_t ldrLoadDll[] = { 0xB3, 0x9B, 0x8D, 0xB3, 0x90, 0x9E, 0x9B, 0xBB, 0x93, 0x93 }; // LdrLoadDll - - HMODULE ntdll = Utils::GetNTDLL(); - //AntiCheat::LoadLibHook[4].initialize(GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast(ldrLoadDll), sizeof ldrLoadDll), -1).data()), ldrLoadDllStub, HOOK_JUMP); - - // Patch LdrpLoadDll - Utils::Hook::Signature::Container container; - container.signature = "\x8B\xFF\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\x00\x00\x00\x00\xA1\x00\x00\x00\x00\x33\xC4\x89\x84\x24\x00\x00\x00\x00\x53\x8B\x5D\x10\x56\x57"; - container.mask = "xxxxxxxxxx????x????xxxxx????xxxxxx"; - container.callback = [](char* addr) - { - static uint8_t ldrpLoadDllStub[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00 }; - AntiCheat::LoadLibHook[5].initialize(addr, ldrpLoadDllStub, HOOK_JUMP); - }; - - Utils::Hook::Signature signature(ntdll, Utils::GetModuleSize(ntdll)); - signature.add(container); - //signature.process(); - } - - void AntiCheat::ReadIntegrityCheck() - { -#ifdef PROCTECT_PROCESS - static Utils::Time::Interval check; - - if (check.elapsed(20s)) - { - check.update(); - - if (HANDLE h = OpenProcess(PROCESS_VM_READ, FALSE, GetCurrentProcessId())) - { -#ifdef DEBUG_DETECTIONS - Logger::Print("AntiCheat: Process integrity check failed"); -#endif - - CloseHandle(h); - AntiCheat::CrashClient(); - } - } - - // Set the integrity flag - AntiCheat::Flags |= AntiCheat::IntergrityFlag::READ_INTEGRITY_CHECK; -#endif - } - - void AntiCheat::FlagIntegrityCheck() - { - static Utils::Time::Interval check; - - if (check.elapsed(30s)) - { - check.update(); - - unsigned long flags = ((AntiCheat::IntergrityFlag::MAX_FLAG - 1) << 1) - 1; - - if (AntiCheat::Flags != flags) - { -#ifdef DEBUG_DETECTIONS - Logger::Print(Utils::String::VA("AntiCheat: Flag integrity check failed: %X", AntiCheat::Flags)); -#endif - - AntiCheat::CrashClient(); - } - } - } - - void AntiCheat::ScanIntegrityCheck() - { - // If there was no check within the last 40 seconds, crash! - if (AntiCheat::LastCheck.elapsed(40s)) - { -#ifdef DEBUG_DETECTIONS - Logger::Print("AntiCheat: Integrity check failed"); -#endif - - AntiCheat::CrashClient(); - } - - // Set the integrity flag - AntiCheat::Flags |= AntiCheat::IntergrityFlag::SCAN_INTEGRITY_CHECK; - } - - void AntiCheat::PerformScan() - { - static std::optional hashVal; - - // Perform check only every 20 seconds - if (!AntiCheat::LastCheck.elapsed(20s)) return; - AntiCheat::LastCheck.update(); - - // Hash .text segment - // Add 1 to each value, so searching in memory doesn't reveal anything - size_t textSize = 0x2D6001; - char* textBase = reinterpret_cast(0x401001); - - unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(textBase - 1, textSize - 1); - - // Set the hash, if none is set - if (!hashVal.has_value()) - { - hashVal.emplace(hash); - } - // Crash if the hashes don't match - else if (hashVal.value() != hash) - { -#ifdef DEBUG_DETECTIONS - Logger::Print("AntiCheat: Memory scan failed"); -#endif - - AntiCheat::CrashClient(); - } - - // Set the memory scan flag - AntiCheat::Flags |= AntiCheat::IntergrityFlag::MEMORY_SCAN; - } - - void AntiCheat::QuickCodeScanner1() - { - static Utils::Time::Interval interval; - static std::optional hashVal; - - if (!interval.elapsed(32s)) return; - interval.update(); - - // Hash .text segment - // Add 1 to each value, so searching in memory doesn't reveal anything - size_t textSize = 0x2D5FFF; - char* textBase = reinterpret_cast(0x400FFF); - unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(textBase + 1, textSize + 1); - - if (hashVal.has_value() && hash != hashVal.value()) - { - Utils::Hook::Set(0x42A667, 0x90); // Crash - } - - hashVal.emplace(hash); - } - - void AntiCheat::QuickCodeScanner2() - { - static Utils::Time::Interval interval; - static std::optional hashVal; - - if (!interval.elapsed(42s)) return; - interval.update(); - - // Hash .text segment - unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(reinterpret_cast(0x401000), 0x2D6000); - if (hashVal.has_value() && hash != hashVal.value()) - { - Utils::Hook::Set(0x40797C, 0x90); // Crash - } - - hashVal.emplace(hash); - } - -#ifdef DEBUG_LOAD_LIBRARY - HANDLE AntiCheat::LoadLibary(std::wstring library, HANDLE file, DWORD flags, void* callee) - { - HMODULE module; - char buffer[MAX_PATH] = { 0 }; - - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(callee), &module); - GetModuleFileNameA(module, buffer, sizeof buffer); - - MessageBoxA(nullptr, Utils::String::VA("Loading library %s via %s %X", std::string(library.begin(), library.end()).data(), buffer, reinterpret_cast(callee)), nullptr, 0); - - AntiCheat::LoadLibHook[3].uninstall(); - HANDLE h = LoadLibraryExW(library.data(), file, flags); - AntiCheat::LoadLibHook[3].install(); - return h; - } - - HANDLE WINAPI AntiCheat::LoadLibaryAStub(const char* library) - { - std::string lib(library); - return AntiCheat::LoadLibary(std::wstring(lib.begin(), lib.end()), nullptr, 0, _ReturnAddress()); - } - - HANDLE WINAPI AntiCheat::LoadLibaryWStub(const wchar_t* library) - { - return AntiCheat::LoadLibary(library, nullptr, 0, _ReturnAddress()); - } - - HANDLE WINAPI AntiCheat::LoadLibaryExAStub(const char* library, HANDLE file, DWORD flags) - { - std::string lib(library); - return AntiCheat::LoadLibary(std::wstring(lib.begin(), lib.end()), file, flags, _ReturnAddress()); - } - - HANDLE WINAPI AntiCheat::LoadLibaryExWStub(const wchar_t* library, HANDLE file, DWORD flags) - { - return AntiCheat::LoadLibary(library, file, flags, _ReturnAddress()); - } -#endif - - void AntiCheat::UninstallLibHook() - { - for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) - { - AntiCheat::LoadLibHook[i].uninstall(); - } - } - - void AntiCheat::InstallLibHook() - { - for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) - { - AntiCheat::LoadLibHook[i].install(); - } - } - - void AntiCheat::PatchWinAPI() - { - LibUnlocker _; - - // Initialize directx - Utils::Hook::Call(0x5078C0)(); - } - - void AntiCheat::SoundInitStub(int a1, int a2, int a3) - { - LibUnlocker _; - Game::SND_Init(a1, a2, a3); - } - - void AntiCheat::SoundInitDriverStub() - { - LibUnlocker _; - Game::SND_InitDriver(); - } - - void AntiCheat::LostD3DStub() - { - LibUnlocker _; - - // Reset directx - Utils::Hook::Call(0x508070)(); - } - - __declspec(naked) void AntiCheat::CinematicStub() - { - __asm - { - pushad - call AntiCheat::UninstallLibHook - popad - - call Game::R_Cinematic_StartPlayback_Now - - pushad - call AntiCheat::InstallLibHook - popad - - retn - } - } - - __declspec(naked) void AntiCheat::DObjGetWorldTagPosStub() - { - __asm - { - pushad - push [esp + 20h] - - call AntiCheat::AssertCalleeModule - - pop esi - popad - - push ecx - mov ecx, [esp + 10h] - - push 426585h - retn - } - } - - __declspec(naked) void AntiCheat::AimTargetGetTagPosStub() - { - __asm - { - pushad - push [esp + 20h] - - call AntiCheat::AssertCalleeModule - - pop esi - popad - - sub esp, 14h - cmp dword ptr[esi + 0E0h], 1 - push 56AC6Ah - ret - } - } - - 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(callee), &hModuleTarget); - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(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 (GetCurrentProcessId() == GetProcessId(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() - { -#ifdef PROCTECT_PROCESS - - Utils::Memory::Allocator allocator; - - HANDLE hToken = nullptr; - if (!OpenProcessToken(GetCurrentProcess(), /*TOKEN_ADJUST_PRIVILEGES | */TOKEN_READ, &hToken)) - { - if (!OpenThreadToken(GetCurrentThread(), /*TOKEN_ADJUST_PRIVILEGES | */TOKEN_READ, TRUE, &hToken)) - { - return GetLastError(); - } - } - - auto freeSid = [](void* sid) - { - if (sid) - { - FreeSid(reinterpret_cast(sid)); - } - }; - - allocator.reference(hToken, [](void* hToken) - { - if (hToken) - { - CloseHandle(hToken); - } - }); - - //AntiCheat::AcquireDebugPrivilege(hToken); - - DWORD dwSize = 0; - PVOID pTokenInfo = nullptr; - if (GetTokenInformation(hToken, TokenUser, nullptr, 0, &dwSize) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return GetLastError(); - - if (dwSize) - { - pTokenInfo = allocator.allocate(dwSize); - if (!pTokenInfo) return GetLastError(); - } - - if (!GetTokenInformation(hToken, TokenUser, pTokenInfo, dwSize, &dwSize) || !pTokenInfo) return GetLastError(); - - PSID psidCurUser = reinterpret_cast(pTokenInfo)->User.Sid; - - PSID psidEveryone = nullptr; - SID_IDENTIFIER_AUTHORITY sidEveryone = SECURITY_WORLD_SID_AUTHORITY; - if (!AllocateAndInitializeSid(&sidEveryone, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psidEveryone) || !psidEveryone) return GetLastError(); - allocator.reference(psidEveryone, freeSid); - - PSID psidSystem = nullptr; - SID_IDENTIFIER_AUTHORITY sidSystem = SECURITY_NT_AUTHORITY; - if (!AllocateAndInitializeSid(&sidSystem, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psidSystem) || !psidSystem) return GetLastError(); - allocator.reference(psidSystem, freeSid); - - PSID psidAdmins = nullptr; - SID_IDENTIFIER_AUTHORITY sidAdministrators = SECURITY_NT_AUTHORITY; - if (!AllocateAndInitializeSid(&sidAdministrators, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmins) || !psidAdmins) return GetLastError(); - allocator.reference(psidAdmins, freeSid); - - const PSID psidArray[] = - { - psidEveryone, /* Deny most rights to everyone */ - psidCurUser, /* Allow what was not denied */ - psidSystem, /* Full control */ - psidAdmins, /* Full control */ - }; - - // Determine required size of the ACL - dwSize = sizeof(ACL); - - // First the DENY, then the ALLOW - dwSize += GetLengthSid(psidArray[0]); - dwSize += sizeof(ACCESS_DENIED_ACE) - sizeof(DWORD); - - for (UINT i = 1; i < _countof(psidArray); ++i) - { - // DWORD is the SidStart field, which is not used for absolute format - dwSize += GetLengthSid(psidArray[i]); - dwSize += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD); - } - - PACL pDacl = reinterpret_cast(allocator.allocate(dwSize)); - if (!pDacl || !InitializeAcl(pDacl, dwSize, ACL_REVISION)) return GetLastError(); - - // Just give access to what steam needs - //static const DWORD dwPoison = 0UL | ~(SYNCHRONIZE | GENERIC_EXECUTE | GENERIC_ALL); - 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(); - - // Standard and specific rights not explicitly denied - //static const DWORD dwAllowed = 0UL | SYNCHRONIZE; - static const DWORD dwAllowed = (~dwPoison & 0x1FFF) | SYNCHRONIZE; - if (!AddAccessAllowedAce(pDacl, ACL_REVISION, dwAllowed, psidArray[1])) return GetLastError(); - - // Because of ACE ordering, System will effectively have dwAllowed even - // though the ACE specifies PROCESS_ALL_ACCESS (unless software uses - // SeDebugPrivilege or SeTcbName and increases access). - // As an exercise, check behavior of tools such as Process Explorer under XP, - // Vista, and above. Vista and above should exhibit slightly different behavior - // due to Restricted tokens. - if (!AddAccessAllowedAce(pDacl, ACL_REVISION, PROCESS_ALL_ACCESS, psidArray[2])) return GetLastError(); - - // Because of ACE ordering, Administrators will effectively have dwAllowed - // even though the ACE specifies PROCESS_ALL_ACCESS (unless the Administrator - // invokes 'discretionary security' by taking ownership and increasing access). - // As an exercise, check behavior of tools such as Process Explorer under XP, - // Vista, and above. Vista and above should exhibit slightly different behavior - // due to Restricted tokens. - if (!AddAccessAllowedAce(pDacl, ACL_REVISION, PROCESS_ALL_ACCESS, psidArray[3])) return GetLastError(); - - PSECURITY_DESCRIPTOR pSecDesc = allocator.allocate(); - if (!pSecDesc) return GetLastError(); - - // InitializeSecurityDescriptor initializes a security descriptor in - // absolute format, rather than self-relative format. See - // http://msdn.microsoft.com/en-us/library/aa378863(VS.85).aspx - if (!InitializeSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION)) return GetLastError(); - if (!SetSecurityDescriptorDacl(pSecDesc, TRUE, pDacl, FALSE)) return GetLastError(); - - return SetSecurityInfo( - GetCurrentProcess(), - SE_KERNEL_OBJECT, // process object - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - psidCurUser, // NULL, // Owner SID - nullptr, // Group SID - pDacl, - nullptr // SACL - ); -#else - return 0; -#endif - } - - void AntiCheat::AcquireDebugPrivilege(HANDLE hToken) - { - LUID luid; - TOKEN_PRIVILEGES tp = { 0 }; - DWORD cb = sizeof(TOKEN_PRIVILEGES); - if (!LookupPrivilegeValueA(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; - } - - 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); - } - - NTSTATUS NTAPI AntiCheat::NtCreateThreadExStub(PHANDLE phThread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPTHREAD_START_ROUTINE startAddress, LPVOID parameter, BOOL createSuspended, DWORD stackZeroBits, DWORD sizeOfStackCommit, DWORD sizeOfStackReserve, LPVOID bytesBuffer) - { - HANDLE hThread = nullptr; - std::lock_guard _(AntiCheat::ThreadMutex); - - AntiCheat::CreateThreadHook.uninstall(); - NTSTATUS result = NtCreateThreadEx_t(AntiCheat::CreateThreadHook.getAddress())(&hThread, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits, sizeOfStackCommit, sizeOfStackReserve, bytesBuffer); - AntiCheat::CreateThreadHook.install(); - - if (phThread) *phThread = hThread; - - if (GetProcessId(processHandle) == GetCurrentProcessId()) - { - AntiCheat::OwnThreadIds.push_back(GetThreadId(hThread)); - } - - return result; - } - - void AntiCheat::PatchThreadCreation() - { - HMODULE ntdll = Utils::GetNTDLL(); - if (ntdll) - { - static uint8_t ntCreateThreadEx[] = { 0xB1, 0x8B, 0xBC, 0x8D, 0x9A, 0x9E, 0x8B, 0x9A, 0xAB, 0x97, 0x8D, 0x9A, 0x9E, 0x9B, 0xBA, 0x87 }; // NtCreateThreadEx - FARPROC createThread = GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast(ntCreateThreadEx), sizeof ntCreateThreadEx), -1).data()); - if (createThread) - { - AntiCheat::CreateThreadHook.initialize(createThread, AntiCheat::NtCreateThreadExStub, HOOK_JUMP)->install(); - } - } - } - - int AntiCheat::ValidateThreadTermination(void* addr) - { - { - std::lock_guard _(AntiCheat::ThreadMutex); - - DWORD id = GetCurrentThreadId(); - if (const auto threadHook = AntiCheat::ThreadHookMap.find(id); threadHook != AntiCheat::ThreadHookMap.end()) - { - threadHook->second->uninstall(false); - AntiCheat::ThreadHookMap.erase(threadHook); // Uninstall and delete the hook - return 1; // Kill - } - } - - while (true) - { - std::lock_guard _(AntiCheat::ThreadMutex); - - // It would be better to wait for the thread - // but we don't know if there are multiple hooks at the same address - bool found = false; - for (const auto& threadHook : AntiCheat::ThreadHookMap) - { - if (threadHook.second->getAddress() == addr) - { - found = true; - break; - } - } - - if (!found) break; - std::this_thread::sleep_for(10ms); - } - - return 0; // Don't kill - } - - __declspec(naked) void AntiCheat::ThreadEntryPointStub() - { - __asm - { - push eax - push eax - pushad - - // Reinitialize the return address - mov eax, [esp + 28h] - sub eax, 5 - mov [esp + 28h], eax - - push eax - call AntiCheat::ValidateThreadTermination - add esp, 4h - - mov [esp + 20h], eax - - popad - - pop eax - - test eax, eax - jz dontKill - - pop eax - add esp, 4h // Remove return address (simulate a jump hook) - retn - - dontKill: - pop eax - retn - } - } - - void AntiCheat::VerifyThreadIntegrity() - { - bool kill = true; - { - std::lock_guard _(AntiCheat::ThreadMutex); - - auto threadHook = std::find(AntiCheat::OwnThreadIds.begin(), AntiCheat::OwnThreadIds.end(), GetCurrentThreadId()); - if (threadHook != AntiCheat::OwnThreadIds.end()) - { - AntiCheat::OwnThreadIds.erase(threadHook); - kill = false; - } - } - - if (kill) - { - static bool first = true; - if (first) first = false; // We can't control the main thread, as it's spawned externally - else - { - std::lock_guard _(AntiCheat::ThreadMutex); - - HMODULE ntdll = Utils::GetNTDLL(), targetModule; - if (!ntdll) return; // :( - - void* address = Utils::GetThreadStartAddress(GetCurrentThread()); - if (address) - { - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(address), &targetModule); - if (targetModule == ntdll) return; // Better not kill kernel threads - - DWORD id = GetCurrentThreadId(); - { - auto threadHook = AntiCheat::ThreadHookMap.find(id); - if (threadHook != AntiCheat::ThreadHookMap.end()) - { - threadHook->second->uninstall(false); - AntiCheat::ThreadHookMap.erase(threadHook); - } - } - - std::shared_ptr hook = std::make_shared(); - AntiCheat::ThreadHookMap[id] = hook; - - // Hook the entry point of the thread to properly terminate it - hook->initialize(address, AntiCheat::ThreadEntryPointStub, HOOK_CALL)->install(true, true); - } - } - } - } - - void AntiCheat::SystemTimeDiff(LPSYSTEMTIME stA, LPSYSTEMTIME stB, LPSYSTEMTIME stC) - { - FILETIME ftA, ftB, ftC; - ULARGE_INTEGER uiA, uiB, uiC; - - SystemTimeToFileTime(stA, &ftA); - SystemTimeToFileTime(stB, &ftB); - uiA.HighPart = ftA.dwHighDateTime; - uiA.LowPart = ftA.dwLowDateTime; - uiB.HighPart = ftB.dwHighDateTime; - uiB.LowPart = ftB.dwLowDateTime; - - uiC.QuadPart = uiA.QuadPart - uiB.QuadPart; - - ftC.dwHighDateTime = uiC.HighPart; - ftC.dwLowDateTime = uiC.LowPart; - FileTimeToSystemTime(&ftC, stC); - } - - void AntiCheat::CheckStartupTime() - { - FILETIME creation, exit, kernel, user; - SYSTEMTIME current, creationSt, diffSt; - - GetSystemTime(¤t); - GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user); - - FileTimeToSystemTime(&creation, &creationSt); - AntiCheat::SystemTimeDiff(¤t, &creationSt, &diffSt); - -#ifdef DEBUG - char buf[512]; - snprintf(buf, 512, "creation: %d:%d:%d:%d\n", creationSt.wHour, creationSt.wMinute, creationSt.wSecond, creationSt.wMilliseconds); - OutputDebugStringA(buf); - - snprintf(buf, 512, "current: %d:%d:%d:%d\n", current.wHour, current.wMinute, current.wSecond, current.wMilliseconds); - OutputDebugStringA(buf); - - snprintf(buf, 512, "diff: %d:%d:%d:%d\n", diffSt.wHour, diffSt.wMinute, diffSt.wSecond, diffSt.wMilliseconds); - OutputDebugStringA(buf); -#endif - - // crash client if they are using process suspension to inject dlls during startup (aka before we got to here) - // maybe tweak this value depending on what the above logging reveals during testing, - // but 5 seconds seems about right for now - int time = diffSt.wMilliseconds + (diffSt.wSecond * 1000) + (diffSt.wMinute * 1000 * 60); - if (time > 5000) - { - Components::AntiCheat::CrashClient(); - } - - // use below for logging when using StartSuspended.exe - // FILE* f = fopen("times.txt", "a"); - // fwrite(buf, 1, strlen(buf), f); - // fclose(f); - } - - AntiCheat::AntiCheat() - { - time(nullptr); - AntiCheat::Flags = NO_FLAG; - -#ifndef DISABLE_ANTICHEAT - - Utils::Hook(0x507BD5, AntiCheat::PatchWinAPI, HOOK_CALL).install()->quick(); - Utils::Hook(0x5082FD, AntiCheat::LostD3DStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x51C76C, AntiCheat::CinematicStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x418209, AntiCheat::SoundInitStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x60BE9D, AntiCheat::SoundInitStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x60BE8E, AntiCheat::SoundInitDriverStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x418204, AntiCheat::SoundInitDriverStub, HOOK_CALL).install()->quick(); - Scheduler::OnFrame(AntiCheat::PerformScan, true); - - // Detect aimbots - Utils::Hook(0x426580, AntiCheat::DObjGetWorldTagPosStub, HOOK_JUMP).install()->quick(); - Utils::Hook(0x56AC60, AntiCheat::AimTargetGetTagPosStub, HOOK_JUMP).install()->quick(); - - // TODO: Probably move that :P - if (!Dedicated::IsEnabled()) - { - AntiCheat::InitLoadLibHook(); - } - - // Prevent external processes from accessing our memory - AntiCheat::ProtectProcess(); - Renderer::OnDeviceRecoveryEnd([]() - { - AntiCheat::ProtectProcess(); - }); - - // Set the integrity flag - AntiCheat::Flags |= AntiCheat::IntergrityFlag::INITIALIZATION; - -#endif - } - - AntiCheat::~AntiCheat() - { - AntiCheat::Flags = NO_FLAG; - AntiCheat::OwnThreadIds.clear(); - AntiCheat::ThreadHookMap.clear(); - - for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) - { - AntiCheat::LoadLibHook[i].uninstall(); - } - - for (int i = 0; i < ARRAYSIZE(AntiCheat::VirtualProtectHook); ++i) - { - AntiCheat::VirtualProtectHook[i].uninstall(false); - } - } -} diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp deleted file mode 100644 index 53f5ae83..00000000 --- a/src/Components/Modules/AntiCheat.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#ifndef DEBUG -// Hide AntiCheat in embeded symbol names -#define AntiCheat SubComponent -#else -# ifndef DISABLE_ANTICHEAT -# define DISABLE_ANTICHEAT -# endif -#endif - -// Uncomment to enable process protection (conflicts with steam!) -#define PROCTECT_PROCESS - -namespace Components -{ - class AntiCheat : public Component - { - public: - AntiCheat(); - ~AntiCheat(); - - class LibUnlocker - { - public: - LibUnlocker() - { - UninstallLibHook(); - } - ~LibUnlocker() - { - InstallLibHook(); - } - }; - - static void CrashClient(); - - static void InitLoadLibHook(); - - static void ReadIntegrityCheck(); - static void ScanIntegrityCheck(); - static void FlagIntegrityCheck(); - - static unsigned long ProtectProcess(); - - static void PatchVirtualProtect(void* vp, void* vpex); - static void PatchThreadCreation(); - - static void VerifyThreadIntegrity(); - - static void QuickCodeScanner1(); - static void QuickCodeScanner2(); - - static void UninstallLibHook(); - static void InstallLibHook(); - - static void CheckStartupTime(); - static void SystemTimeDiff(LPSYSTEMTIME stA, LPSYSTEMTIME stB, LPSYSTEMTIME stC); - - private: - enum IntergrityFlag - { - NO_FLAG = (0), - INITIALIZATION = (1 << 0), - MEMORY_SCAN = (1 << 1), - SCAN_INTEGRITY_CHECK = (1 << 2), - -#ifdef PROCTECT_PROCESS - READ_INTEGRITY_CHECK = (1 << 3), -#endif - - MAX_FLAG, - }; - - static Utils::Time::Interval LastCheck; - static unsigned long Flags; - - static void PerformScan(); - static void PatchWinAPI(); - - static void NullSub(); - - static bool IsPageChangeAllowed(void* callee, void* addr, size_t len); - static void AssertCalleeModule(void* callee); - -#ifdef DEBUG_LOAD_LIBRARY - static HANDLE LoadLibary(std::wstring library, HANDLE file, DWORD flags, void* callee); - static HANDLE WINAPI LoadLibaryAStub(const char* library); - static HANDLE WINAPI LoadLibaryWStub(const wchar_t* library); - static HANDLE WINAPI LoadLibaryExAStub(const char* library, HANDLE file, DWORD flags); - static HANDLE WINAPI LoadLibaryExWStub(const wchar_t* library, HANDLE file, DWORD flags); -#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 CinematicStub(); - static void SoundInitStub(int a1, int a2, int a3); - static void SoundInitDriverStub(); - - static void DObjGetWorldTagPosStub(); - static void AimTargetGetTagPosStub(); - - static void AcquireDebugPrivilege(HANDLE hToken); - - static NTSTATUS NTAPI NtCreateThreadExStub(PHANDLE hThread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPTHREAD_START_ROUTINE startAddress, LPVOID parameter, BOOL createSuspended, DWORD stackZeroBits, DWORD sizeOfStackCommit, DWORD sizeOfStackReserve, LPVOID bytesBuffer); - static int ValidateThreadTermination(void* addr); - static void ThreadEntryPointStub(); - - static std::mutex ThreadMutex; - static std::vector OwnThreadIds; - static std::map> ThreadHookMap; - - static Utils::Hook CreateThreadHook; - static Utils::Hook LoadLibHook[6]; - static Utils::Hook VirtualProtectHook[2]; - }; -} - diff --git a/src/Components/Modules/CardTitles.cpp b/src/Components/Modules/CardTitles.cpp index 396eebf5..e3ac4a5c 100644 --- a/src/Components/Modules/CardTitles.cpp +++ b/src/Components/Modules/CardTitles.cpp @@ -218,8 +218,5 @@ namespace Components // This is placed here in case the anticheat has been disabled! // This checks specifically for launching the process suspended to inject a dll -#if !defined(DISABLE_ANTICHEAT) - AntiCheat::CheckStartupTime(); -#endif } } diff --git a/src/Components/Modules/Changelog.cpp b/src/Components/Modules/Changelog.cpp index a6da0d83..93b5974d 100644 --- a/src/Components/Modules/Changelog.cpp +++ b/src/Components/Modules/Changelog.cpp @@ -55,9 +55,5 @@ namespace Components // Changelog UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog); - -#ifndef DISABLE_ANTICHEAT - Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner1); -#endif } } diff --git a/src/Components/Modules/Discovery.cpp b/src/Components/Modules/Discovery.cpp index 93dbf96f..c71ca293 100644 --- a/src/Components/Modules/Discovery.cpp +++ b/src/Components/Modules/Discovery.cpp @@ -83,16 +83,6 @@ namespace Components ServerList::InsertRequest(address); } }); - - // This is placed here in case the anticheat has been disabled! - // Make sure this is called after the memory scan! -#ifndef DISABLE_ANTICHEAT - Utils::Hook(0x5ACB9E, []() // Somewhere in the renderer, past the scan check - { - AntiCheat::ScanIntegrityCheck(); - return Utils::Hook::Call(0x4AA720)(); - }, HOOK_CALL).install()->quick(); -#endif } void Discovery::preDestroy() diff --git a/src/Components/Modules/Exception.cpp b/src/Components/Modules/Exception.cpp index 3700587b..572bfdfd 100644 --- a/src/Components/Modules/Exception.cpp +++ b/src/Components/Modules/Exception.cpp @@ -137,10 +137,6 @@ namespace Components Utils::IO::CreateDir("minidumps"); PathCombineA(filename, "minidumps\\", Utils::String::VA("%s-" VERSION "-%s.dmp", exeFileName, filenameFriendlyTime)); -#ifndef DISABLE_ANTICHEAT - AntiCheat::UninstallLibHook(); -#endif - DWORD fileShare = FILE_SHARE_READ | FILE_SHARE_WRITE; HANDLE hFile = CreateFileA(filename, GENERIC_WRITE | GENERIC_READ, fileShare, nullptr, (fileShare & FILE_SHARE_WRITE) > 0 ? OPEN_ALWAYS : OPEN_EXISTING, NULL, nullptr); MINIDUMP_EXCEPTION_INFORMATION ex = { GetCurrentThreadId(), ExceptionInfo, FALSE }; @@ -157,10 +153,6 @@ namespace Components TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode); } -#ifndef DISABLE_ANTICHEAT - AntiCheat::InstallLibHook(); -#endif - return EXCEPTION_CONTINUE_SEARCH; } diff --git a/src/Components/Modules/Gametypes.cpp b/src/Components/Modules/Gametypes.cpp index c155cf99..d7f567f4 100644 --- a/src/Components/Modules/Gametypes.cpp +++ b/src/Components/Modules/Gametypes.cpp @@ -98,15 +98,5 @@ namespace Components // Dynamically grab gametypes Utils::Hook(0x5FA46C, Gametypes::BuildGametypeList, HOOK_CALL).install()->quick(); // Scr_UpdateGameTypeList Utils::Hook(0x632155, Gametypes::BuildGametypeList, HOOK_CALL).install()->quick(); // UI_UpdateGameTypesList - - // This is placed here in case the anticheat has been disabled! - // Make sure this is called after every onther anticheat check! -#ifndef DISABLE_ANTICHEAT - Utils::Hook(0x5ACBA3, []() // Somewhere in the renderer, past other renderer hooks! - { - AntiCheat::FlagIntegrityCheck(); - return Utils::Hook::Call(0x50AB20)(); - }, HOOK_CALL).install()->quick(); -#endif } } diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index 3b385506..641f1b0f 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -297,13 +297,6 @@ namespace Components } } }); - -// #ifndef DISABLE_ANTICHEAT -// if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled() && !Utils::IsWineEnvironment() && !Loader::IsPerformingUnitTests()) -// { -// AntiCheat::PatchVirtualProtect(VirtualProtect, VirtualProtectEx); -// } -// #endif } Localization::~Localization() diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index f29b4499..2d316acf 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -70,7 +70,7 @@ namespace Components script->next = nullptr; - Game::source_t* source = allocator->allocate(); + auto* source = allocator->allocate(); if (!source) { Game::FreeMemory(script); @@ -116,7 +116,7 @@ namespace Components { Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator(); - Game::menuDef_t* menu = allocator->allocate(); + auto* menu = allocator->allocate(); if (!menu) return nullptr; menu->items = allocator->allocateArray(512); @@ -284,17 +284,7 @@ namespace Components if (menus.empty()) { - // // Try loading the original menu, if we can't load our custom one - // Game::menuDef_t* originalMenu = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_MENU, menudef->window.name).menu; - // - // if (originalMenu) - // { - // menus.push_back({ false, originalMenu }); - // } - // else - // { menus.push_back({ false, menudef }); // Native menu -// } } return menus; @@ -308,7 +298,7 @@ namespace Components if (menus.empty()) return nullptr; // Allocate new menu list - Game::MenuList* newList = allocator->allocate(); + auto* newList = allocator->allocate(); if (!newList) return nullptr; newList->menus = allocator->allocateArray(menus.size()); @@ -319,7 +309,7 @@ namespace Components } newList->name = allocator->duplicateString(menu); - newList->menuCount = menus.size(); + newList->menuCount = static_cast(menus.size()); // Copy new menus for (unsigned int i = 0; i < menus.size(); ++i) @@ -759,50 +749,14 @@ namespace Components void Menus::RegisterCustomMenusHook() { - Game::UiContext* uiInfoArray = (Game::UiContext*)0x62E2858; - // Game::MenuList list; - Utils::Hook::Call(0x401700)(); // call original load functions - //Game::XAssetHeader header = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MENULIST, "ui_mp/iw4x.txt"); - //if (header.data && !(header.menuList->menuCount == 1 && !_stricmp("default_menu", header.menuList->menus[0]->window.name))) - //{ - // // Utils::Hook::Call(0x401700)(uiInfoArray, header.menuList, 1); // add loaded menus - // std::memcpy(&list, header.data, sizeof(Game::MenuList)); - // for (int i = 0; i < uiInfoArray->menuCount; i++) - // { - // for (int j = 0; j < list.menuCount; j++) - // { - // if (!list.menus[j]) continue; // skip already used entries - // if (!stricmp(list.menus[j]->window.name, uiInfoArray->Menus[i]->window.name)) - // { - // uiInfoArray->Menus[i] = list.menus[j]; // overwrite UiContext pointer - // list.menus[j] = nullptr; // clear entries that already exist so we don't add them later - // } - // } - // } - - // for (int i = 0; i < list.menuCount; i++) - // { - // if (list.menus[i]) - // { - // uiInfoArray->Menus[uiInfoArray->menuCount++] = list.menus[i]; - // } - // } - //} - - for (int i = 0; i < uiInfoArray->menuCount; i++) +#ifdef _DEBUG + for (int i = 0; i < Game::uiContext->menuCount; i++) { - OutputDebugStringA(Utils::String::VA("%s\n", uiInfoArray->Menus[i]->window.name)); + OutputDebugStringA(Utils::String::VA("%s\n", Game::uiContext->Menus[i]->window.name)); } - - /* - header = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MENULIST, "ui_mp/mod.txt"); - if (header.data && !(header.menuList->menuCount == 1 && !_stricmp("default_menu", header.menuList->menus[0]->window.name))) - { - Utils::Hook::Call(0x401700)(uiInfoArray, header.menuList, 1); // add loaded menus - } - */ +#endif } Menus::Menus() @@ -824,12 +778,12 @@ namespace Components // Use the connect menu open call to update server motds Utils::Hook(0x428E48, []() + { + if (!Party::GetMotd().empty() && Party::Target() == *Game::connectedHost) { - if (!Party::GetMotd().empty() && Party::Target() == *Game::connectedHost) - { - Dvar::Var("didyouknow").set(Party::GetMotd()); - } - }, HOOK_CALL).install()->quick(); + Dvar::Var("didyouknow").set(Party::GetMotd()); + } + }, HOOK_CALL).install()->quick(); // Intercept menu painting Utils::Hook(0x4FFBDF, Menus::IsMenuVisible, HOOK_CALL).install()->quick(); @@ -844,53 +798,49 @@ namespace Components Utils::Hook::SetString(0x6FC790, "main_text"); Command::Add("openmenu", [](Command::Params* params) + { + if (params->size() != 2) { - if (params->size() != 2) - { - Logger::Print("USAGE: openmenu \n"); - return; - } + Logger::Print("USAGE: openmenu \n"); + return; + } - // Not quite sure if we want to do this if we're not ingame, but it's only needed for ingame menus. - if (Dvar::Var("cl_ingame").get()) - { - Game::Key_SetCatcher(0, 16); - } + // Not quite sure if we want to do this if we're not ingame, but it's only needed for ingame menus. + if (Dvar::Var("cl_ingame").get()) + { + Game::Key_SetCatcher(0, 16); + } - Game::Menus_OpenByName(Game::uiContext, params->get(1)); - }); + Game::Menus_OpenByName(Game::uiContext, params->get(1)); + }); Command::Add("reloadmenus", [](Command::Params*) + { + // Close all menus + Game::Menus_CloseAll(Game::uiContext); + + // Free custom menus + Menus::FreeEverything(); + + // Only disconnect if in-game, context is updated automatically! + if (Game::CL_IsCgameInitialized()) { - // Close all menus - Game::Menus_CloseAll(Game::uiContext); + Game::Cbuf_AddText(0, "disconnect\n"); + } + else + { + // Reinitialize ui context + Utils::Hook::Call(0x401700)(); - // Free custom menus - Menus::FreeEverything(); - - // Only disconnect if in-game, context is updated automatically! - if (Game::CL_IsCgameInitialized()) - { - Game::Cbuf_AddText(0, "disconnect\n"); - } - else - { - // Reinitialize ui context - Utils::Hook::Call(0x401700)(); - - // Reopen main menu - Game::Menus_OpenByName(Game::uiContext, "main_text"); - } - }); - -#ifndef DISABLE_ANTICHEAT - Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner2); -#endif + // Reopen main menu + Game::Menus_OpenByName(Game::uiContext, "main_text"); + } + }); Command::Add("mp_QuickMessage", [](Command::Params*) - { - Command::Execute("openmenu quickmessage"); - }); + { + Command::Execute("openmenu quickmessage"); + }); // Define custom menus here Menus::Add("ui_mp/changelog.menu"); diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index a4e61251..c931c859 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -871,11 +871,6 @@ namespace Components // Add frame callback Scheduler::OnFrame(ServerList::Frame); - - // This is placed here in case the anticheat has been disabled! -#if !defined(DISABLE_ANTICHEAT) && defined(PROCTECT_PROCESS) - Scheduler::OnFrame(AntiCheat::ReadIntegrityCheck, true); -#endif } ServerList::~ServerList() diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 0a04d18f..49c45e8c 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -424,7 +424,7 @@ namespace Game int* svs_numclients = reinterpret_cast(0x31D938C); client_t* svs_clients = reinterpret_cast(0x31D9390); - UiContext *uiContext = reinterpret_cast(0x62E2858); + UiContext* uiContext = reinterpret_cast(0x62E2858); int* arenaCount = reinterpret_cast(0x62E6930); mapArena_t* arenas = reinterpret_cast(0x62E6934); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index ee0d4d0c..fa7b2ed5 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -402,7 +402,7 @@ namespace Game typedef void(__cdecl * LargeLocalInit_t)(); extern LargeLocalInit_t LargeLocalInit; - typedef bool(__cdecl * Load_Stream_t)(bool atStreamStart, const void *ptr, unsigned int size); + typedef bool(__cdecl * Load_Stream_t)(bool atStreamStart, const void* ptr, unsigned int size); extern Load_Stream_t Load_Stream; typedef void(__cdecl * Load_XString_t)(bool atStreamStart); @@ -411,64 +411,64 @@ namespace Game typedef void(__cdecl * Load_XModelPtr_t)(bool atStreamStart); extern Load_XModelPtr_t Load_XModelPtr; - typedef void(__cdecl * Load_XModelSurfsFixup_t)(XModelSurfs **, XModelLodInfo *); + typedef void(__cdecl * Load_XModelSurfsFixup_t)(XModelSurfs**, XModelLodInfo*); extern Load_XModelSurfsFixup_t Load_XModelSurfsFixup; typedef void(__cdecl * Load_XStringArray_t)(bool atStreamStart, int count); extern Load_XStringArray_t Load_XStringArray; - typedef void(__cdecl * Load_XStringCustom_t)(const char **str); + typedef void(__cdecl * Load_XStringCustom_t)(const char** str); extern Load_XStringCustom_t Load_XStringCustom; - typedef void(__cdecl *Load_FxEffectDefHandle_t)(bool atStreamStart); + typedef void(__cdecl * Load_FxEffectDefHandle_t)(bool atStreamStart); extern Load_FxEffectDefHandle_t Load_FxEffectDefHandle; - typedef void(__cdecl *Load_FxElemDef_t)(bool atStreamStart); + typedef void(__cdecl * Load_FxElemDef_t)(bool atStreamStart); extern Load_FxElemDef_t Load_FxElemDef; - typedef void(__cdecl *Load_GfxImagePtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_GfxImagePtr_t)(bool atStreamStart); extern Load_GfxImagePtr_t Load_GfxImagePtr; - typedef void(__cdecl *Load_GfxTextureLoad_t)(bool atStreamStart); + typedef void(__cdecl * Load_GfxTextureLoad_t)(bool atStreamStart); extern Load_GfxTextureLoad_t Load_GfxTextureLoad; - typedef int(__cdecl *Load_Texture_t)(GfxImageLoadDef **loadDef, GfxImage *image); + typedef int(__cdecl * Load_Texture_t)(GfxImageLoadDef** loadDef, GfxImage* image); extern Load_Texture_t Load_Texture; typedef void(__cdecl * Load_SndAliasCustom_t)(snd_alias_list_t** var); extern Load_SndAliasCustom_t Load_SndAliasCustom; - typedef void(__cdecl *Load_MaterialHandle_t)(bool atStreamStart); + typedef void(__cdecl * Load_MaterialHandle_t)(bool atStreamStart); extern Load_MaterialHandle_t Load_MaterialHandle; - typedef void(__cdecl *Load_PhysCollmapPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_PhysCollmapPtr_t)(bool atStreamStart); extern Load_PhysCollmapPtr_t Load_PhysCollmapPtr; - typedef void(__cdecl *Load_PhysPresetPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_PhysPresetPtr_t)(bool atStreamStart); extern Load_PhysPresetPtr_t Load_PhysPresetPtr; - typedef void(__cdecl *Load_TracerDefPtr_t)(bool atStreamStart); + typedef void(__cdecl * Load_TracerDefPtr_t)(bool atStreamStart); extern Load_TracerDefPtr_t Load_TracerDefPtr; - typedef void(__cdecl *Load_snd_alias_list_nameArray_t)(bool atStreamStart, int count); + typedef void(__cdecl * Load_snd_alias_list_nameArray_t)(bool atStreamStart, int count); extern Load_snd_alias_list_nameArray_t Load_snd_alias_list_nameArray; - typedef void(__cdecl * Menus_CloseAll_t)(UiContext *dc); + typedef void(__cdecl * Menus_CloseAll_t)(UiContext* dc); extern Menus_CloseAll_t Menus_CloseAll; typedef void(__cdecl * Menus_CloseRequest_t)(UiContext *dc, menuDef_t* menu); extern Menus_CloseRequest_t Menus_CloseRequest; - typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p); + typedef int(__cdecl * Menus_OpenByName_t)(UiContext* dc, const char* p); extern Menus_OpenByName_t Menus_OpenByName; - typedef menuDef_t *(__cdecl * Menus_FindByName_t)(UiContext *dc, const char *name); + typedef menuDef_t *(__cdecl * Menus_FindByName_t)(UiContext* dc, const char* name); extern Menus_FindByName_t Menus_FindByName; - typedef bool(__cdecl * Menu_IsVisible_t)(UiContext *dc, menuDef_t *menu); + typedef bool(__cdecl * Menu_IsVisible_t)(UiContext* dc, menuDef_t* menu); extern Menu_IsVisible_t Menu_IsVisible; - typedef bool(__cdecl * Menus_MenuIsInStack_t)(UiContext *dc, menuDef_t *menu); + typedef bool(__cdecl * Menus_MenuIsInStack_t)(UiContext* dc, menuDef_t* menu); extern Menus_MenuIsInStack_t Menus_MenuIsInStack; typedef menuDef_t*(__cdecl * Menu_GetFocused_t)(UiContext* ctx); @@ -480,16 +480,16 @@ namespace Game typedef bool(__cdecl * UI_KeyEvent_t)(int clientNum, int key, int down); extern UI_KeyEvent_t UI_KeyEvent; - typedef const char* (__cdecl * UI_SafeTranslateString_t)(const char* reference); + typedef const char*(__cdecl * UI_SafeTranslateString_t)(const char* reference); extern UI_SafeTranslateString_t UI_SafeTranslateString; typedef void(__cdecl * UI_ReplaceConversions_t)(const char* sourceString, ConversionArguments* arguments, char* outputString, size_t outputStringSize); extern UI_ReplaceConversions_t UI_ReplaceConversions; - typedef void(__cdecl * MSG_Init_t)(msg_t *buf, char *data, int length); + typedef void(__cdecl * MSG_Init_t)(msg_t* buf, char* data, int length); extern MSG_Init_t MSG_Init; - typedef void(__cdecl * MSG_ReadData_t)(msg_t *msg, void *data, int len); + typedef void(__cdecl * MSG_ReadData_t)(msg_t* msg, void* data, int len); extern MSG_ReadData_t MSG_ReadData; typedef int(__cdecl * MSG_ReadLong_t)(msg_t* msg); @@ -873,16 +873,16 @@ namespace Game typedef void(__cdecl * Sys_SuspendOtherThreads_t)(); extern Sys_SuspendOtherThreads_t Sys_SuspendOtherThreads; - typedef void(__cdecl * UI_AddMenuList_t)(UiContext *dc, MenuList *menuList, int close); + typedef void(__cdecl * UI_AddMenuList_t)(UiContext* dc, MenuList* menuList, int close); extern UI_AddMenuList_t UI_AddMenuList; typedef uiMenuCommand_t(__cdecl * UI_GetActiveMenu_t)(int localClientNum); extern UI_GetActiveMenu_t UI_GetActiveMenu; - typedef char* (__cdecl * UI_CheckStringTranslation_t)(char*, char*); + typedef char*(__cdecl * UI_CheckStringTranslation_t)(char*, char*); extern UI_CheckStringTranslation_t UI_CheckStringTranslation; - typedef MenuList *(__cdecl * UI_LoadMenus_t)(const char *menuFile, int imageTrack); + typedef MenuList*(__cdecl * UI_LoadMenus_t)(const char* menuFile, int imageTrack); extern UI_LoadMenus_t UI_LoadMenus; typedef void(__cdecl * UI_UpdateArenas_t)(); @@ -985,7 +985,7 @@ namespace Game extern source_t **sourceFiles; extern keywordHash_t **menuParseKeywordHash; - extern UiContext *uiContext; + extern UiContext* uiContext; extern int* arenaCount; extern mapArena_t* arenas; diff --git a/src/Main.cpp b/src/Main.cpp index 0e78434b..db9c14ad 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -55,7 +55,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l Steam::Proxy::RunMod(); // Ensure we're working with our desired binary - char* _module = reinterpret_cast(0x400000); + auto* _module = reinterpret_cast(0x400000); auto hash1 = Utils::Cryptography::JenkinsOneAtATime::Compute(_module + 0x1000, 0x2D531F); // .text auto hash2 = Utils::Cryptography::JenkinsOneAtATime::Compute(_module + 0x2D75FC, 0xBDA04); // .rdata if ((hash1 != 0x54684DBE @@ -67,17 +67,6 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l return FALSE; } -#ifndef DISABLE_ANTICHEAT - []() - { - if (!Components::Dedicated::IsEnabled() && !Components::Loader::IsPerformingUnitTests()) - { - Components::AntiCheat::ProtectProcess(); - Components::AntiCheat::PatchThreadCreation(); - } - }(); -#endif - DWORD oldProtect; VirtualProtect(_module + 0x1000, 0x2D6000, PAGE_EXECUTE_READ, &oldProtect); // Protect the .text segment @@ -88,18 +77,6 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l { Main::Uninitialize(); } - else if (ul_reason_for_call == DLL_THREAD_ATTACH) - { -#ifndef DISABLE_ANTICHEAT - []() - { - if (!Components::Dedicated::IsEnabled() && !Components::Loader::IsPerformingUnitTests()) - { - Components::AntiCheat::VerifyThreadIntegrity(); - } - }(); -#endif - } return TRUE; } diff --git a/src/Utils/Utils.cpp b/src/Utils/Utils.cpp index e17480bf..5166b84f 100644 --- a/src/Utils/Utils.cpp +++ b/src/Utils/Utils.cpp @@ -123,10 +123,6 @@ namespace Utils void SafeShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd) { -#ifndef DISABLE_ANTICHEAT - Components::AntiCheat::LibUnlocker _; -#endif - [=]() { __try