PsSetCreateProcessNotifyRoutine函数和源码分析

一.函数: NTSTATUS PsSetCreateProcessNotifyRoutine(__in PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,__in BOOLEAN Remove)

<1>功能描述:创建一个回调函数,每当有进程创建的时候,系统就会调用这个回调函数

<2>参数:

          NotifyRoutine 参数:  

            其类型为:typedef  VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE)( IN HANDLE ParentId,IN HANDLE ProcessId,IN BOOLEAN Create);

              1.它提供了程序被创建和被删除的处理过程,可通过句柄ProcessId 得到被创建的程序,和通过createProcess创建该程序的父程序句柄为ParentId)

              2.当该程序没有被父进程打开时,ParentId句柄为NULL

              3. Create参数,如果程序正在被创建则为true,如果程序被卸载,则为false。

              4.创建通知是发生在程序的第一个线程被创建时,卸载通知是发生在程序的最后一个线程已经结束时。

              5.可能存在着,得到了卸载的通知却没有创建通知,此错误情况发生在程序被创建和卸载却没有一个线程曾经被创建过。

    

         FALSE参数:表示安装,ture表示移除 该注册,特别要注意的是,安装和移除是2对必须要存在的,否则会蓝屏

<3>返回值: 

              返回成功:STATUS_SUCCESS

               失败: TATUS_INVALID_PARAMETER

在Wrk中有其源码,下面作粗略分析:

typedef struct _EX_CALLBACK_ROUTINE_BLOCK
{
	EX_RUNDOWN_REF RundownProtect;
	PEX_CALLBACK_FUNCTION Function;
	PVOID Context;
} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;

#define PSP_MAX_CREATE_PROCESS_NOTIFY 8

EX_CALLBACK PspCreateProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY];


 NTSTATUS PsSetCreateProcessNotifyRoutine(__in PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,__in BOOLEAN Remove)
{

	ULONG i;
	PEX_CALLBACK_ROUTINE_BLOCK CallBack;

	PAGED_CODE();//此宏确保调用线程行在一个允许分页的足够低IRQL级别

	if (Remove) {//当回调被移除时: 
		for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++)
		{//PSP_MAX_CREATE_PROCESS_NOTIFY表示最大注册回调数目,固定数目为8

			//
			// Reference the callback so we can check its routine address.
			//
			CallBack = ExReferenceCallBackBlock (&PspCreateProcessNotifyRoutine[i]);//PspCreateProcessNotifyRoutine指向存在回调结构的数组
             //ExReferenceCallBackBlock 获得取回调结构
			if (CallBack != NULL) //调用成功
			{
				//
				// See if the routine matches our target
				//
				if ((PCREATE_PROCESS_NOTIFY_ROUTINE) ExGetCallBackBlockRoutine (CallBack) == NotifyRoutine)//ExGetCallBackBlockRoutine获取程序回调结构
				{//如果查找成功

					if (ExCompareExchangeCallBack (&PspCreateProcessNotifyRoutine[i],NULL,CallBack)) 
					{//将数组PspCreateProcessNotifyRoutine中的该CallBack用Null代替,清空处理

							InterlockedDecrement ((PLONG) &PspCreateProcessNotifyRoutineCount);//数目减少一,保证同一时刻只有一个线程访问该变量

							ExDereferenceCallBackBlock (&PspCreateProcessNotifyRoutine[i],CallBack);//断开系统回调数组与这个结构的联系

							//
							// Wait for any active callbacks to finish and free the block.
							//
							ExWaitForCallBacks (CallBack);//等待CallBack完成

							ExFreeCallBack (CallBack);//释放CallBack

							return STATUS_SUCCESS;
					}
				}
				ExDereferenceCallBackBlock (&PspCreateProcessNotifyRoutine[i],CallBack);//断开系统回调数组与这个结构的联系
			}
		}

		return STATUS_PROCEDURE_NOT_FOUND;
	} 
	else //如果要注册
	{
		//
		// Allocate a new callback block.
		// 
		CallBack = ExAllocateCallBack ((PEX_CALLBACK_FUNCTION) NotifyRoutine, NULL);//  //申请一个块内存,内容为null 
		if (CallBack == NULL) {
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++)
		{
			//
			// Try and swap a null entry for the new block.
			//
			if (ExCompareExchangeCallBack (&PspCreateProcessNotifyRoutine[i],
				CallBack,
				NULL))//找到一个空位存放
			{
					InterlockedIncrement ((PLONG) &PspCreateProcessNotifyRoutineCount);//增加
					return STATUS_SUCCESS;
			}
		}
		//
		// No slots left. Free the block and return.
		//
		ExFreeCallBack (CallBack);
		return STATUS_INVALID_PARAMETER;
	}

}



你可能感兴趣的:(内核函数,齐齐来踢球)