Implementing Process Creation and Termination Monitoring in Windows Kernel Drivers
Process Notification Callback Implementation
The implementation involves three primary components: defining the callback function, registering it, and unregistering it.
#include <ntddk.h>
// Callback prototype declaration
VOID ProcessNotificationCallback(
_Inout_ PEPROCESS Process,
_In_ HANDLE ProcessID,
_In_opt_ PPS_CREATE_NOTIFY_INFO CreationData
);
// Unload routine
DRIVER_UNLOAD DriverUnregister;
NTSTATUS
DriverInitialize(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS regStatus;
DriverObject->DriverUnload = DriverUnregister;
// Register the callback
regStatus = PsSetCreateProcessNotifyRoutineEx(ProcessNotificationCallback, FALSE);
return STATUS_SUCCESS;
}
NTSTATUS
DriverUnregister(_In_ PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
NTSTATUS unregStatus;
// Unregister the callback
unregStatus = PsSetCreateProcessNotifyRoutineEx(ProcessNotificationCallback, TRUE);
return unregStatus;
}
// Callback implementation
VOID
ProcessNotificationCallback(
_Inout_ PEPROCESS Process,
_In_ HANDLE ProcessID,
_In_opt_ PPS_CREATE_NOTIFY_INFO CreationData
)
{
UNREFERENCED_PARAMETER(Process);
UNREFERENCED_PARAMETER(ProcessID);
if (CreationData != NULL) {
// Process creation event
// To block creation, set:
// CreationData->CreationStatus = STATUS_ACCESS_DENIED;
} else {
// Process termination event
}
}
Implementation Requirements
Linker Settings
For the notification callback to function correctly, the /INTEGRITYCHECK flag must be added to the linker options.
Callback Registration
The PsSetCreateProcessNotifyRoutineEx functon is used.
NTSTATUS
PsSetCreateProcessNotifyRoutineEx (
_In_ PCREATE_PROCESS_NOTIFY_ROUTINE_EX CallbackFunction,
_In_ BOOLEAN RemoveFlag
);
CallbackFunction: Pointer to the callback routine.RemoveFlag:FALSEto register,TRUEto unregister.
The callback function type PCREATE_PROCESS_NOTIFY_ROUTINE_EX is defined as:
typedef VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE_EX) (
_Inout_ PEPROCESS Process,
_In_ HANDLE ProcessId,
_Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo
);
PEPROCESS: Opaque kernel process object.ProcessId: The process identifier.CreateInfo: Pointer to creation data;NULLindicates process termination.
Accessing Process Information
When CreateInfo is not NULL, it points to a PS_CREATE_NOTIFY_INFO structure:
typedef struct _PS_CREATE_NOTIFY_INFO {
_In_ SIZE_T Size;
union {
_In_ ULONG Flags;
struct {
_In_ ULONG FileOpenNameAvailable : 1;
_In_ ULONG Reserved : 31;
};
};
_In_ HANDLE ParentProcessId;
_In_ CLIENT_ID CreatingThreadId;
_Inout_ struct _FILE_OBJECT *FileObject;
_In_ PCUNICODE_STRING ImageFileName;
_In_opt_ PCUNICODE_STRING CommandLine;
_Inout_ NTSTATUS CreationStatus;
} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;
Key accessible fields include:
ParentProcessId: ID of the parent process.ImageFileName: Path to the executable image.CommandLine: Process command-line arguments (may beNULL).CreationStatus: Status of the creation operation.
Blocking Process Creation
To prevent a process from launching, set the CreationStatus member of the PS_CREATE_NOTIFY_INFO structure to STATUS_ACCESS_DENIED within the callback.