0

我正在尝试实现一个简单的防火墙来过滤 Windows 进程建立的网络连接。

防火墙应该允许/阻止连接。

为了拦截任何进程的连接,我创建了一个使用Windows Filtering Platform的内核驱动程序。

我在过滤层 FWPM_LAYER_ALE_AUTH_CONNECT_V4注册了一个ClassifyFn (FWPS_CALLOUT_CLASSIFY_FN1)回调:

FWPM_CALLOUT m_callout = { 0 };
m_callout.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
...
status = FwpmCalloutAdd(filter_engine_handle, &m_callout, NULL, NULL);

关于连接允许/阻止的决定应由用户级别决定。

我使用FltSendMessage与 Userlevel 通信,它不能在 IRQL DISPATCH_LEVEL 中使用。

按照 Microsoft 文档中有关如何异步处理标注的说明,我确实在调用FltSendMessage之前调用了 FwpsPendOperation0。

在调用 FltSendMessage 之后,我通过调用FwpsCompleteOperation0来恢复数据包处理。

FwpsPendOperation0 文档指出调用此函数应该可以在 PASSIVE_LEVEL 操作调用:

当调出必须对这些层之一执行处理时,调出可以挂起数据包上的当前处理操作,这可能需要很长时间才能完成,或者如果当前 IRQL > PASSIVE_LEVEL 则应该在 IRQL = PASSIVE_LEVEL 处发生。

但是,当在 DISPATCH_LEVEL 调用 ClassifyFn 回调时,有时我仍然会在 FltSendMessage (INVALID_PROCESS_ATTACH_ATTEMPT) 上收到 BSOD

我不明白出了什么问题。

提前感谢您提供任何可以为我指明正确方向的建议。

下面是 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;
}
4

1 回答 1

1

您需要在另一个以 PASSIVE_LEVEL 运行的线程上调用 FltSendMessage()。您可以使用 IoQueueWorkItem() 或实现自己的机制来在通过 PsCreateSystemThread() 创建的系统工作线程上处理它。

于 2020-03-27T22:21:39.970 回答