您的位置:首页 > 其它

PsSetCreateProcessNotifyRoutine函数和源码分析

2013-08-02 00:23 585 查看
一.函数: 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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: