Windows 过滤平台:DISPATCH_LEVEL 处的 ClassifyFn 蓝屏
Windows Filtering Platform: ClassifyFn BSOD at DISPATCH_LEVEL
我正在尝试实现一个简单的防火墙来过滤 Windows 进程建立的网络连接。
防火墙应该 allow/block 连接。
为了拦截任何进程的连接,我创建了一个使用 Windows Filtering Platform.
的内核驱动程序
我在过滤层注册了一个ClassifyFn (FWPS_CALLOUT_CLASSIFY_FN1)回调FWPM_LAYER_ALE_AUTH_CONNECT_V4:
FWPM_CALLOUT m_callout = { 0 };
m_callout.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
...
status = FwpmCalloutAdd(filter_engine_handle, &m_callout, NULL, NULL);
有关连接的决定 allow/block 应由用户级别做出。
我使用 FltSendMessage 与 Userlevel 通信,
不能用于 IRQL DISPATCH_LEVEL.
按照 Microsoft 文档中关于如何 process callouts asynchronously 的说明,
我确实在调用 FltSendMessage 之前调用了 FwpsPendOperation0。
调用 FltSendMessage 后,我通过调用 FwpsCompleteOperation0 恢复数据包处理。
FwpsPendOperation0 文档指出调用此函数应该可以在 PASSIVE_LEVEL:
操作调用
A callout can pend the current processing operation on a packet when
the callout must perform processing on one of these layers that may
take a long interval to complete or that should occur at IRQL =
PASSIVE_LEVEL if the current IRQL > PASSIVE_LEVEL.
但是,当在 DISPATCH_LEVEL 调用 ClassifyFn 回调时,有时我仍然会在 FltSendMessage (INVALID_PROCESS_ATTACH_ATTEMPT).
我不明白怎么了。
提前感谢您给我指明正确方向的任何建议。
这里是ClassifyFn回调的相关代码:
/*************************
ClassifyFn Function
**************************/
void example_classify(
const FWPS_INCOMING_VALUES * inFixedValues,
const FWPS_INCOMING_METADATA_VALUES * inMetaValues,
void * layerData,
const void * classifyContext,
const FWPS_FILTER * filter,
UINT64 flowContext,
FWPS_CLASSIFY_OUT * classifyOut)
{
NTSTATUS status;
BOOLEAN bIsReauthorize = FALSE;
BOOLEAN SafeToOpen = TRUE; // Value returned by userlevel which signals to allow/deny packet
classifyOut->actionType = FWP_ACTION_PERMIT;
remote_address = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
remote_port = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
bIsReauthorize = IsAleReauthorize(inFixedValues);
if (!bIsReauthorize)
{
// First time receiving packet (not a reauthorized packet)
// Communicate with userlevel asynchronously
HANDLE hCompletion;
status = FwpsPendOperation0(inMetaValues->completionHandle, &hCompletion);
//
// FltSendMessage call here
// ERROR HERE:
// INVALID_PROCESS_ATTACH_ATTEMP BSOD on FltMessage call when at IRQL DISPATCH_LEVEL
//
FwpsCompleteOperation0(hCompletion, NULL);
}
if (!SafeToOpen) {
// Packet blocked
classifyOut->actionType = FWP_ACTION_BLOCK;
}
else {
// Packet allowed
}
return;
}
您需要在 PASSIVE_LEVEL 的另一个线程 运行 上调用 FltSendMessage()。您可以使用 IoQueueWorkItem() 或实现您自己的机制来在通过 PsCreateSystemThread() 创建的系统工作线程上处理它。
我正在尝试实现一个简单的防火墙来过滤 Windows 进程建立的网络连接。
防火墙应该 allow/block 连接。
为了拦截任何进程的连接,我创建了一个使用 Windows Filtering Platform.
的内核驱动程序我在过滤层注册了一个ClassifyFn (FWPS_CALLOUT_CLASSIFY_FN1)回调FWPM_LAYER_ALE_AUTH_CONNECT_V4:
FWPM_CALLOUT m_callout = { 0 };
m_callout.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
...
status = FwpmCalloutAdd(filter_engine_handle, &m_callout, NULL, NULL);
有关连接的决定 allow/block 应由用户级别做出。
我使用 FltSendMessage 与 Userlevel 通信, 不能用于 IRQL DISPATCH_LEVEL.
按照 Microsoft 文档中关于如何 process callouts asynchronously 的说明, 我确实在调用 FltSendMessage 之前调用了 FwpsPendOperation0。
调用 FltSendMessage 后,我通过调用 FwpsCompleteOperation0 恢复数据包处理。
FwpsPendOperation0 文档指出调用此函数应该可以在 PASSIVE_LEVEL:
操作调用A callout can pend the current processing operation on a packet when the callout must perform processing on one of these layers that may take a long interval to complete or that should occur at IRQL = PASSIVE_LEVEL if the current IRQL > PASSIVE_LEVEL.
但是,当在 DISPATCH_LEVEL 调用 ClassifyFn 回调时,有时我仍然会在 FltSendMessage (INVALID_PROCESS_ATTACH_ATTEMPT).
我不明白怎么了。
提前感谢您给我指明正确方向的任何建议。
这里是ClassifyFn回调的相关代码:
/*************************
ClassifyFn Function
**************************/
void example_classify(
const FWPS_INCOMING_VALUES * inFixedValues,
const FWPS_INCOMING_METADATA_VALUES * inMetaValues,
void * layerData,
const void * classifyContext,
const FWPS_FILTER * filter,
UINT64 flowContext,
FWPS_CLASSIFY_OUT * classifyOut)
{
NTSTATUS status;
BOOLEAN bIsReauthorize = FALSE;
BOOLEAN SafeToOpen = TRUE; // Value returned by userlevel which signals to allow/deny packet
classifyOut->actionType = FWP_ACTION_PERMIT;
remote_address = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
remote_port = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
bIsReauthorize = IsAleReauthorize(inFixedValues);
if (!bIsReauthorize)
{
// First time receiving packet (not a reauthorized packet)
// Communicate with userlevel asynchronously
HANDLE hCompletion;
status = FwpsPendOperation0(inMetaValues->completionHandle, &hCompletion);
//
// FltSendMessage call here
// ERROR HERE:
// INVALID_PROCESS_ATTACH_ATTEMP BSOD on FltMessage call when at IRQL DISPATCH_LEVEL
//
FwpsCompleteOperation0(hCompletion, NULL);
}
if (!SafeToOpen) {
// Packet blocked
classifyOut->actionType = FWP_ACTION_BLOCK;
}
else {
// Packet allowed
}
return;
}
您需要在 PASSIVE_LEVEL 的另一个线程 运行 上调用 FltSendMessage()。您可以使用 IoQueueWorkItem() 或实现您自己的机制来在通过 PsCreateSystemThread() 创建的系统工作线程上处理它。