一、核心代码
一共三部分:
- #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 回调,需要为链接器增加参数:这一点需要着重注意。
2.2 PsSetCreateProcessNotifyRoutineEx 注册回调
函数原型:- 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 内核不透明结构
[2] PsSetCreateProcessNotifyRoutineEx 函数 (ntddk.h)
[3] PCREATE_PROCESS_NOTIFY_ROUTINE_EX回调函数 (ntddk.h)
[4] PS_CREATE_NOTIFY_INFO 结构 (ntddk.h)
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |