Kernel WMI Notification Callback

Good morning/afternoon everyone,

I am currently working on a small Windows kernel driver that would monitor specific WMI operations. I did a some research and found the following combination of APIs in order to register a notification callback: IoWMIOpenBlock and IoWMISetNotificationCallback.

At the moment I am trying to get a simple example working with Win32_Process. I found the GUID for this WMI class with the following PowerShell code:

PS C:\>   (Get-CimClass -ClassName Win32_Process | Select-Object *).CimClassQualifiers

Name                                            Value CimType                      Flags
----                                            ----- -------                      -----
Locale                                           1033  SInt32 EnableOverride, ToSubclass
UUID           {8502C4DC-5FBB-11D2-AAC1-006008C78BC7}  String EnableOverride, ToSubclass
CreateBy                                       Create  String EnableOverride, Restricted
DeleteBy                               DeleteInstance  String EnableOverride, Restricted
dynamic                                          True Boolean EnableOverride, ToSubclass
provider                                     CIMWin32  String EnableOverride, ToSubclass
SupportsCreate                                   True Boolean EnableOverride, Restricted
SupportsDelete                                   True Boolean EnableOverride, Restricted

Now in my DriverEntry I am using the following code (some code removed for clarity):

/// <summary>
/// UUID = "{8502C4DC-5FBB-11D2-AAC1-006008C78BC7}" --> Win32_Process
/// </summary>
static const GUID GUID_WMI_WIN32_PROCESS =
{ 0x8502C4DCL, 0x5FBB, 0x11D2, { 0xAA, 0xC1, 0x00, 0x60, 0x08, 0xC7, 0x8B, 0xC7 } };

PVOID Win32Process = NULL;
NTSTATUS Status = IoWMIOpenBlock(&GUID_WMI_WIN32_PROCESS, WMIGUID_NOTIFICATION | SYNCHRONIZE, &Win32Process );
if (!NT_SUCCESS(Status) || Win32Process == NULL) {
	// error handling
}

Status = IoWMISetNotificationCallback(Win32Process, MyWmiCallback, NULL);
if (!NT_SUCCESS(Status) ) {
	// error handling
}

My callback is for the moment just as follows:

_Use_decl_annotations_
EXTERN_C VOID MyWmiCallback(
	_In_ PWNODE_EVENT_ITEM Wnode,
	_In_ PVOID             Context
) {
	UNREFERENCED_PARAMETER(Wnode);
	UNREFERENCED_PARAMETER(Context);

	KdPrint(("Win32Process: PID(%u) TIB(%u)\r\n",
		HandleToULong(PsGetCurrentProcessId()),
		HandleToULong(PsGetCurrentThreadId())
	));
}

Despite the WMI APIs returning STATUS_SUCCESS and the pointer to the WMI block being not null the callback is never reached after executing a command line like this one: wmic.exe process call create cmd.exe. Please note that I also tried with the GUID of the CIM_Process class as well.

Finally, my driver is not registered via IoWMIRegistrationControl, so I do not know if this is the reason or something completely unrelated. I am obviously missing something and I was wondering if anyone ever faced this issue.

It’s possible I have misunderstood things, but as I understand it, that API is not used to register a WMI “filter”. WMI, exactly like Kernel Streaming, has properties, methods, and events. Properties return information upon request. Methods take actions upon request. Events can send information back asynchronously. THAT’S what you’re registering for. It’s not monitoring, it for those specific events that a driver has said it wants to send. I’m not aware of any ability to insert a driver into a WMI communication.

1 Like

You have to specify an event, not a class. AFAICT win32_process doesn’t have any events. If you want to get notified about process creation why not register for process creation callbacks?

1 Like

Win32_ProcessStartTrace is an event block that does what you want.

Thanks everyone for the answers.

My objective with all of this is to identify when the WMI facility is being used to conduct specific actions (e.g., creating a process, creating a service, listing shadow copies, etc …) and I want to find a more elegant way to get than checking the command line passed to the process creation/termination callback.

I will look into Win32_ProcessStartTrace, thanks and see if there is similar event pre-created for other actions I am looking for. I supposed I could create new WMI event block myself and then create a callback for it. Also because applications could use user-mode Windows APIs instead of starting a process with wmic.exe image.

Also you can test all of this from user mode, like with simple powershell scripts.

My objective with all of this is to identify when the WMI facility is being used to conduct specific actions (e.g., creating a process,

Then you will be disappointed. You are just going to observe when a WMI event block gets signaled. Win32_ProcessStartTrace, for example, is signaled whenever a process is started, any process.