驱动层PsSetCreateProcessNotifyRoutine监视进程 ,返回应用层

源程序大致过程如下:


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;
}


 

你可能感兴趣的:(内核编程)