源程序大致过程如下:
1、驱动程序调用函数PsSetCreateProcessNotifyRoutine 设置监视进程的回调函数ProcessMonitorCallback ,当应用层有进程创建时,驱动程序调用回调函
数ProcessMonitorCallback获得新建或者结束的进程信息,将信息存放到扩展结构中,以便通过method_buffer方式传回应用层。
2、当回调函数ProcessMonitorCallback执行并获得进程相关信息后,调用KeSetEvent(pDevExt->ProcessEvent,0,FALSE); ,将事件设置为授信状态,
应用程函数WaitForSingleObject(hProcessEvent,INFINITE)不断监视,收到通知后,调用 DeviceIoControl 函数向驱动层发送消息,取回结果。
代码如下:
头文件:
//
///
#define IOCTL_NTPROCDRV_GET_PROCINFO \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_READ_ACCESS|FILE_WRITE_ACCESS)
//结构体,用户与内核交互的缓冲区格式,将这个结构向用户层返回进程信息
typedef struct _CallbackInfo
{
HANDLE hParentId;
HANDLE hProcessId;
BOOLEAN bCreate;
}CallbackInfo,*pCallbackInfo;
应用层:
#include
#include
#include
#include "monitorProc.h"
#pragma comment(lib,"Advapi32.lib")
int main()
{
//获取驱动程序的monitorProc.sys的完成目录
//在当前目录下
char szDriverPath[256];
char szLinkName[] = "slinkMonitorProc";
char *p;
GetFullPathName("monitorProc.sys",256,szDriverPath,&p);
//打开scm管理器
SC_HANDLE hScm = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hScm == NULL)
{
printf("打开服务控制管理器失败,可能因为你不具有administrator权限\n");
return -1;
}
//创建或打开服务
SC_HANDLE hService = CreateService(
hScm,
szLinkName,
szLinkName,
SC_MANAGER_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
szDriverPath,
NULL,
NULL,
NULL,
NULL,
NULL);
if(hService == NULL)
{
int nError = GetLastError();
if(nError == ERROR_SERVICE_EXISTS || nError == ERROR_SERVICE_MARKED_FOR_DELETE)
{
hService = OpenService(hScm,szLinkName,SERVICE_ALL_ACCESS);
}
}
if(hService == NULL)
{
printf("创建服务失败!\n");
return -1;
}
//启动服务
if(!StartService(hService,0,NULL))
{
int nError = GetLastError();
if(nError == ERROR_SERVICE_ALREADY_RUNNING)
{
printf("服务已经在运行!\n");
return -1;
}
}
//打开到驱动的所控设备的句柄
char sz[256]="";
sprintf(sz,"\\\\.\\%s",szLinkName);
HANDLE hDriver = CreateFile(
sz,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hDriver == INVALID_HANDLE_VALUE)
{
printf("打开设备失败!\n");
return -1;
}
//打开时间内核对象,等待驱动程序通知
HANDLE hProcessEvent = OpenEvent(SYNCHRONIZE,FALSE,"MonitorProcEvent");
CallbackInfo callbackinfo={0},callbacktemp ={0};
while(WaitForSingleObject(hProcessEvent,INFINITE) == WAIT_OBJECT_0)
{
printf("here message coming!!\n ");
printf("before recive callbackinfo->hProcesssId = %d\n",callbackinfo.hProcessId);
//想驱动发送控制代码
DWORD nBytesReturn;
BOOL bRet = DeviceIoControl(
hDriver,
IOCTL_NTPROCDRV_GET_PROCINFO,
NULL,
0,
&callbackinfo,
sizeof(callbackinfo),
&nBytesReturn,
NULL);
printf("recive buffer length bBytesReturn = %d\n",nBytesReturn);
if(bRet)
{
if(callbackinfo.hParentId != callbacktemp.hParentId || \
callbackinfo.hProcessId !=callbacktemp.hProcessId ||\
callbackinfo.bCreate != callbacktemp.bCreate)
{
if(callbackinfo.bCreate)
{
printf("有进程被创建, pid :%d\n",callbackinfo.hProcessId);
}
else
{
printf("有进程被结束, pid : %d \n",callbackinfo.hProcessId);
}
callbacktemp = callbackinfo;
}
else
{
printf("callbacktemp.hProcessId = %d\ncallbackinfo.hProcessId = %d\n",callbacktemp.hProcessId,callbackinfo.hProcessId);
}
}
else
{
printf("获取进程信息失败 !\n");
break;
}
}
CloseHandle(hDriver);
//服务完全停止运行
SERVICE_STATUS ss;
ControlService(hService,SERVICE_CONTROL_STOP,&ss);
//从scm数据库中删除服务
DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hScm);
return 0;
}
驱动层:
#include
#include
#include "monitorProc.h"
//定义驱动名称,符号链接名称,事件对象名称
#define DEVICE_NAME L"\\Device\\devMonitorProc"
#define LINK_NAME L"\\DosDevices\\slinkMonitorProc"
#define EVENT_NAME L"\\BaseNamedObjects\\MonitorProcEvent"
//设备对象扩展结构,存放一些必要信息
typedef struct _DEVICE_EXTENSION
{
HANDLE hProcessHandle;//事件对象句柄
PKEVENT ProcessEvent;// 用于和内核通信事件的对象指针
HANDLE hPParentId; //在回调函数中保存进程信息,传递给用户层
HANDLE hPProcessId;
BOOLEAN bPCreate; //true表示进程被创建,false表示进程被删除
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
//定义全局的设备对象指针
PDEVICE_OBJECT g_pDeviceObject;
//直接返回完成信息
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
//完成此请求
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
//I/O派遣历程处理
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint("monitorProc : DispatchIotcl...\n");
//默认返回失败
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
//取得此IRP的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
//取得设备扩展结构指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
//获取I/O控制代码
ULONG uIoContrlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
//取得I/O缓冲区的指针和其长度
pCallbackInfo pCallbackInfoBuff = (pCallbackInfo)pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;//输入缓冲区长度
ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;//输出缓冲区长度
switch(uIoContrlCode)
{
case IOCTL_NTPROCDRV_GET_PROCINFO: //想用户程序返回有事件发生的进程信息
{
if(uOutSize >= sizeof(CallbackInfo)) //输出缓冲区长度要大于返回结构大小
{
pCallbackInfoBuff->hParentId = pDevExt->hPParentId;
pCallbackInfoBuff->hProcessId = pDevExt->hPProcessId;
pCallbackInfoBuff->bCreate = pDevExt->bPCreate;
status = STATUS_SUCCESS;
}
DbgPrint("dispatch pcallbackinfobufff->hProcessId = %d\n",pCallbackInfoBuff->hProcessId);
}
break;
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
//完成请求
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return status;
}
//进程监视回调函数
VOID ProcessMonitorCallback(
IN HANDLE hParentId,
IN HANDLE hProcessId,
IN BOOLEAN bCreate)
{
//得到设备扩展的结构指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
//处理当前的设备扩展结构,传给应用层
pDevExt->hPParentId = hParentId;
pDevExt->hPProcessId = hProcessId;
pDevExt->bPCreate = bCreate;
DbgPrint("hProcessId = %d\n",hProcessId);
//出发这个时间,通知应用层监听程序
KeSetEvent(pDevExt->ProcessEvent,0,FALSE);
//设置为非授信状态
KeClearEvent(pDevExt->ProcessEvent);
}
//驱动卸载函数
void DriverUnload(PDRIVER_OBJECT pDriveObj)
{
PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback,TRUE);
//删除设备连接符号
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink,LINK_NAME);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriveObj->DeviceObject); //删除设备对象
DbgPrint("driver unloaded ...\n");
}
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;
}