moonlightwatch 965f382cc5
All checks were successful
Build and Upload / Explore-Gitea-Actions (push) Successful in 2m2s
post: windows-process-driver
2025-04-01 14:42:31 +08:00

184 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Windows内核驱动-进程创建回调
description: 如何创建一个进程创建回调项目
date: 2025-04-01
slug: windows-process-driver
image: process.png
keywords:
- 驱动
- driver
- windows
- process
- 进程
- 回调
categories:
- Windows
tags:
- driver
- windows
---
# 一、核心代码
一共三部分:
1. 定义回调函数
2. 注册回调
3. 移除回调
```cpp
#include <ntddk.h>
// 定义回调函数,在后续实现
VOID ProcessNotifyRoutine(
_Inout_ PEPROCESS Process, // 进程对象,这是个不透明结构,不建议强行使用其中的字段
_In_ HANDLE ProcessId, // 进程ID
_In_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo // 进程创建信息
);
// 定义卸载函数,在后续实现
NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT DriverObject);
// 在DriverEntry中注册回调
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
UNREFERENCED_PARAMETER(RegistryPath); // 未使用的参数需要UNREFERENCED_PARAMETER处理不然会warning
NTSTATUS status;
// 注册卸载函数
DriverObject->DriverUnload = DriverUnload;
// 注册进程回调第二个参数表示是否移除true表示移除false表示注册
status = PsSetCreateProcessNotifyRoutineEx(ProcessNotifyRoutine, FALSE);
return STATUS_SUCCESS;
}
// 在卸载函数中移除回调
NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
NTSTATUS status;
// 移除回调第二个参数表示是否移除true表示移除false表示注册
status = PsSetCreateProcessNotifyRoutineEx(ProcessNotifyRoutine, TRUE);
return status;
}
// 进程回调实现
VOID ProcessNotifyRoutine(
_Inout_ PEPROCESS Process, // 进程对象,这是个不透明结构,不建议强行使用其中的字段
_In_ HANDLE ProcessId, // 进程ID
_In_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo // 进程创建信息
)
{
UNREFERENCED_PARAMETER(Process);
UNREFERENCED_PARAMETER(ProcessId);
UNREFERENCED_PARAMETER(CreateInfo);
// 这里可以记录进程的创建和销毁
if (CreateInfo != NULL)
{
// 进程创建
// 如果需要阻止进程创建,则可以
// 设置 CreateInfo 中的 CreationStatus 字段为 STATUS_ACCESS_DENIED
// CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
}
else
{
// 进程销毁
}
}
```
# 二、关键操作
## 2.1 链接器设置
上述代码编译后,无法正确触发 `ProcessNotifyRoutine` 回调,需要为链接器增加参数:
```
/INTEGRITYCHECK
```
这一点需要着重注意。
## 2.2 PsSetCreateProcessNotifyRoutineEx 注册回调
函数原型:
```cpp
NTSTATUS
PsSetCreateProcessNotifyRoutineEx (
_In_ PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,
_In_ BOOLEAN Remove
);
```
参数解释:
第一个参数:回调函数,当进程创建或者销毁时会调用此函数,类型为 `PCREATE_PROCESS_NOTIFY_ROUTINE_EX`
第二个参数是否移除true表示移除false表示注册
其中`PCREATE_PROCESS_NOTIFY_ROUTINE_EX` 定义为:
```
typedef
VOID
(*PCREATE_PROCESS_NOTIFY_ROUTINE_EX) (
_Inout_ PEPROCESS Process,
_In_ HANDLE ProcessId,
_Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo
);
```
`PEPROCESS` 是内核态进程对象,`HANDLE` 是进程ID`PPS_CREATE_NOTIFY_INFO` 是进程创建信息如果为NULL表示进程销毁否则表示进程创建。
## 2.3 获取进程信息
如上的 `PCREATE_PROCESS_NOTIFY_ROUTINE_EX` 定义,我们可以通过回调函数的 `CreateInfo` 参数获取进程相关信息。
`PPS_CREATE_NOTIFY_INFO` 定义如下:
```
typedef struct _PS_CREATE_NOTIFY_INFO {
_In_ SIZE_T Size;
union {
_In_ ULONG Flags;
struct {
_In_ ULONG FileOpenNameAvailable : 1;
_In_ ULONG Reserved : 31;
};
};
_In_ HANDLE ParentProcessId;
_In_ CLIENT_ID CreatingThreadId;
_Inout_ struct _FILE_OBJECT *FileObject;
_In_ PCUNICODE_STRING ImageFileName;
_In_opt_ PCUNICODE_STRING CommandLine;
_Inout_ NTSTATUS CreationStatus;
} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;
```
可以直接获得:
- `ParentProcessId`父进程ID
- `CreatingThreadId`创建进程的线程ID
- `FileObject`:文件对象,可以获得文件路径
- `ImageFileName`:进程映像文件名,也就是可执行文件路径
- `CommandLine`进程启动命令行如果为NULL表示没有命令行否则为命令行字符串
## 2.4 阻止进程创建
`PPS_CREATE_NOTIFY_INFO` 中有一个 `CreationStatus` 字段,如果设置为 `STATUS_ACCESS_DENIED`,则表示阻止进程创建。
# 三、参考资料
[1] [Windows 内核不透明结构](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/kernel/eprocess#eprocess)
[2] [PsSetCreateProcessNotifyRoutineEx 函数 (ntddk.h)](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/ntddk/nf-ntddk-pssetcreateprocessnotifyroutineex)
[3] [PCREATE_PROCESS_NOTIFY_ROUTINE_EX回调函数 (ntddk.h)](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/ntddk/nc-ntddk-pcreate_process_notify_routine_ex)
[4] [PS_CREATE_NOTIFY_INFO 结构 (ntddk.h)](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_ps_create_notify_info)