174 lines
5.3 KiB
C++
174 lines
5.3 KiB
C++
/*
|
|
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Driver Assistant, host injected process utilities
|
|
//---------------------------------------------------------------------------
|
|
|
|
// warning C4652: compiler option 'C++ Exception Handling Unwinding' inconsistent with precompiled header; current command-line option will override that defined in the precompiled header
|
|
#pragma warning(disable : 4652)
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <psapi.h>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <set>
|
|
|
|
typedef long NTSTATUS;
|
|
#undef WIN32_NO_STATUS
|
|
#include <ntstatus.h>
|
|
|
|
#include "common/my_version.h"
|
|
#include "core/dll/sbieapi.h"
|
|
|
|
|
|
#define CONF_LINE_LEN 2000 // keep in sync with drv/conf.c
|
|
|
|
using namespace std;
|
|
|
|
set<wstring> g_setSvcNames;
|
|
|
|
// build a map of all services that are HosInjectProcess'es
|
|
|
|
void BuildSvcSet()
|
|
{
|
|
WCHAR wszConfigLine[CONF_LINE_LEN];
|
|
int i = 0;
|
|
|
|
g_setSvcNames.clear();
|
|
|
|
// Loop through every section, searching for "HostInjectProcess", and add the service names to the set.
|
|
while (SbieApi_QueryConf(NULL, NULL, i++, wszConfigLine, sizeof(wszConfigLine)) == STATUS_SUCCESS)
|
|
{
|
|
if (SbieApi_IsBoxEnabled(wszConfigLine) == STATUS_SUCCESS)
|
|
{
|
|
if (SbieApi_QueryConf(wszConfigLine, L"HostInjectProcess", 0, wszConfigLine, sizeof(wszConfigLine)) == STATUS_SUCCESS)
|
|
{
|
|
WCHAR wszProcName[261];
|
|
WCHAR wszSvcName[261];
|
|
if (swscanf(wszConfigLine, L"%260[^'|']|%260s", wszProcName, wszSvcName) == 2)
|
|
{
|
|
g_setSvcNames.insert(wstring(wszSvcName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL IsSvcInjected(DWORD dwPid)
|
|
{
|
|
HANDLE hProcess;
|
|
HMODULE hMods[1024];
|
|
BOOL res = FALSE;
|
|
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid);
|
|
if (hProcess != NULL)
|
|
{
|
|
DWORD dwSize;
|
|
// search through all loaded modules and see if we are injected
|
|
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &dwSize))
|
|
{
|
|
DWORD n;
|
|
for (n = 0; n < (dwSize / sizeof(HMODULE)); n++)
|
|
{
|
|
WCHAR wszModName[MAX_PATH];
|
|
if (GetModuleBaseNameW(hProcess, hMods[n], wszModName, sizeof(wszModName) / sizeof(WCHAR)))
|
|
{
|
|
if (_wcsicmp(wszModName, SBIEDLL L".dll") == 0)
|
|
{
|
|
res = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} // if (EnumProcessModules())
|
|
|
|
CloseHandle(hProcess);
|
|
} // if (OpenProcess())
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
void RestartService(SC_HANDLE hScm, WCHAR *wszServiceName)
|
|
{
|
|
SC_HANDLE hService;
|
|
BOOL res;
|
|
|
|
hService = OpenService(hScm, wszServiceName, SERVICE_ALL_ACCESS);
|
|
res = GetLastError();
|
|
if (hService != NULL)
|
|
{
|
|
SERVICE_STATUS stServiceStatus;
|
|
res = ControlService(hService, SERVICE_CONTROL_STOP, &stServiceStatus);
|
|
res = StartServiceW(hService, 0, NULL);
|
|
CloseServiceHandle(hService);
|
|
}
|
|
}
|
|
|
|
|
|
void RestartHostInjectedSvcs()
|
|
{
|
|
BuildSvcSet();
|
|
|
|
SC_HANDLE hScm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
|
if (!hScm)
|
|
return;
|
|
|
|
const DWORD dwProcBufSize = 32 * 1024;
|
|
LPBYTE pProcBuf = new BYTE[dwProcBufSize];
|
|
|
|
DWORD dwBytesNeeded = 0;
|
|
DWORD dwServicesReturned = 0;
|
|
DWORD dwResumeHandle = 0;
|
|
|
|
// get a list of all active services
|
|
BOOL b = EnumServicesStatusExW(hScm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, pProcBuf, dwProcBufSize,
|
|
&dwBytesNeeded, &dwServicesReturned, &dwResumeHandle, NULL);
|
|
DWORD res = GetLastError();
|
|
|
|
DWORD i = 0;
|
|
for (i = 0; i < dwServicesReturned; i++)
|
|
{
|
|
ENUM_SERVICE_STATUS_PROCESS *pService = &((ENUM_SERVICE_STATUS_PROCESS*)pProcBuf)[i];
|
|
|
|
if ((_wcsicmp(pService->lpServiceName, SBIESVC) == 0) ) // ignore the Sbie service
|
|
continue;
|
|
|
|
set<wstring>::iterator itr = g_setSvcNames.find(pService->lpServiceName); // is service name in the map?
|
|
|
|
if (itr != g_setSvcNames.end())
|
|
{
|
|
// if we are not injected and we should be, restart svc
|
|
if (!IsSvcInjected(pService->ServiceStatusProcess.dwProcessId))
|
|
RestartService(hScm, pService->lpServiceName);
|
|
}
|
|
else
|
|
{
|
|
// if we are injected and we should not be, restart svc
|
|
if (IsSvcInjected(pService->ServiceStatusProcess.dwProcessId))
|
|
RestartService(hScm, pService->lpServiceName);
|
|
}
|
|
}
|
|
|
|
CloseServiceHandle(hScm);
|
|
delete pProcBuf;
|
|
}
|
|
|