进程监视函数PsSetCreateProcessNotifyRoutine

这两天看书,看到这个函数,感觉挺有意思,就测试了下。从便面意思来看PsSetCreateProcessNotifyRoutine 设置创建进程通知的函数。

The PsSetCreateProcessNotifyRoutine routine adds a driver-supplied callback routine to, or removes it from, a list of routines to be called whenever a process is created or deleted.
NTSTATUS
 PsSetCreateProcessNotifyRoutine(
   IN PCREATE_PROCESS_NOTIFY_ROUTINE  NotifyRoutine,
   IN BOOLEAN  Remove
   );

根据wdk可知,此函数可以设置一个回调函数,每当有进程建立或者进程关闭时,会调用该回调函数,因此可以用来简单的监视进程的创建于结束。

撸主简单的测试了下,写了个简单的小程序,设置回调函数,每当有新进程创建时,就结束新创建的进程,代码如下:

#include 

//进程监视回调函数
VOID ProcessMonitorCallback(
						IN HANDLE hParentId,
						IN HANDLE hProcessId, 
						IN BOOLEAN bCreate)
{
	NTSTATUS status;
	HANDLE procHandle = NULL;
	CLIENT_ID ClientId;
	
	OBJECT_ATTRIBUTES Obja;
	Obja.Length = sizeof(Obja);
	Obja.RootDirectory = 0;
	Obja.ObjectName = 0;
	Obja.Attributes = 0;
	Obja.SecurityDescriptor = 0;
	Obja.SecurityQualityOfService = 0;
	
	ClientId.UniqueProcess = (HANDLE)hProcessId;
	ClientId.UniqueThread = 0;
	//不管创建什么程序都关闭程序
 if(bCreate)   //bCreate 为True表示创建程序
 {
 //调用函数ZwOpenProcess函数,通过进程pid号获得进程句柄
	
	status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &Obja, &ClientId);
	if(status == STATUS_INVALID_PARAMETER_MIX)
	 DbgPrint("STATUS_INVALID_PARAMETER_MIX\n");
	else if(status == STATUS_INVALID_CID)
	 DbgPrint("STATUS_INVALID_CID\n");
	else if(status == STATUS_INVALID_PARAMETER)
	 DbgPrint("STATUS_INVALID_PARAMETER\n");
	else if(status == STATUS_ACCESS_DENIED)
	 DbgPrint("STATUS_ACCESS_DENIED\n");
	else 
		DbgPrint("STATUS_SUCCESS\n");
		
	if(procHandle != NULL)
		status = ZwTerminateProcess(procHandle,1);
	else
	{
		DbgPrint("failed to ZwOpenProcess...\n");
		return ;
	}
	//这里是我来判断没有成功结束进程用的
	switch(status)
	{
	 case STATUS_SUCCESS:
		DbgPrint("process %u has beed killed ...\n",hProcessId);
		break;
	 case STATUS_OBJECT_TYPE_MISMATCH:
		DbgPrint("failed to kill %u process,The specified handle is not a process handle. \n",hProcessId);
		break;
	 case STATUS_INVALID_HANDLE:
		DbgPrint("failed to kill %u process,The specified handle is not valid.\n",hProcessId);
		break;
	 case STATUS_ACCESS_DENIED:
		DbgPrint("failed to kill %u process,The driver cannot access the specified process object.\n",hProcessId);
		break;
	 case STATUS_PROCESS_IS_TERMINATING:
		DbgPrint("failed to kill %u process,The specified process is already terminating.\n",hProcessId);
		break;
	 default:
		break;
	}
	
		
	
 }
}
//驱动卸载函数
void DriverUnload(PDRIVER_OBJECT pDriveObj)
{
//取消监视
	PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback,TRUE);
	DbgPrint("driver unloaded ...\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegisterString)
{
	NTSTATUS status = STATUS_SUCCESS;
	//驱动卸载处理
	pDriverObj->DriverUnload = DriverUnload;
	status = PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback,FALSE);
	return status;
}


回调函数有三个参数,父进程pid号,该进程的pid号,还有一个创建或者结束进程的标志。

通过pid,调用函数ZwOpenProcess,获得进程的句柄,最后调用函数ZwTerminateProcess,结束新创建的进程(由于开始测试时,程序没有正确执行,撸主就打印了写信息,用来判断错误信息)

测试结果如下:

进程监视函数PsSetCreateProcessNotifyRoutine_第1张图片

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