injector refactoring
This commit is contained in:
parent
b8971674ed
commit
444ccad844
14 changed files with 845 additions and 514 deletions
174
operator/system/ServiceManager.h
Normal file
174
operator/system/ServiceManager.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
// system/ServiceManager.h
|
||||
#pragma once
|
||||
|
||||
#ifdef CURRENT_MODULE
|
||||
#undef CURRENT_MODULE
|
||||
#endif
|
||||
#define CURRENT_MODULE "ServiceManager"
|
||||
|
||||
#include "core/Logger.h"
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
namespace ServiceManager
|
||||
{
|
||||
struct ServiceHandleCloser { void operator()(SC_HANDLE h) const noexcept { if (h) CloseServiceHandle(h); } };
|
||||
using UniqueServiceHandle = std::unique_ptr<std::remove_pointer<SC_HANDLE>::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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue