我正在尝试实现一个简单的防火墙,用于过滤Windows进程建立的网络连接。
防火墙应允许/阻止连接。
为了拦截任何进程的连接,我创建了一个使用Windows筛选平台的内核驱动程序。
我在过滤层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中发生=如果当前IRQL>PASSIVE_LEVEL,则为PASSIVE_EVEL。
但是,当在DISPATCH_LEVEL调用ClassifFn回调时,我有时仍然会在FltSendMessage(INVALID_PROCESS_ATTACH_ATTEMPT(上获得BSOD。
我不明白怎么了。
提前感谢您的任何建议,这些建议可以为我指明正确的方向。
以下是ClassifFn回调的相关代码:
/*************************
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((创建的系统工作线程上处理它。