// system/ServiceManager.h #pragma once #ifdef CURRENT_MODULE #undef CURRENT_MODULE #endif #define CURRENT_MODULE "ServiceManager" #include "core/Logger.h" #include #include namespace ServiceManager { struct ServiceHandleCloser { void operator()(SC_HANDLE h) const noexcept { if (h) CloseServiceHandle(h); } }; using UniqueServiceHandle = std::unique_ptr::type, ServiceHandleCloser>; inline bool WaitUntilGone(SC_HANDLE scm, const std::wstring& name, DWORD timeoutMs = 30000) { const DWORD step = 2000; DWORD elapsed = 0; LOG_I("Waiting for service deletion: " + std::string(name.begin(), name.end())); while (elapsed < timeoutMs) { elapsed += step; Sleep(step); system("sc query BEService >nul 2>&1"); UniqueServiceHandle hSvc{ OpenServiceW(scm, name.c_str(), SERVICE_QUERY_STATUS) }; if (hSvc) { CloseServiceHandle(hSvc.get()); continue; } if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { CloseServiceHandle(hSvc.get()); LOG_I("Service fully deleted from SCM"); return true; } } LOG_W("Timeout waiting for service deletion (ERROR 1072 may occur)"); return false; } inline bool StopService(SC_HANDLE hSvc) { SERVICE_STATUS status{}; if (!ControlService(hSvc, SERVICE_CONTROL_STOP, &status)) return false; LOG_I("Sent stop command to service"); for (int i = 0; i < 40; ++i) { Sleep(300); if (!QueryServiceStatus(hSvc, &status)) return false; if (status.dwCurrentState == SERVICE_STOPPED) return true; } LOG_W("Service did not stop in time"); return false; } inline bool Remove(const std::wstring& serviceName) { UniqueServiceHandle scm{ OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT) }; if (!scm) { LOG_E("OpenSCManager failed: " + std::to_string(GetLastError())); return false; } UniqueServiceHandle hSvc{ OpenServiceW(scm.get(), serviceName.c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE) }; if (!hSvc) { if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { LOG_I("Service does not exist, nothing to delete"); return true; } LOG_E("OpenService failed: " + std::to_string(GetLastError())); return false; } system("taskkill /f /im service.exe >nul 2>&1"); StopService(hSvc.get()); if (DeleteService(hSvc.get())) { LOG_I("DeleteService command sent"); CloseServiceHandle(hSvc.get()); return WaitUntilGone(scm.get(), serviceName); } DWORD err = GetLastError(); if (err != ERROR_SERVICE_MARKED_FOR_DELETE) { LOG_E("DeleteService failed: " + std::to_string(err)); return false; } LOG_I("Service already marked for delete"); } inline bool DeployFakeBEService(const std::wstring& fakeExePath) { UniqueServiceHandle scm{ OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE) }; if (!scm) { LOG_E("OpenSCManager(create) failed: " + std::to_string(GetLastError())); return false; } // Just create and start the service UniqueServiceHandle hSvc{ CreateServiceW( scm.get(), L"BEService", L"BattlEye Service", SERVICE_START | SERVICE_QUERY_STATUS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fakeExePath.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr) }; if (hSvc) return StartServiceW(hSvc.get(), 0, nullptr) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING; // if failed to create the service, delete the service by force and then create DWORD err = GetLastError(); if (err != ERROR_SERVICE_EXISTS && err != ERROR_SERVICE_MARKED_FOR_DELETE) { LOG_E("CreateService failed: " + std::to_string(err)); return false; } LOG_W("Service conflict detected, forcing cleanup..."); if (!Remove(L"BEService")) return false; // retry hSvc.reset(CreateServiceW(scm.get(), L"BEService", L"BattlEye Service", SERVICE_START | SERVICE_QUERY_STATUS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fakeExePath.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr)); if (!hSvc) { LOG_E("Retry CreateService failed: " + std::to_string(GetLastError())); return false; } bool started = StartServiceW(hSvc.get(), 0, nullptr); if (!started && GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { LOG_W("StartService failed: " + std::to_string(GetLastError())); return false; } LOG_I("Fake BEService is running"); return true; } }