1. 程式人生 > >進程線程創建與退出監視(DBGVIEW打印)

進程線程創建與退出監視(DBGVIEW打印)

UC RM associate IE created bool reserve 感覺 process

曾經想著做個自己的主動防禦項目,就是監控而已,實現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;
}

進程線程創建與退出監視(DBGVIEW打印)