post: windows-process-driver
All checks were successful
Build and Upload / Explore-Gitea-Actions (push) Successful in 2m2s
All checks were successful
Build and Upload / Explore-Gitea-Actions (push) Successful in 2m2s
This commit is contained in:
parent
2b43d949a1
commit
965f382cc5
184
content/post/windows-process-driver/index.md
Normal file
184
content/post/windows-process-driver/index.md
Normal file
@ -0,0 +1,184 @@
|
||||
---
|
||||
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)
|
BIN
content/post/windows-process-driver/process.png
Normal file
BIN
content/post/windows-process-driver/process.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 768 KiB |
Loading…
x
Reference in New Issue
Block a user