一些应用中,要用到判断某个进程或者所有进程的启动与退出事件。比如,我们做局部代理软件时,就要判断某个进程运行了没有,退出了没有。或者守护进程功能等。
很早以前,大家可能用得多一点的是用枚举进程,或者VMI来监视进程启动或退出。
但是这两种方法都存在着占用资源过高,VMI还在某些精简版的WIN系统中给禁用了从而引起监视不到问题出现。
后来经过大量市场测试,发现用回调函数PsSetCreateProcessNotifyRoutine来监视进程,稳定,可靠,不占CPU,不漏进程,适用于所有WIN系统。效率相当高。
这里发上驱动层代码:
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegisterString)
{
NTSTATUS status = STATUS_SUCCESS;
//初始化各个历程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
//创建,并出事换设备对象
UNICODE_STRING strDevName;
RtlInitUnicodeString(&strDevName, DEVICE_NAME);
//创建设备对象
PDEVICE_OBJECT pDevObj;
status = IoCreateDevice(
pDriverObj,
sizeof(DEVICE_EXTENSION),//为设备国战结构申请空间
&strDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj
);
if (!NT_SUCCESS(status))
{
return status;
}
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
//创建符号链接
UNICODE_STRING strLinkName;
RtlInitUnicodeString(&strLinkName, LINK_NAME);
//创建 关联
status = IoCreateSymbolicLink(&strLinkName, &strDevName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
//将设备指针保存到全局变量中,方便后续使用
g_pDeviceObject = pDevObj;
//为了能够监视用户层进程,创建事件对象
UNICODE_STRING szProcessEventString;
RtlInitUnicodeString(&szProcessEventString, EVENT_NAME);
//此函数待查
pDevExt->ProcessEvent = IoCreateNotificationEvent(&szProcessEventString, &pDevExt->hProcessHandle);
//设置非授信状态
KeClearEvent(pDevExt->ProcessEvent);
//设置回调函数历程
status = PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback, FALSE);
return status;
}