mirror of
https://github.com/rbmm/SC
synced 2026-06-08 17:03:41 +00:00
289 lines
6.2 KiB
C++
289 lines
6.2 KiB
C++
#include "stdafx.h"
|
|
|
|
#include "print.h"
|
|
|
|
inline ULONG BOOL_TO_ERROR(BOOL f)
|
|
{
|
|
return f ? NOERROR : GetLastError();
|
|
}
|
|
|
|
struct SIDS
|
|
{
|
|
PBYTE _ptr = (PBYTE)_buf;
|
|
ULONG _nSids = 0;
|
|
ULONG _cb;
|
|
SID _buf[];
|
|
|
|
SIDS(ULONG cb) : _cb(cb)
|
|
{
|
|
}
|
|
|
|
void* operator new(size_t, void* pv)
|
|
{
|
|
return pv;
|
|
}
|
|
|
|
NTSTATUS AddSid(LONGLONG time, ULONG dwProcessId, PULONG pIndex);
|
|
|
|
void Dump(LSA_HANDLE PolicyHandle, ENUM_SERVICE_STATUS_PROCESSW* Services, ULONG n);
|
|
};
|
|
|
|
NTSTATUS SIDS::AddSid(LONGLONG time, ULONG dwProcessId, PULONG pIndex)
|
|
{
|
|
CLIENT_ID cid = { (HANDLE)(ULONG_PTR)dwProcessId };
|
|
OBJECT_ATTRIBUTES oa = { sizeof(oa) };
|
|
NTSTATUS status;
|
|
HANDLE hProcess, hToken = 0;
|
|
if (0 <= (status = NtOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION, &oa, &cid)))
|
|
{
|
|
KERNEL_USER_TIMES times;
|
|
if (0 <= (status = NtQueryInformationProcess(hProcess, ProcessTimes, ×, sizeof(times), 0)))
|
|
{
|
|
if (times.CreateTime.QuadPart < time)
|
|
{
|
|
status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
|
|
}
|
|
else
|
|
{
|
|
// probably new process created with same id
|
|
status = STATUS_PROCESS_IS_TERMINATING;
|
|
}
|
|
}
|
|
|
|
NtClose(hProcess);
|
|
|
|
if (0 <= status)
|
|
{
|
|
union {
|
|
PVOID pv;
|
|
PTOKEN_USER ptu;
|
|
};
|
|
|
|
ULONG rcb;
|
|
status = NtQueryInformationToken(hToken, TokenUser, pv = _ptr, _cb, &rcb);
|
|
|
|
NtClose(hToken);
|
|
|
|
if (0 <= status)
|
|
{
|
|
ULONG i = 0;
|
|
PSID Sid = _buf, UserSid = ptu->User.Sid;
|
|
if (rcb = _nSids)
|
|
{
|
|
do
|
|
{
|
|
if (RtlEqualSid(Sid, UserSid))
|
|
{
|
|
// such sid already exist
|
|
*pIndex = i;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
(ULONG_PTR&)Sid += RtlLengthSid(Sid);
|
|
|
|
} while (i++, --rcb);
|
|
}
|
|
// new Sid
|
|
|
|
if (_ptr != Sid)
|
|
{
|
|
__debugbreak();
|
|
}
|
|
|
|
RtlCopySid(_cb, Sid, UserSid);
|
|
*pIndex = _nSids++, _ptr += (rcb = RtlLengthSid(Sid)), _cb -= rcb;
|
|
}
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
void SIDS::Dump(LSA_HANDLE PolicyHandle, ENUM_SERVICE_STATUS_PROCESSW* Services, ULONG n)
|
|
{
|
|
if (ULONG i = _nSids)
|
|
{
|
|
PVOID pv = alloca(i * sizeof(void*));
|
|
PSID *Sids = (PSID *)pv;
|
|
|
|
PSID sid = _buf;
|
|
do
|
|
{
|
|
*Sids++ = sid;
|
|
(ULONG_PTR&)sid += RtlLengthSid(sid);
|
|
} while (--i);
|
|
|
|
PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = 0;
|
|
PLSA_TRANSLATED_NAME Names = 0;
|
|
|
|
if (0 <= LsaLookupSids(PolicyHandle, _nSids, (PSID *)pv, &ReferencedDomains, &Names))
|
|
{
|
|
do
|
|
{
|
|
int index = Services->ServiceStatusProcess.dwWaitHint;
|
|
if (0 <= index)
|
|
{
|
|
switch (Names[index].Use)
|
|
{
|
|
case SidTypeUser:
|
|
case SidTypeGroup:
|
|
case SidTypeAlias:
|
|
case SidTypeWellKnownGroup:
|
|
case SidTypeComputer:
|
|
ULONG DomainIndex = Names[index].DomainIndex;
|
|
UNICODE_STRING us = {}, *Domain = &us;
|
|
if (DomainIndex < ReferencedDomains->Entries)
|
|
{
|
|
Domain = &ReferencedDomains->Domains[DomainIndex].Name;
|
|
}
|
|
|
|
DbgPrint("%x \"%ws\" (\"%ws\") \"%wZ\\%wZ\"\r\n",
|
|
Services->ServiceStatusProcess.dwProcessId,
|
|
Services->lpServiceName,
|
|
Services->lpDisplayName,
|
|
Domain, &Names[index].Name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
} while (Services++, --n);
|
|
}
|
|
|
|
LsaFreeMemory(ReferencedDomains);
|
|
LsaFreeMemory(Names);
|
|
}
|
|
}
|
|
|
|
NTSTATUS PrintSrvAccount(SC_HANDLE hSCManager,
|
|
PCWSTR lpServiceName,
|
|
QUERY_SERVICE_CONFIGW* lpServiceConfig,
|
|
DWORD cbBufSize)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (SC_HANDLE hService = HR(hr, OpenServiceW(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG)))
|
|
{
|
|
HR(hr, QueryServiceConfigW(hService, lpServiceConfig, cbBufSize, &cbBufSize));
|
|
|
|
CloseServiceHandle(hService);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
DbgPrint("\tStartName = \"%ws\"\r\n", lpServiceConfig->lpServiceStartName);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT List_Services()
|
|
{
|
|
union NT_OS_VER
|
|
{
|
|
ULONG FullVersion;
|
|
struct
|
|
{
|
|
USHORT Build;
|
|
union {
|
|
USHORT Version;
|
|
struct
|
|
{
|
|
UCHAR Minor;
|
|
UCHAR Major;
|
|
};
|
|
};
|
|
};
|
|
|
|
NT_OS_VER()
|
|
{
|
|
ULONG M, m, b;
|
|
RtlGetNtVersionNumbers(&M, &m, &b);
|
|
Build = (USHORT)b;
|
|
Minor = (UCHAR)m;
|
|
Major = (UCHAR)M;
|
|
}
|
|
} nt_ver;
|
|
|
|
ULONG cbBytesNeeded, ResumeHandle = 0, n, i;
|
|
|
|
DWORD dwServiceType = nt_ver.Version < _WIN32_WINNT_WIN10 ?
|
|
SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS : SERVICE_TYPE_ALL;
|
|
|
|
enum { cb_buf = 0x10000, cb_b2 = 0x2000, cb_s = sizeof(SIDS) + 64*SECURITY_MAX_SID_SIZE };
|
|
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
|
|
if (PBYTE lpServices = new BYTE[cb_buf + cb_b2 + cb_s])
|
|
{
|
|
QUERY_SERVICE_CONFIGW* lpServiceConfig = (QUERY_SERVICE_CONFIGW*)RtlOffsetToPointer(lpServices, cb_buf);
|
|
SIDS* pSids = new(RtlOffsetToPointer(lpServiceConfig, cb_b2)) SIDS(cb_s);
|
|
|
|
if (SC_HANDLE hSCManager = HR(hr, OpenSCManagerW(0, 0, SC_MANAGER_ENUMERATE_SERVICE)))
|
|
{
|
|
LSA_HANDLE PolicyHandle;
|
|
OBJECT_ATTRIBUTES oa = { sizeof(oa) };
|
|
if (0 <= (hr = LsaOpenPolicy(0, &oa, POLICY_LOOKUP_NAMES, &PolicyHandle)))
|
|
{
|
|
do
|
|
{
|
|
union {
|
|
LARGE_INTEGER time;
|
|
FILETIME ft;
|
|
};
|
|
|
|
GetSystemTimeAsFileTime(&ft);
|
|
|
|
switch (hr = BOOL_TO_ERROR(EnumServicesStatusExW(hSCManager,
|
|
SC_ENUM_PROCESS_INFO, dwServiceType, SERVICE_STATE_ALL,
|
|
lpServices, cb_buf, &cbBytesNeeded, &n, &ResumeHandle, 0)))
|
|
{
|
|
case NOERROR:
|
|
case ERROR_MORE_DATA:
|
|
if (i = n)
|
|
{
|
|
ENUM_SERVICE_STATUS_PROCESSW* Services = (ENUM_SERVICE_STATUS_PROCESSW*)lpServices;
|
|
|
|
do
|
|
{
|
|
Services->ServiceStatusProcess.dwWaitHint = (ULONG)-1; // until no sid
|
|
|
|
if (Services->ServiceStatusProcess.dwProcessId &&
|
|
SERVICE_RUNNING == Services->ServiceStatusProcess.dwCurrentState)
|
|
{
|
|
if (0 > pSids->AddSid(time.QuadPart,
|
|
Services->ServiceStatusProcess.dwProcessId,
|
|
&Services->ServiceStatusProcess.dwWaitHint))
|
|
{
|
|
// service terminated or access denied, or too many sids, or some error
|
|
PrintSrvAccount(hSCManager,
|
|
Services->lpServiceName,
|
|
lpServiceConfig,
|
|
cb_b2);
|
|
}
|
|
}
|
|
} while (Services++, --i);
|
|
|
|
pSids->Dump(PolicyHandle, (ENUM_SERVICE_STATUS_PROCESSW*)lpServices, n);
|
|
}
|
|
break;
|
|
}
|
|
} while (ERROR_MORE_DATA == hr);
|
|
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
}
|
|
|
|
delete [] lpServices;
|
|
}
|
|
|
|
DbgPrint("List_Services=%x\r\n", hr);
|
|
|
|
if (hr)
|
|
{
|
|
PrintError(hr);
|
|
}
|
|
|
|
return hr;
|
|
} |