I wrote simple Driver for scan new created process. Firstly I create 2 event object one for usermodeapp and one for kernelmode. In DriverEntryRoutine i call IoCreateNotificationEvent to creating event(A) object for usermode app, and in the user side i create event(B) and send it driver via ioctl.Then driver uses ObReferenceObjectByHandle(B) to access user mode handle. After this usermodeapp send next ioctl to start PsSetCreateProcessNotifyRoutineEx routine. It works well. So when new process is created , inside CallBack function I firstly send signal(KeSetEvent(A)) to wake up usermode app and call WaitForSingleObject(B). And when usermode app wake up it sleeping for 5 seconds and then send signal to kernel via SetEvent(B).Its also works fine. But if I want to print count of created process I didnt get all of newly created process. Why? I put source code and attach visual studio project files: I will be happy if someone help me. Tahnk you very much for reading.
Source Code:
UserModeAPP:
#include <Windows.h>
#include <stdio.h>
#define IOCTL_RECV_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define IOCTL_START_MONITOR CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ALL_ACCESS)
int main(void)
{
HANDLE hEvent = NULL;
HANDLE hEvent2 = NULL;
HANDLE hDriver = INVALID_HANDLE_VALUE;
DWORD dwRet = 0;
int i = 0;
hDriver = CreateFileW(L"\\\\.\\XXEvent", GENERIC_READ |GENERIC_WRITE,
FILE_SHARE_READ |FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDriver == INVALID_HANDLE_VALUE)
{
printf("Error open driver\n");
return -1;
}
hEvent = CreateEventW(NULL, TRUE, FALSE, L"XXTESTEVENT");
if (hEvent == NULL)
{
printf("Error CreateEvent\n");
return -1;
}
hEvent2 = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\XXTESTEVENT2");
if (hEvent2 == NULL)
{
printf("Error open event2");
return -1;
}
DeviceIoControl(hDriver, IOCTL_RECV_EVENT, (PVOID)&hEvent, sizeof(HANDLE), NULL, 0, &dwRet, NULL);
DeviceIoControl(hDriver, IOCTL_START_MONITOR, NULL, 0, NULL, 0, &dwRet, NULL);
while (1)
{
WaitForSingleObject(hEvent2, INFINITE);
i++;
Sleep(5000);
printf("Process Created:%d\n",i);
SetEvent(hEvent);
ResetEvent(hEvent);
}
}
SourceCode KernelMode:
#include <ntddk.h>
#define IOCTL_RECV_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define IOCTL_START_MONITOR CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ALL_ACCESS)
UNICODE_STRING gDeviceName = RTL_CONSTANT_STRING(L"\\Device\\XXTEST");
UNICODE_STRING gSymbolicLink = RTL_CONSTANT_STRING(L"\\??\\XXEvent");
UNICODE_STRING EventName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\XXTESTEVENT2");
PDEVICE_OBJECT gDeviceObject = NULL;
PKEVENT gEvent = { 0 };
PKEVENT localEvent = { 0 };
HANDLE hEvent = NULL;
KGUARDED_MUTEX gMutex = { 0 };
VOID XXoutine(PEPROCESS Process, HANDLE hProcessID, PPS_CREATE_NOTIFY_INFO Create)
{
UNREFERENCED_PARAMETER(Process);
UNREFERENCED_PARAMETER(hProcessID);
UNREFERENCED_PARAMETER(Create);
if (Create != NULL)
{
KeAcquireGuardedMutex(&gMutex);
KeSetEvent(localEvent, 0, FALSE);
KeClearEvent(localEvent);
KeWaitForSingleObject(gEvent, Executive, UserMode, FALSE, NULL);
/*KeClearEvent(gEvent);*/
/*KeReleaseGuardedMutex(&gMutex);*/
DbgPrint("%wZ", Create->ImageFileName);
KeReleaseGuardedMutex(&gMutex);
}
}
VOID Unload(PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
IoDeleteSymbolicLink(&gSymbolicLink);
IoDeleteDevice(gDeviceObject);
PsSetCreateProcessNotifyRoutineEx(XXoutine, TRUE);
ZwClose(hEvent);
DbgPrint("Unloaded");
}
NTSTATUS IrpCreateClose(PDEVICE_OBJECT pDeviceObject, PIRP irp)
{
UNREFERENCED_PARAMETER(pDeviceObject);
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID RegisterNotify(VOID)
{
NTSTATUS status = STATUS_SUCCESS;
status = PsSetCreateProcessNotifyRoutineEx(XXoutine, FALSE);
if (!NT_SUCCESS(status))
{
DbgPrint("Error create notify routine\n");
}
}
NTSTATUS IoCtrl(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(pDeviceObject);
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
PVOID OutBuffer = Irp->AssociatedIrp.SystemBuffer;
HANDLE hUserHandle = NULL;
NTSTATUS status = STATUS_SUCCESS;
if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_RECV_EVENT)
{
hUserHandle = *(HANDLE*)OutBuffer;
status = ObReferenceObjectByHandle(hUserHandle, SYNCHRONIZE, *ExEventObjectType, UserMode, &gEvent, NULL);
if (!NT_SUCCESS(status))
{
DbgPrint("Error get usermode handle\n");
}
else {
DbgPrint("Yeah i get usermode handle");
}
}
if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_START_MONITOR)
{
RegisterNotify();
status = STATUS_SUCCESS;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS status = STATUS_SUCCESS;
DriverObject->DriverUnload = Unload;
status = IoCreateDevice(DriverObject,
0,
&gDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gDeviceObject);
if (!NT_SUCCESS(status))
{
DbgPrint("Error create DeviceDirectoryData object");
return status;
}
status = IoCreateSymbolicLink(&gSymbolicLink, &gDeviceName);
if (!NT_SUCCESS(status))
{
DbgPrint("Error IoCreateSymbolicLink");
IoDeleteDevice(gDeviceObject);
return status;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoCtrl;
KeInitializeGuardedMutex(&gMutex);
localEvent = IoCreateNotificationEvent(&EventName, &hEvent);
KeClearEvent(localEvent);
return status;
}