PsSetCreateProcessNotifyRoutine监控进程创建

PsSetCreateProcessNotifyRoutine函数用来注册一个进程创建的回调函数,当有新从进程被创建时,就把父进程的ID,和子进程(被创建的进程)ID传给回调函数,通过回调函数,可以监控新创建的进程

NTSTATUS PsSetCreateProcessNotifyRoutine(
  _In_  PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
  _In_  BOOLEAN Remove
);

想要实现的功能:新进程被系统创建时,打印出父进程和子进程的名字

在回调函数中可以直接获取两个进程的PID,但是要想通过PID得到进程名字,也有很多种方式。
但最简单的是还是通过PsLookupProcessByProcessId函数来根据PID获取EPROCESS结构体,然后可以直接通过结构体+偏移的方式读取到该进程的名字。

需要注意的是,在使用PsLookupProcessByProcessId得到一个 EPROCESS结构以后,系统会对该进程的引用计数累加1,需要在不使用该结构时,及时调用ObDereferenceObject解除引用计数

也可以使用PsGetProcessImageFileName函数来获取,其内部实现原理也是通过EPROCESS+偏移的方式得到的进程名字

进程名字在EPROCESS结构体偏移0x16C的位置,可能不同的系统版本,偏移会有区别。
在这里插入图片描述
再来看PsGetProcessImageFileName函数的反汇编,是不是也贼简单:
[图片]
效果:
在这里插入图片描述

完整代码:

extern NTSYSAPI PUCHAR NTAPI PsGetProcessImageFileName(PEPROCESS Process);


// 监控进程创建回调函数
VOID CreateProcessNotify(IN HANDLE  ParentId, IN HANDLE  ChildId, IN BOOLEAN  Create)
{
    PEPROCESS ParentEprocess = NULL;
    PEPROCESS ChildEprocess = NULL;
    NTSTATUS status;
    if (Create)
    {
        
        // 获取EPROCESS结构体
        status = PsLookupProcessByProcessId(ParentId, &ParentEprocess);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("Get Parent Eprocess Failed\n"));
            return;
        }
        status = PsLookupProcessByProcessId(ChildId, &ChildEprocess);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("Get Child Eprocess Failed\n"));
            return;
        }

        // 通过EPROCESS获取进程名
        KdPrint((
            "ParentName:%s---> ChildName:%s\n",
            PsGetProcessImageFileName(ParentEprocess),
            PsGetProcessImageFileName(ChildEprocess)
            ));

        ObDereferenceObject(ParentEprocess);
        ObDereferenceObject(ChildEprocess);
    }
}


VOID DriverUnload(PDRIVER_OBJECT driver)
{
    // 卸载时,移除回掉
    PsSetCreateProcessNotifyRoutine(CreateProcessNotify, TRUE);
    DbgPrint("first: Our driver is unloading...\r\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
{
    DbgBreakPoint();

    PsSetCreateProcessNotifyRoutine(CreateProcessNotify, FALSE);
   
    pDriver->DriverUnload = DriverUnload;

    return STATUS_SUCCESS;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值