进程线程创建与退出监视(DBGVIEW打印)

曾经想着做个自己的主动防御项目,就是监控而已,实现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;
}

原文地址:https://www.cnblogs.com/L-Sunny/p/9094927.html

时间: 2024-08-30 12:45:41

进程线程创建与退出监视(DBGVIEW打印)的相关文章

POSIX 线程的创建与退出

前言 创建线程: pthread_create() 退出线程: pthread_exit()return pthread_cancel() 线程的创建 使用多线程,首先就需要创建一个新线程.那么线程是如何被创建的呢,是用下面这个函数创建的. #include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *ar

Java并发编程:线程、进程的创建

首先要理清下进程.线程和应用程序概念. 从一定意义上讲,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行. a. 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体.它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示. b. 进程是一个"执行中的程序".程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的

在挂起的进程中创建一个远程线程

以挂起状态创建一个进程 invoke CreateProcess, NULL, szPath, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, addr @si, addr @pi 在该进程中创建一个远程线程 invoke CreateRemoteThread, hProcess, NULL, 0, eax, NULL, NULL, NULL 如果在恢复主线程之前,远程线程退出了,程序就会退出或没有界面(XP下会有这个问题,WIN7不会出现).

MFC进程的创建销毁、线程的创建与交互

进程的创建 STARTUPINFO si; //**成员DWORD dwFlags;表示结构体当中哪些成员有效.**STARTF_USESHOWWINDOW|STARTF_USEPOSITION PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); //LPTSTR pszCmdLine = TEXT("C:\\Windows\\S

python 线程(创建2种方式,守护进程,锁,死锁,递归锁,GIL锁,其他方式)

###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位    线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个进程中的资源共享,会涉及到安全问题,所以需要加锁解决 锁:牺牲了效率,保证了数据安全(重点) 死锁现象:出现在嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待(重点) 递归锁: 解决了死锁现象(重点) rlock 首先本身就是个互斥锁,维护了一个计数器,每次acquire+1,release

进程线程协程那些事儿

一.进程与线程 1.进程 我们电脑的应用程序,都是进程,假设我们用的电脑是单核的,cpu同时只能执行一个进程.当程序出于I/O阻塞的时候,CPU如果和程序一起等待,那就太浪费了,cpu会去执行其他的程序,此时就涉及到切换,切换前要保存上一个程序运行的状态,才能恢复,所以就需要有个东西来记录这个东西,就可以引出进程的概念了. 进程就是一个程序在一个数据集上的一次动态执行过程.进程由程序,数据集,进程控制块三部分组成.程序用来描述进程哪些功能以及如何完成:数据集是程序执行过程中所使用的资源:进程控制

进程线程----转自林海峰

进程与线程 一 背景知识 进程是对正在运行程序的一个抽象,进程的概念起源于操作系统,是操作系统最核心的概念,操作系统的其他所有内容都是围绕进程的概念展开的.所以想要真正了解进程,必须事先了解操作系统,点击进入 进程是操作系统提供的最古老也是最重要的抽象概念之一.即使可以利用的cpu只有一个(早期的计算机确实如此),也能保证支持(伪)并发的能力.将一个单独的cpu变成多个虚拟的cpu(多道技术:时间多路复用和空间多路复用+硬件上支持隔离),没有进程的抽象,现代计算机将不复存在. 本文将将着重介绍进

[linux]进程(四)——进程的创建

11,进程的创建 linux的进程创建可以分为两个步骤,分别为fork()和exec()函数,fork()负责创建一个子进程,和父进程的差别仅仅是PID PPID以及一些统计量,exec()函数负责读取可执行文件载入地址空间运行. fork()函数原型 pid_t fork(void); 子进程返回0,父进程返回子进程的PID,fork()函数一次创建两次返回. fork()函数的实现fork()采用了写时拷贝(copy-on-write)的技术,刚创建子进程的时候父进程和子进程拥有相同的地址空

001-多线程基础-进程线程、线程状态、优先级、用户线程和守护线程

一.进程与线程 1.DOS系统[单进程系统] 最早的时候DOS有一个特点:只要电脑有病毒,那么电脑就死机了. 原因:传统的DOS系统属于单进程系统,即:在同一时间段内只允许有一个程序运行. 2.Windows系统[多进程多线程] 电脑中毒也可以运行,但是会变慢 原因:因为在一个cpu.一块资源的情况下,程序利用一些轮转算法,可以让一个资源在一个时间段可以同时处理多个程序(进程),但是在一个时间点上只允许一个进程去执行. windows:任务管理器 linux:ps 在每一个进程上可以划分出若干个