WFP防火墙在应用层的增删过滤器操作

WFP防火墙的作用

WFP防火墙是在Vista/Win2008之后的操作系统中才引入的一套流量管控平台。提供一套API接口供开发人员调用。应用层和驱动层都有不同的模块可以调用。用于取代之前的LSP过滤器、TDI过滤器、NDIS过滤器等。通过WFP API,可以实现防火墙、网络管控工具等流量管控服务。

使用WFP防火墙时注意的事项

  • WFP防火墙仅在Vista/Win 2008以后的系统中方可生效。
  • 在Vista/Win 2008中,过滤器的添加不支持"或"策略。如果需求中包含对个IP段、多个端口号、多个协议或多个进程同时存在时,在Vista/Win2008中,需要依次进行较为复杂的交叉匹配,依次添加。这一点需要注意。只有在Win7/Win2008 R2系统中,WFP防火墙才能直接添加策略运行。

基本概念以及决策逻辑

  • Layer(层):层是过滤器的容器,其功能是将过滤器组织成为集合,由层ID决定过滤器生效的位置。每一个层里面都包含一套内置的子层,用户可以添加自定义的子层。
  • SubLayer(子层):过滤器的容器,在对应的层中生效。
  • Filter(过滤器):过滤器是对出/入数据包进行匹配的规则。过滤器负责告诉过滤引擎如何处理数据包。添加过滤器时,使用FWPM_FILTER0结构体中的flags参数,可以指定过滤器的生效时间。

Layer(层)的过滤决策策略:

  1. 按照权重由高到低的顺序对每个子层进行决策匹配
  2. 即使有更高优先级的子层决定阻塞流量,下方的子层也会依次得到评估的机会。所以,每个子层都可以匹配到通过当前层的所有数据包
  3. 如果有一个子层明确返回阻断,当前层的决策即为阻断。(这里只谈应用层的决策策略,在Callout驱动层中,返回阻断,依然会被其它策略所修改,放在以后讨论。)

SubLayer(子层)的过滤决策策略:

  1. 按照权重从高到底的顺序对每个过滤器进行匹配
  2. 在匹配的过程中,如果有过滤器明确返回了"Permit"或"Block",则马上中断匹配,权重更低的过滤器不会收到数据包的信息。如果所有过滤器都返回"Continue",则会一直匹配到列表耗尽。
  3. 最后一个执行匹配的过滤器返回值,即为当前子层最终的过滤决策。

常用的随手便签

netsh wfp show state

该命令可以打印系统中当前存活的WFP防火墙层、子层、过滤器等。是在调试的过程中最实用的命令,也许没有之一。

调用流程

打开与关闭WFP防火墙

打开防火墙句柄

DWORD FwpmEngineOpen0( 
                    const wchar_t *serverName, 
                    UINT32 authnService, 
                    SEC_WINNT_AUTH_IDENTITY_W *authIdentity, 
                    const FWPM_SESSION0 *session, 
                    HANDLE *engineHandle 
                    );
  • 输入参数
    • serverName:必须为空。
    • authnService:身份验证方式,可选为RPC_C_AUTHN_WINNT和RPC_C_AUTHN_DEFAULT。
    • authIdentity:身份验证和授权凭证,可以为NULL。
    • session:会话指针,不使用的话可以为NULL。
    • engineHandle:用于输出防火墙引擎句柄,其它对防火墙操作的函数大都依赖此句柄。
  • 输出参数
    • ERROR_SUCCESS为成功,其它参考错误码

关闭防火墙句柄

DWORD FwpmEngineClose0( 
                        HANDLE engineHandle 
                        );
  • 输入参数
    • engineHandle:防火墙引擎句柄,由FwpmEngineOpen0参数返回
  • 输出参数
    • ERROR_SUCCESS为成功,其它参考错误码

枚举当前所有层

创建层枚举句柄

DWORD FwpmLayerCreateEnumHandle0( 
                HANDLE engineHandle, 
                const FWPM_LAYER_ENUM_TEMPLATE0 *enumTemplate,
                HANDLE *enumHandle 
        );
  • 输入参数
    • engineHandle:引擎句柄,由FwpmEngineOpen0创建。
    • enumTemplate:枚举参数,实际上内容保留使用,可以为NULL。
    • enumHandle:输出参数,用于传出枚举句柄
  • 输出参数
    • ERROR_SUCCESS为成功,其它参考错误码

执行枚举操作

DWORD FwpmLayerEnum0( 
                    HANDLE engineHandle, 
                    HANDLE enumHandle, 
                    UINT32 numEntriesRequested, 
                    FWPM_LAYER0 ***entries, 
                    UINT32 *numEntriesReturned 
        );
  • 输入参数
    • engineHandle:引擎句柄
    • enumHandle:枚举句柄,FwpmLayerCreateEnumHandle0创建
    • numEntriesRequested:请求的数目
    • entries:用于返回的层参数数组,需要FwpmFreeMemory0释放(这里需要注意,该参数定义为:FWPM_LAYER0** p=NULL,释放使用FwpmFreeMemory0((void**)&p))
    • numEntriesReturned:本次返回的结构体数目
  • 输出参数
    • ERROR_SUCCESS为成功

销毁层枚举句柄

DWORD FwpmLayerDestroyEnumHandle0( 
                        HANDLE engineHandle, 
                        HANDLE enumHandle 
            );
  • 输入参数
    • engineHandle:引擎句柄,由FwpmEngineOpen0创建
    • enumHandle:枚举句柄,由FwpmLayerCreateEnumHandle0创建
  • 输出参数
    • ERROR_SUCCESS为成功,其它参考错误码

参考代码

    #define SESSION_LAYER    L"session_layer";
    GUID SESSION_GUID = { 0x2ec66da9, 0x2ae4, 0x4f83, { 0x81, 0xc7, 0x34, 0x5d, 0x19, 
0x6a, 0xe3, 0xd7 } };

int main()
{
    HANDLE engineHandle = NULL;
    DWORD result = ERROR_SUCCESS;
    FWPM_SESSION0 fwpmSession;
    memset(&fwpmSession, 0, sizeof(FWPM_SESSION0));
    fwpmSession.flags = FWPM_SESSION_FLAG_DYNAMIC;

    result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &fwpmSession, 
&engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineOpen0 failed;Return value:%d.\n", __FUNCTION__, 
result);
        return 0;
    }

    HANDLE enumHandle = NULL;
    result = FwpmLayerCreateEnumHandle0(engineHandle, NULL, &enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmFilterCreateEnumHandle0, Return value:%d\n", __FUNCTION__, 
result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }
    
    UINT32 numEntriesReturned = 0;
    do
    {
        FWPM_LAYER0** fwpmLayerList = NULL;
        numEntriesReturned = 0;
        result = FwpmLayerEnum0(engineHandle, enumHandle, 1, &fwpmLayerList, 
&numEntriesReturned);
        if (result != ERROR_SUCCESS || numEntriesReturned == 0)
        {
            break;
        }

        std::string strLayerName = boost::locale::conv::from_utf(fwpmLayerList[0]->displayData.name, "GBK");
        printf("layer name:%s\n", strLayerName.c_str());
        FwpmFreeMemory0((void**)&fwpmLayerList);
    } while (numEntriesReturned > 0);
    
    result = FwpmLayerDestroyEnumHandle0(engineHandle, enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmFilterDestroyEnumHandle0, Return value:%d\n", __FUNCTION__, 
result);
    }

    result = FwpmEngineClose0(engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineClose0 failed; Return value:%d\n", __FUNCTION__, 
result);
        return 0;
    }
    printf("[%s]result Success\n", __FUNCTION__);
}

执行结果

在这里插入图片描述

枚举当前所有子层

创建子层枚举句柄

DWORD FwpmSubLayerCreateEnumHandle0( 
                                HANDLE engineHandle, 
                                const FWPM_SUBLAYER_ENUM_TEMPLATE0 *enumTemplate, 
                                HANDLE *enumHandle 
                );
  • 输入参数
    • engineHandle:防火墙引擎句柄,由FwpmEngineOpen0创建
    • enumTemplate:选择参数,可以为NULL
    • enumHandle:枚举句柄,用于输出
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

执行子层枚举

DWORD FwpmSubLayerEnum0( 
                        HANDLE engineHandle, 
                        HANDLE enumHandle, 
                        UINT32 numEntriesRequested, 
                        FWPM_SUBLAYER0 ***entries, 
                        UINT32 *numEntriesReturned 
                );
  • 输入参数
    • engineHandle:防火墙引擎,由FwpmEngineOpen0创建
    • enumHandle:枚举句柄,由FwpmSubLayerCreateEnumHandle0创建
    • numEntriesRequested:本次请求的个数
    • entries:用于输出子层参数,需要FwpmFreeMemory0手动释放
    • numEntriesReturned:本次返回的子层个数
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

销毁子层枚举句柄

DWORD FwpmSubLayerDestroyEnumHandle0( 
                            HANDLE engineHandle, 
                            HANDLE enumHandle 
                );
  • 输入参数
    • engineHandle:防火墙引擎句柄,由FwpmEngingOpen0创建
    • enumHandle:枚举句柄
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

参考代码

#define SESSION_LAYER    L"session_layer";
GUID SESSION_GUID = { 0x2ec66da9, 0x2ae4, 0x4f83, { 0x81, 0xc7, 0x34, 0x5d, 0x19, 
0x6a, 0xe3, 0xd7 } };

int main()
{
    std::cout << "Hello World!\n";
    
    HANDLE engineHandle = NULL;
    DWORD result = ERROR_SUCCESS;
    FWPM_SESSION0 fwpmSession;
    memset(&fwpmSession, 0, sizeof(FWPM_SESSION0));
    fwpmSession.flags = FWPM_SESSION_FLAG_DYNAMIC;
    
    result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &fwpmSession, 
&engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineOpen0 failed;Return value:%d.\n", __FUNCTION__, 
result);
        return 0;
    }

    HANDLE enumHandle = NULL;
    result = FwpmSubLayerCreateEnumHandle0(engineHandle, NULL, &enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmSubLayerCreateEnumHandle, Return value:%d\n", __FUNCTION__, 
result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }

    UINT32 numEntriesReturned = 0;
    do
    {
        FWPM_SUBLAYER0** fwpmSubLayerList = NULL;
        numEntriesReturned = 0;
        result = FwpmSubLayerEnum0(engineHandle, enumHandle, 1, &fwpmSubLayerList, 
&numEntriesReturned);
        if (result != ERROR_SUCCESS || numEntriesReturned == 0)
        {
            break;
        }

        std::string subLayerName = 
boost::locale::conv::from_utf(fwpmSubLayerList[0]->displayData.name, "GBK");
        printf("[%s]subLayer name:%s\n", __FUNCTION__, subLayerName.c_str());
        FwpmFreeMemory0((void**)&fwpmSubLayerList);
    } while (numEntriesReturned > 0);

    result = FwpmSubLayerDestroyEnumHandle0(engineHandle, enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmSubLayerDestroyEnumHandle, Return value:%d\n", 
__FUNCTION__, result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }

    result = FwpmEngineClose0(engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineClose0 failed; Return value:%d\n", __FUNCTION__, 
result);
        return 0;
    }
    printf("[%s]result Success\n", __FUNCTION__);
    return 0;
}

执行结果

在这里插入图片描述

枚举子层内所有过滤器

创建过滤器枚举器

DWORD FwpmFilterCreateEnumHandle0( 
                                HANDLE engineHandle, 
                                const FWPM_FILTER_ENUM_TEMPLATE0 *enumTemplate, 
                                HANDLE *enumHandle 
                    );
  • 输入参数
    • engineHandle:防火墙引擎句柄
    • enumTemplate:过滤参数,可以为NULL
    • enumHandle:枚举句柄,用于输出
  • 输出参数
    • ERROR_SUCCESS为成功

执行过滤器枚举

DWORD FwpmFilterEnum0( 
                                HANDLE engineHandle, 
                                HANDLE enumHandle, 
                                UINT32 numEntriesRequested, 
                                FWPM_FILTER0 ***entries, 
                                UINT32 *numEntriesReturned 
                    );
  • 输入参数
    • engineHandle:防火墙引擎句柄
    • enumHandle:过滤器枚举句柄,FwpmFilterCreateEnumHandle0创建
    • numEntriesRequested:本次请求过滤器个数
    • entries:用于输出的过滤器数组,需要调用FwpmFreeMemory0释放
    • numEntriesReturned:本次返回的过滤器个数
  • 输出参数
    • ERROR_SUCCESS为成功

销毁过滤器枚举器

DWORD FwpmFilterDestroyEnumHandle0( 
                                HANDLE engineHandle, 
                                HANDLE enumHandle 
                );
  • 输入参数
    • engineHandle:防火墙引擎句柄
    • enumHandle:过滤器枚举句柄,FwpmFilterCreateEnumHandle0创建
  • 输出参数
    • ERROR_SUCCESS为成功

参考代码

int main()
{
    std::cout << "Hello World!\n";

    HANDLE engineHandle = NULL;
    DWORD result = ERROR_SUCCESS;
    FWPM_SESSION0 fwpmSession;
    memset(&fwpmSession, 0, sizeof(FWPM_SESSION0));
    fwpmSession.flags = FWPM_SESSION_FLAG_DYNAMIC;

    result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &fwpmSession, 
&engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineOpen0 failed;Return value:%d.\n", __FUNCTION__, 
result);
        return 0;
    }

    HANDLE enumHandle = NULL;
    result = FwpmFilterCreateEnumHandle0(engineHandle, NULL, &enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmFilterCreateEnumHandle0, Return value:%d\n", __FUNCTION__, 
result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }

    UINT32 numEntriesReturned = 0;
    do
    {
        FWPM_FILTER0** fwpmFilterList = NULL;
        numEntriesReturned = 0;
        result = FwpmFilterEnum0(engineHandle, enumHandle, 1, &fwpmFilterList, 
&numEntriesReturned);
        if (result != ERROR_SUCCESS || numEntriesReturned == 0)
        {
            break;
        }
        std::string filterName = 
boost::locale::conv::from_utf(fwpmFilterList[0]->displayData.name, "GBK");
        printf("[%s]filter name:%s\t filter count:%d\n", __FUNCTION__, 
filterName.c_str(), fwpmFilterList[0]->numFilterConditions);
        FwpmFreeMemory0((void**)&fwpmFilterList);
    } while (numEntriesReturned > 0);

    result = FwpmFilterDestroyEnumHandle0(engineHandle, enumHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmFilterDestroyEnumHandle0, Return value:%d\n", __FUNCTION__, 
result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }

    result = FwpmEngineClose0(engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineClose0 failed; Return value:%d\n", __FUNCTION__, 
result);
        return 0;
    }
    printf("[%s]result Success\n", __FUNCTION__);
    return 0;
}

执行结果
在这里插入图片描述

添加和删除子层

添加子层

DWORD FwpmSubLayerAdd0( 
                                HANDLE engineHandle, 
                                const FWPM_SUBLAYER0 *subLayer,
                                PSECURITY_DESCRIPTOR sd 
                );
  • 输入参数
    • engineHandle:防火墙引擎句柄
    • subLayer:防火墙子层参数
    • sd:安全描述符,可以为空
  • 输出参数
    • ERROR_SUCCESS为成功

删除子层

DWORD FwpmSubLayerDeleteByKey0( 
                                            HANDLE engineHandle, 
                                            const GUID *key 
                        );
  • 输入参数
    • engineHandle:防火墙引擎
    • key:防火墙要删除的GUID
  • 输出参数
    * ERROR_SUCCESS为成功

参考代码

int main()
{
    std::cout << "Hello World!\n";

    HANDLE engineHandle = NULL;
    DWORD result = ERROR_SUCCESS;
    FWPM_SESSION0 fwpmSession;
    memset(&fwpmSession, 0, sizeof(FWPM_SESSION0));
    fwpmSession.flags = FWPM_SESSION_FLAG_DYNAMIC;

    result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &fwpmSession, 
&engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineOpen0 failed;Return value:%d.\n", __FUNCTION__, 
result);
        return 0;
    }

    FWPM_SUBLAYER0 insertSubLayer;
    memset(&insertSubLayer, 0, sizeof(FWPM_SUBLAYER0));
    insertSubLayer.subLayerKey = SUBLEYER_GUID;
    insertSubLayer.displayData.name = (wchar_t*)SUBLEYER_NAME;
    insertSubLayer.displayData.description = (wchar_t*)L"demo_sublayer_des";
    insertSubLayer.weight = 50;
    result = FwpmSubLayerAdd0(engineHandle, &insertSubLayer, NULL);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmSubLayerAdd0, Return value:%d\n", __FUNCTION__, result);
        FwpmEngineClose0(engineHandle);
        return 0;
    }
    printf("after 
add\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");

    enumSubLayer(engineHandle);

    FwpmSubLayerDeleteByKey0(engineHandle, (const GUID*)&SUBLEYER_GUID);
    printf("after 
del\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");

    enumSubLayer(engineHandle);
    result = FwpmEngineClose0(engineHandle);
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmEngineClose0 failed; Return value:%d\n", __FUNCTION__, 
result);
        return 0;
    }

    printf("[%s]result Success\n", __FUNCTION__);
    return 0;
}

执行效果
添加之后
在这里插入图片描述

添加过滤器

过滤条件结构体

typedef struct FWPM_FILTER_CONDITION0_ { 
                        GUID fieldKey; 
                        FWP_MATCH_TYPE matchType; 
                        FWP_CONDITION_VALUE0 conditionValue; 
            } FWPM_FILTER_CONDITION0;
  • fieldKey:过滤器检测位置的GUID,参数定义与fwpmu.h,举例有如下几个,可以根据这几个值到对应头文件查看

    GUID含义
    FWPM_CONDITION_ALE_APP_ID全路径校验
    FWPM_CONDITION_IP_LOCAL_PORT本地传输端口号
    FWPM_CONDITION_IP_REMOTE_PORT远程传输端口号
    FWPM_CONDITION_IP_LOCAL_ADDRESS本地IP地址
    FWPM_CONDITION_IP_REMOTE_ADDRESS远程IP地址
    FWPM_CONDITION_IP_PROTOCOL协议类型
  • matchType:过滤器校验方式,常用的如下,其余的可以查FWP_MATCH_TYPE结构体。

    TYPE操作类型
    FWP_MATCH_EQUAL相等
    FWP_MATCH_GREATER大于
    FWP_MATCH_LESS小于
    FWP_MATCH_GREATER_OR_EQUAL大于等于
    FWP_MATCH_LESS_OR_EQUAL小于等于
    FWP_MATCH_RANGE范围内
    FWP_MATCH_NOT_EQUAL不等于
  • conditionValue:过滤器校验参数

过滤器结构体

typedef struct FWPM_FILTER0_ { 
                        GUID filterKey; 
                        FWPM_DISPLAY_DATA0 displayData; 
                        UINT32 flags; 
                        GUID *providerKey; 
                        FWP_BYTE_BLOB providerData; 
                        GUID layerKey; 
                        GUID subLayerKey; 
                        FWP_VALUE0 weight; 
                        UINT32 numFilterConditions; 
                        FWPM_FILTER_CONDITION0 *filterCondition; 
                        FWPM_ACTION0 action; 
                        union { 
                            UINT64 rawContext; 
                            GUID providerContextKey; 
                        }; 
                        GUID *reserved; 
                        UINT64 filterId; 
                        FWP_VALUE0 effectiveWeight; 
            } FWPM_FILTER0;

部分参数如下

  • filterKey:过滤器生效的位置GUID,如FWPM_LAYER_ALE_AUTH_CONNECT_V4,可以查看:Filter Layer Identifiers
  • layerKey:层GUID
  • subLayerKey:子层GUID
  • weight:过滤器权重
  • numFilterConditions:本次过滤器的数目
  • filterCondition:过滤器数组
  • action:过滤方式,FWP_ACTION_BLOCK:阻断,FWP_ACTION_PERMIT:放行。

开始防火墙操作事务

DWORD FwpmTransactionBegin0( 
                            HANDLE engineHandle, 
                            UINT32 flags 
                );
  • 输入参数
    • engineHandle:过滤器句柄
    • flags:读写标识。0为读写,FWPM_TXN_READ_ONLY为只读
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

添加过滤器

DWORD FwpmFilterAdd0( 
                            HANDLE engineHandle, 
                            const FWPM_FILTER0 *filter, 
                            PSECURITY_DESCRIPTOR sd, 
                            UINT64 *id 
                );
  • 输入参数
    • engineHandle:过滤器句柄
    • filter:过滤器参数结构体
    • sd:安全句柄,可为空。
    • id:输出参数,用于输出过滤器ID
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

提交防火墙操作事务

DWORD FwpmTransactionCommit0( 
                                    HANDLE engineHandle 
                        );
  • 输入参数
    • engineHandle:过滤器句柄
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

取消防火墙操作事务

DWORD FwpmTransactionAbort0( 
                                    HANDLE engineHandle 
                        );
  • 输入参数
    • engineHandle:过滤器句柄
  • 输出参数
    • ERROR_SUCCESS为成功,其它为错误码

参考代码

    const wchar_t* application_path = L"C:\\Program Files\\Internet 
Explorer\\iexplore.exe";

    FWP_BYTE_BLOB* fwpApplicationBlob;
    result = FwpmGetAppIdFromFileName0(application_path, &fwpApplicationBlob);  //  fwpApplicationBlob需要FwpmFreeMemory释放
    if (result != ERROR_SUCCESS)
    {
        printf("[%s]FwpmGetAppIdFromFileName0, Return value:%d\n", __FUNCTION__, 
result);
        FwpmEngineClose(engineHandle);
        return 0;
    }

    FWPM_FILTER0    fwpmFilter;
    FWPM_FILTER_CONDITION0 fwpmConditions[4] = {0};
    int conCount = 0;
    fwpmConditions[conCount].fieldKey = FWPM_CONDITION_ALE_APP_ID;
    fwpmConditions[conCount].matchType = FWP_MATCH_EQUAL;
    fwpmConditions[conCount].conditionValue.type = FWP_BYTE_BLOB_TYPE;
    fwpmConditions[conCount].conditionValue.byteBlob = fwpApplicationBlob;
    conCount++;

    memset(&fwpmFilter, 0, sizeof(FWPM_FILTER0));
    fwpmFilter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
    fwpmFilter.subLayerKey = SUBLEYER_GUID;
    fwpmFilter.numFilterConditions = conCount;
    fwpmFilter.filterCondition = fwpmConditions;
    fwpmFilter.action.type = FWP_ACTION_BLOCK;
    fwpmFilter.weight.type = FWP_UINT64;

    UINT64 u64Weight = 80;
    fwpmFilter.weight.uint64 = &u64Weight;

    fwpmFilter.displayData.name = (wchar_t*)L"demo_filter";
    fwpmFilter.displayData.description = (wchar_t*)L"demo_filter";

    result = FwpmTransactionBegin0(engineHandle, 0);

    result = FwpmFilterAdd0(engineHandle, &fwpmFilter, NULL, 
&(fwpmFilter.filterId));

    result = FwpmTransactionCommit0(engineHandle);

    enumFilter(engineHandle);

    FwpmFreeMemory0((void**)&fwpApplicationBlob);   //  释放

执行结果

在这里插入图片描述


版权声明:本文为QQ1113130712原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。