内核中常见的通知的使用

应用场景

一个程序打开,可以用驱动捕获到这个程序的PID ,程序名字,和这个程序用到的DLL模块等信息,包括加载的顺序都可以获取

注册一个通知和对应的回调函数就可以实现这一的功能

全部代码:

/**********************驱动程序学习例程************************
*  平台:visual studio 2019 
*  功能:内核通知
*  编写:ZGL
*  日期:2021-01-22
*
*	 更改记录:未更改
******************************************************************/


#include <ntifs.h>
#include <windef.h>

PCHAR PsGetProcessImageFileName(PEPROCESS epobj);

VOID MyCreateProcessNotify(HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create)
{
    
    
	if (Create)
	{
    
    
		PEPROCESS tempep = NULL;

		NTSTATUS status = STATUS_SUCCESS;

		status = PsLookupProcessByProcessId(ProcessId, &tempep);

		if (NT_SUCCESS(status))
		{
    
    
			ObDereferenceObject(tempep);

			PCHAR imagename=PsGetProcessImageFileName(tempep);

			DbgPrint("pid<%d>--name<%s>\n", ParentId, imagename);
		}
	}
	return;
}

VOID MyLoadImageNotify( PUNICODE_STRING FullImageName,HANDLE ProcessId,PIMAGE_INFO ImageInfo)
{
    
    
	PEPROCESS tempep = NULL;

	NTSTATUS status = STATUS_SUCCESS;

	status = PsLookupProcessByProcessId(ProcessId, &tempep);

	if (NT_SUCCESS(status))
	{
    
    
		ObDereferenceObject(tempep);

		PCHAR imagename = PsGetProcessImageFileName(tempep);

		DbgPrint("<%s>Load Image <%wZ> \n-Baseaddr <%p>\n-size is <%llx>\n", imagename, FullImageName, ImageInfo->ImageBase,ImageInfo->ImageSize);
	}
	
	return;
}

VOID MyCreteThreadNotify(
	_In_ HANDLE ProcessId,
	_In_ HANDLE ThreadId,
	_In_ BOOLEAN Create)
{
    
    
	if (Create)
	{
    
    
		PEPROCESS tempep = NULL;

		NTSTATUS status = STATUS_SUCCESS;

		status = PsLookupProcessByProcessId(ProcessId, &tempep);

		if (NT_SUCCESS(status))
		{
    
    
			ObDereferenceObject(tempep);

			PCHAR imagename = PsGetProcessImageFileName(tempep);

			DbgPrint("<%s> create thread <%d>\n", imagename,ThreadId);
		}

	}


	return;
}


VOID DrvUnload(PDRIVER_OBJECT pdriver)
{
    
    
	///PsSetCreateProcessNotifyRoutine注册的通知需要用这个卸载,这个注册和卸载函数同名
	PsSetCreateProcessNotifyRoutine(MyCreateProcessNotify, TRUE);
	
	//PsSetLoadImageNotifyRoutine注册的通知需要用这个卸载
	PsRemoveLoadImageNotifyRoutine(MyLoadImageNotify);

	//PsSetCreateThreadNotifyRoutine注册的通知需要用这个卸载
	PsRemoveCreateThreadNotifyRoutine(MyCreteThreadNotify);

	DbgPrint("Unload\n");
	
	return;
	

}



NTSTATUS DriverEntry(PDRIVER_OBJECT pdriver, PUNICODE_STRING reg_path)
{
    
    
	
	NTSTATUS status = STATUS_SUCCESS;
	pdriver->DriverUnload = DrvUnload;

	//PsSetCreateProcessNotifyRoutine 有程序打开就会执行参数1的函数,创建这个回调和卸载这个回调都是用这个函数
	status = PsSetCreateProcessNotifyRoutine(MyCreateProcessNotify, FALSE);//回调函数,有程序打开会执行MyCreateProcessNotify函数

	//每当有模块加载的时候出发这个通知,打开一个程序后会加载很多模块,包括系统的,自身的,这个通知都能捕获到
	status = PsSetLoadImageNotifyRoutine(MyLoadImageNotify);

	//捕获线程通知
	status = PsSetCreateThreadNotifyRoutine(MyCreteThreadNotify);

	return 0;
}

执行效果:

这个没有加线程捕获通知是的代码铺货的信息
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
还能右键删除这些回调
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lygl35/article/details/113027591