diff --git a/content/post/windows-process-driver/index.md b/content/post/windows-process-driver/index.md new file mode 100644 index 0000000..1a85c2f --- /dev/null +++ b/content/post/windows-process-driver/index.md @@ -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 + +// 定义回调函数,在后续实现 +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) \ No newline at end of file diff --git a/content/post/windows-process-driver/process.png b/content/post/windows-process-driver/process.png new file mode 100644 index 0000000..7de63e3 Binary files /dev/null and b/content/post/windows-process-driver/process.png differ