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

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):

If PsSetCreateProcessNotifyRoutineEx is not working in your driver, you will need to add a /integritycheck switch in your linker configuration

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