标签:NPU set system stack 自己的 实现 sso wdm cpp
曾经想着做个自己的主动防御项目,就是监控而已,实现RING3通信,各方参考学习,想着HOOK 来着
但是有一次知道了无HOOK的方式,感觉这挺方便呀 还是微软承认的函数,那我就实现一套监控的方案,考虑到逆向分析的话就准备后面
有事没事空闲了就去尽量实现HOOK的方式,希望一切顺利,少蓝屏几次。谢谢胡老师教程指导!
这里是代码和注意:实现的是监控进程线程创建退出,如果calc创建则阻止创建(W7 64位通过)
其中注意的是:
进程监视函数
PsSetCreateProcessNotifyRoutineEx(MSDN可查)。此函数的原型为:
| NTSTATUS PsSetCreateProcessNotifyRoutineEx( __in PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine, __in BOOLEAN Remove );  | 
接下来注意回调函数 NotifyRoutine 的原型:
| VOID CreateProcessNotifyEx( __inout PEPROCESS Process, //新进程 EPROCESS __in HANDLE ProcessId, //新进程 PID __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo //新进程详细信息(仅在创建进程时有效) );  | 
接下来看看 PS_CREATE_NOTIFY_INFO 结构体的定义:
| typedef struct _PS_CREATE_NOTIFY_INFO { SIZE_T Size; union { ULONG Flags; struct { ULONG FileOpenNameAvailable :1; ULONG Reserved :31; }; }; HANDLE ParentProcessId; CLIENT_ID CreatingThreadId; struct _FILE_OBJECT *FileObject; PCUNICODE_STRING ImageFileName; PCUNICODE_STRING CommandLine; NTSTATUS CreationStatus; } PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;  | 
父进程 ID,父线ID
甚至直接包括程序的路径(不用通过 FileObject 来取,路径直接包含在了
ImageFileName 里)和命令行参数!
最紧要的是,如果要阻止进程创建,直接把
此结构体的 CreationStatus 成员改为 STATUS_UNSUCCESSFUL 
线程监控函数:
NTKERNELAPI
NTSTATUS
PsSetCreateThreadNotifyRoutine(
    _In_ PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
    );(MSDN可查)
他的回调函数如下:
typedef
VOID
(*PCREATE_THREAD_NOTIFY_ROUTINE)(
    _In_ HANDLE ProcessId,
    _In_ HANDLE ThreadId,
    _In_ BOOLEAN Create
    );
这样很容易就看到进程 线程ID(句柄)了。而且第三位BOOLEAN型代表创建成功与否是一个 yes or no 的选择。
下面是测试代码
ProcessDrv.h:
#include <ntddk.h>
#define dprintf DbgPrint
#define	DEVICE_NAME			L"\\Device\\monitor_create_process_x64"
#define LINK_NAME			L"\\DosDevices\\monitor_create_process_x64"
#define LINK_GLOBAL_NAME	L"\\DosDevices\\Global\\monitor_create_process_x64"
ProcessNotify.h
NTKERNELAPI PCHAR PsGetProcessImageFileName(PEPROCESS Process);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
PCHAR GetProcessNameByProcessId(HANDLE ProcessId)
{
	NTSTATUS Status=STATUS_UNSUCCESSFUL;
	PEPROCESS ProcessObj=NULL;
	PCHAR StringName =NULL;
	Status = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
	if(NT_SUCCESS(Status))
	{
		StringName = PsGetProcessImageFileName(ProcessObj);
		ObfDereferenceObject(ProcessObj);//EPROCESS 里结构是有ProcessImageFileName
	}
	return StringName;
}
VOID MyCreateProcessNotifyEx
(
	__inout   PEPROCESS Process,
	__in      HANDLE ProcessId,
	__in_opt  PPS_CREATE_NOTIFY_INFO CreateInfo
)
{
	
	char v1[16]={0};
	if(CreateInfo!=NULL)	//进程创建事件
	{
		DbgPrint("[flame看到进程在创建(x64)][%ld]%s创建进程: %wZ",
				CreateInfo->ParentProcessId,
				GetProcessNameByProcessId(CreateInfo->ParentProcessId),
				CreateInfo->ImageFileName);
		strcpy(v1,PsGetProcessImageFileName(Process));
		if(!_stricmp(v1,"calc.exe"))
		{
			DbgPrint("禁止创建计算器进程!");
			CreateInfo->CreationStatus=STATUS_UNSUCCESSFUL;	//禁止创建进程
		}
	}
	else
	{
		DbgPrint("[flame看到进程在退出(x64)]进程退出: %s",PsGetProcessImageFileName(Process));
	}
}
VOID MyCreateThreadNotify
(
	IN HANDLE  ProcessId,
	IN HANDLE  ThreadId,
	IN BOOLEAN  Create
)
{
	if (Create)
	{
		DbgPrint("[flame看到线程在创建(x64)]线程创建! PID=%ld;TID=%ld", ProcessId, ThreadId);
	}
	else
	{
		DbgPrint("[flame看到线程在退出(x64)]线程退出! PID=%ld;TID=%ld", ProcessId, ThreadId);
	}
}
ProcessDrv.cpp:
#include <ntddk.h>
#include "ProcessDrv.h"
#include "ProcessNotify.h"  
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{	
	UNICODE_STRING strLink;
	RtlInitUnicodeString(&strLink, LINK_NAME);
	IoDeleteSymbolicLink(&strLink);
	IoDeleteDevice(pDriverObj->DeviceObject);
	//remove create process/thread notify
	PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)MyCreateProcessNotifyEx,TRUE);
	PsRemoveCreateThreadNotifyRoutine(MyCreateThreadNotify);
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
	PIO_STACK_LOCATION pIrpStack;
	ULONG IoControlCode;
	PVOID IoBuffer;
	ULONG InputLength;
	ULONG OutputLength;
	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	IoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	IoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	InputLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	OutputLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	switch(IoControlCode)
	{
	}
	if(Status == STATUS_SUCCESS)
		pIrp->IoStatus.Information = OutputLength;
	else
		pIrp->IoStatus.Information = 0;	
	pIrp->IoStatus.Status = Status;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return Status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
	NTSTATUS V1 = 0;
	NTSTATUS Status = STATUS_SUCCESS;
	UNICODE_STRING LinkName;
	UNICODE_STRING DeviceName;  
	PDEVICE_OBJECT DevObject;
	pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
	pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
	pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
	pDriverObj->DriverUnload = DriverUnload;
	RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
	Status = IoCreateDevice(pDriverObj, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DevObject);
	if (!NT_SUCCESS(Status))
	{
		return Status;
	}
	if (IoIsWdmVersionAvailable(1, 0x10))//WDM YES OR NO
	{
		RtlInitUnicodeString(&LinkName, LINK_GLOBAL_NAME);
	}
	else
	{ 
		RtlInitUnicodeString(&LinkName, LINK_NAME);
	}
	Status = IoCreateSymbolicLink(&LinkName, &DeviceName);
	if(!NT_SUCCESS(Status))
	{
		IoDeleteDevice(DevObject);
		return Status;
	}
	V1 =PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)MyCreateProcessNotifyEx,FALSE);
	DbgPrint("PsSetCreateProcessNotifyRoutineEx return: %x", V1);
	V1 =PsSetCreateThreadNotifyRoutine(MyCreateThreadNotify);
	DbgPrint("PsSetCreateThreadNotifyRoutine return: %x", V1);
	return STATUS_SUCCESS;
}
标签:NPU set system stack 自己的 实现 sso wdm cpp
原文地址:https://www.cnblogs.com/L-Sunny/p/9094927.html