Reputation: 83
As a part of my project, I get an event notification every time a Service is Started or Stopped using the WMI class Win32_Service through an EventSink. I want to detect the application which had requested "services.exe" to start a particular service.
Till now, I tried Monitoring ALPC calls between any process and "services.exe" and got a Message_ID every time a process communicates (sends/receives) any information to/from "services.exe" using the ALPC Class. I would like to know what these messages are so that I can decode a StartService() or a StopService() procedure.
Is there any way to detect which application starts/stops a service?
Upvotes: 0
Views: 554
Reputation: 640
The best way to do this, in my opinion, would be from kernel-mode using the PsSetCreateProcessNotifyRoutine/Ex/Ex2
kernel-mode callback.
If you're going to be using PsSetCreateProcessNotifyRoutine
, you will receive less information than if you were using the Extended version of the kernel-mode callback (the Ex one). However, you can still query information such as the image file path of the parent process (or the one being created) by using PsLookupProcessByProcessId
to get a pointer to the _EPROCESS
structure and then relying on SeLocateProcessImageName
(undocumented, however it is accessible in WDK by default).
The SeLocateProcessImageName
routine will rely internally on that _EPROCESS
structure, since information like the path of the process image on-disk is all tracked by the Windows kernel there.
If you're going to be using the Ex version of the kernel-mode callback, then you eliminate the need to do what is mentioned above. The Ex version of the routine is more recent than the non-Ex version.
The routine prototype for the callback routine will be:
VOID
CreateProcessNotifyRoutineEx(
PEPROCESS Process,
HANDLE ProcessId,
PPS_CREATE_NOTIFY_INFO CreateInfo
)
As seen above, you get a pointer to the _PS_CREATE_NOTIFY_INFO
structure. You can then access the ImageFileName
and CommandLine
fields to filter for services.exe
(make sure you filter properly to not catch it for a rogue copy - so ensure full path indicates its the real one) and gain more insight into why it was being invoked (if such information is exposed via the command-line... I cannot remember - nonetheless, you can still detect its creation and be aware of who spawned it).
To determine the parent who was responsible for the process creation operation of services.exe
(e.g. if it relied on the Service Manager which in turn resulted in the spawning of it), you can rely on the ParentProcessId
field (under the _PS_CREATE_NOTIFY_INFO
structure as well). The SeLocateProcessImageName
trick will work perfectly here.
SeLocateProcessImageName
is undocumented so here is the routine prototype:
NTSTATUS
NTAPI
SeLocateProcessImageName(
PEPROCESS Process,
PUNICODE_STRING *ImageName
);
At-least with the latest Windows 10 WDK, it's already available by default. If you wanted to though, you can use a dynamic import with MmGetSystemRoutineAddress
.
Resources:
Upvotes: 1