Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
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.
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Writing WDF Drivers | 12 September 2022 | Live, Online |
Internals & Software Drivers | 23 October 2022 | Live, Online |
Kernel Debugging | 14 November 2022 | Live, Online |
Developing Minifilters | 5 December 2022 | Live, Online |
Comments
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.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
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?
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 withwmic.exe
image.Also you can test all of this from user mode, like with simple powershell scripts.
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.