获取WFP用户模式过滤器的通知方法技术咨询
Windows Filtering Platform (WFP) 用户模式过滤器事件通知实现
要在用户模式下获取WFP过滤器动作生效的通知(比如拦截连接的记录),可以通过以下几种直接的方式实现:
1. 注册用户模式回调函数
通过WFP的FwpmCallbackAdd0接口注册自定义回调,当过滤器触发动作时,回调会被调用并传递事件详情:
- 首先调用
FwpmEngineOpen0打开WFP引擎会话,确保使用管理员权限及合适的会话标志(如FWPM_SESSION_FLAG_DYNAMIC)。 - 注册回调时,指定回调类型为
FWPM_CALLBACK_TYPE_PACKET_INSPECTION,回调函数需遵循NTAPI调用约定。 - 在回调中通过
FWPM_CALLOUT_NOTIFY_TYPE判断事件类型,解析FWPM_PACKET_INSPECTION_INFORMATION0结构体获取连接的源IP、目标IP、端口、协议以及动作类型(允许/拦截)等信息。
代码片段示例
#include <fwpmu.h> #include <fwpsk.h> // 自定义回调函数 void NTAPI WfpFilterCallback( IN FWPM_CALLOUT_NOTIFY_TYPE notifyType, IN const GUID* filterId, IN const FWPM_CALLOUT0* callout, IN const FWPM_PACKET_INSPECTION_INFORMATION0* inspectionInfo, IN void* context ) { if (notifyType == FWPM_CALLOUT_NOTIFY_TYPE_CLASSIFY) { // 判断是否是拦截动作 if (inspectionInfo->actionType == FWP_ACTION_BLOCK) { // 解析连接信息(示例为IPv4场景) UINT32 srcIp = inspectionInfo->layerData.incomingValue->value.uint32; UINT32 dstIp = inspectionInfo->layerData.outgoingValue->value.uint32; UINT16 srcPort = inspectionInfo->layerData.incomingValue->value.uint16; UINT16 dstPort = inspectionInfo->layerData.outgoingValue->value.uint16; // 这里添加记录逻辑,比如写入日志或触发内部通知 } } } // 注册回调的流程 void RegisterWfpCallback(HANDLE engineHandle) { NTSTATUS status = FwpmCallbackAdd0( engineHandle, FWPM_CALLBACK_TYPE_PACKET_INSPECTION, WfpFilterCallback, NULL, // 自定义上下文参数 NULL // 安全描述符,可设为NULL使用默认权限 ); if (!NT_SUCCESS(status)) { // 处理注册失败逻辑 } }
2. 订阅WFP网络事件
通过FwpmNetEventSubscribe0订阅网络事件,结合过滤器的自定义标注(Annotation)来关联到你的过滤器:
- 添加过滤器时,通过
FWPM_FILTER0的annotation字段设置唯一标识(比如自定义字符串)。 - 调用
FwpmNetEventSubscribe0订阅事件,指定事件类型过滤条件(如只关注拦截事件)。 - 使用事件对象(如
CreateEvent创建的事件)等待通知,每次事件触发时调用FwpmNetEventEnum0获取事件详情,通过annotation字段匹配到你的过滤器,解析FWPM_NET_EVENT0获取连接信息。
3. 注意事项
- 所有WFP用户模式API调用需要管理员权限,否则会返回权限不足的错误。
- 使用完毕后需清理资源:调用
FwpmCallbackRemove0移除回调,FwpmNetEventUnsubscribe0取消订阅,FwpmEngineClose0关闭引擎会话。 - 对于高并发场景,回调函数内的逻辑要尽量轻量化,避免阻塞WFP处理流程。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

