Subscribing to Process Creation, Thread Creation and Image Load Notifications from a Kernel Driver
This is a quick lab to play with some of the interesting notifications that kernel drivers can subscribe to:
PsSetCreateProcessNotifyRoutine- notifies the driver about new/terminated processesPsSetCreateProcessNotifyRoutineEx- notifies the driver about new processes being created, allows to kill them before they can runPsSetCreateThreadNotifyRoutine- notifies the driver about new/terminated threadsPsSetLoadImageNotifyRoutine- notifies the driver about DLLs loaded by processes
PsSetCreateProcessNotifyRoutine
PsSetCreateProcessNotifyRoutine takes two parameters:
NTSTATUS PsSetCreateProcessNotifyRoutine(
// pointer to a function to be called when a process is spawned or terminated
PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
// specifies whether to subscribe or unsubscribe from this event
BOOLEAN Remove
);Below is a snippet that shows how the routine sCreateProcessNotifyRoutine (line 2) gets registered for new/terminated process notifications on line 24:
// handle incoming notifications about new/terminated processes
void sCreateProcessNotifyRoutine(HANDLE ppid, HANDLE pid, BOOLEAN create)
{
if (create)
{
PEPROCESS process = NULL;
PUNICODE_STRING parentProcessName = NULL, processName = NULL;
PsLookupProcessByProcessId(ppid, &process);
SeLocateProcessImageName(process, &parentProcessName);
PsLookupProcessByProcessId(pid, &process);
SeLocateProcessImageName(process, &processName);
DbgPrint("%d %wZ\n\t\t%d %wZ", ppid, parentProcessName, pid, processName);
}
else
{
DbgPrint("Process %d lost child %d", ppid, pid);
}
}
// register sCreateProcessNotifyRoutine function to receive notifications about new/terminated processes
PsSetCreateProcessNotifyRoutine(sCreateProcessNotifyRoutine, FALSE);Below shows how the routine sCreateProcessNotifyRoutine gets executed when a new process hostname.exe (PID 2892) is spawned by powershell (PID 7176). Additionally, it shows that the process 7176 (hostname) terminated:

PsSetLoadImageNotifyRoutine
PsSetLoadImageNotifyRoutine only takes one parameter - a pointer to a function that will handle notifications about DLLs that processes running on the system loaded:
Below indicates that the routine sLoadImageNotifyRoutine is going to handle our notifications as registered with PsSetLoadImageNotifyRoutine on line 14:
Testing the driver - once we open a notepad.exe, our driver gets notified about all the modules that notepad.exe loaded:

PsSetCreateThreadNotifyRoutine
PsSetCreateThreadNotifyRoutine only takes one parameter - a pointer to a function that will handle notifications about new or killed threads across all the system processes:
Below indicates that the routine sCreateThreadNotifyRoutine is going to handle our notifications as registered with PsSetCreateThreadNotifyRoutine on line 15:
Testing the driver now, we can see we are indeed geting notified about new and terminated threads across processes on our system:

PsSetCreateProcessNotifyRoutineEx
PsSetCreateProcessNotifyRoutineEx takes two arguments:
Below is a snippet that shows how the routine sCreateProcessNotifyRoutineEx (line 3) gets registered for new process notifications on line 19. Processes with commandline containing notepad in them will be killed by setting the createInfo.reationStatus member to STATUS_ACCESS_DENIED (line 13):

Below shows how an attempt to spawn notepad.exe is blocked by our driver:

Code
Belos is the full working driver code that registers all the callback routines mentioned above:
References
Last updated