searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

WFP应用编程实践初探

2024-05-20 01:22:26
68
0

总体概述

上篇文章在简介windows驱动开发时以及到的WFP可应用层编程,从而完成防火墙功能。本文从WFP应用编程流程和API介绍开始,最后给出具体简单编码样例,带入WFP的应用编码大门。

WFP和应用API

Windows Filtering Platform (WFP) 是一个网络流量处理平台,旨在取代Windows XP 和Windows Server 2003 网络流量过滤接口。 WFP 由一组网络堆栈挂钩和一个协调网络堆栈交互的过滤引擎组成。WFP提供了应用层API和驱动层API。
编码主要流程为:
1.建一个WFP会话句柄(会话设置FWPM_SESSION_FLAG_DYNAMIC保障变量生命结束销毁注册的条件)
HANDLE engineHandle = NULL;
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
FwpmEngineOpen(NULL,RPC_C_AUTHN_WINNT,NULL,&session,&engineHandle);
2.开始事务(可选,默认会隐性开启)
FwpmTransactionBegin(engineHandle, 0);
3.设置过滤条件和注册
FWPM_FILTER_CONDITION condition;
condition.fieldKey = FWPM_CONDITION_IP_PROTOCOL;
condition.matchType = FWP_MATCH_EQUAL;
condition.conditionValue.type = FWP_UINT8;
condition.conditionValue.uint8 = IPPROTO_ICMP;
filter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;
filter.action.type = FWP_ACTION_BLOCK;
filter.filterCondition = &condition;
filter.numFilterConditions = 1;
filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY;
FwpmFilterAdd(engineHandle, &filter, NULL, NULL);
4.提交事务(可选,默认会隐性开启)
FwpmTransactionCommit(engineHandle);
以上完成便可生产一条防火墙规则:限制外部ping本机。不过由于是动态会话,session变量一旦销毁,对应规则就失效。可以不设置FWPM_SESSION_FLAG_DYNAMIC,但是需要手动删除规则或重启系统才导致规则失效。

完整代码示例

#include <windows.h>
#include <fwpmu.h>
#include <stdio.h>

#pragma comment(lib, "fwpuclnt.lib")
#pragma comment(lib,"ws2_32.lib")

#define CHECK_ERROR(result, msg)  \
if (result != ERROR_SUCCESS) {  \
    wchar_t error_str[256];  \
    error_str[0] = L'\0';  \
    DWORD errCode = GetLastError();   \
    ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errCode, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), error_str, sizeof(error_str) / sizeof(wchar_t), NULL);   \
    printf("%s failed with error: (%u)(%ls)\n", msg, result, error_str);  \
    goto cleanup;   \
}

int addWfpFilter()
{
DWORD ret = -1;
DWORD result;
HANDLE engineHandle = NULL;
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
FWPM_FILTER filter = { 0 };
FWPM_FILTER_CONDITION condition;
const wchar_t* constName = L"Block ICMP from specific IP";
wchar_t* dstName = NULL;
const wchar_t* constDesc = L"Block ping requests from a specific IP address";
wchar_t* dstDesc = NULL;

result = FwpmEngineOpen(
    NULL,
    RPC_C_AUTHN_WINNT,
    NULL,
    &session,
    &engineHandle
);
CHECK_ERROR(result, "FwpmEngineOpen");

result = FwpmTransactionBegin(engineHandle, 0);
CHECK_ERROR(result, "FwpmTransactionBegin");

condition.fieldKey = FWPM_CONDITION_IP_PROTOCOL;
condition.matchType = FWP_MATCH_EQUAL;
condition.conditionValue.type = FWP_UINT8;
condition.conditionValue.uint8 = IPPROTO_ICMP;

filter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;

dstName = new wchar_t[wcslen(constName) + 1];
wcscpy_s(dstName, wcslen(constName) + 1, constName);
filter.displayData.name = dstName;

dstDesc = new wchar_t[wcslen(constDesc) + 1];
wcscpy_s(dstDesc, wcslen(constDesc) + 1, constDesc);
filter.displayData.description = dstDesc;
filter.action.type = FWP_ACTION_BLOCK;
filter.filterCondition = &condition;
filter.numFilterConditions = 1;
filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY;

result = FwpmFilterAdd(engineHandle, &filter, NULL, NULL);
CHECK_ERROR(result, "FwpmFilterAdd");

result = FwpmTransactionCommit(engineHandle);
CHECK_ERROR(result, "FwpmTransactionCommit");

printf("Filter added successfully.\n");
ret = 0;

printf("add WFP successfully...");
while (true)
{
    Sleep(1000);
}

cleanup:
if (engineHandle != NULL) {
    FwpmEngineClose(engineHandle);
}
    return ret;
}

int main()
{
    DWORD ret = addWfpFilter();
    if (ret)
    {
         printf("add WFP failed, exit.");
         return ret;
    }
     return 0;
}

参考文献

[1] 微软#About Windows Filtering Platform#
[2] 微软#windows/win32/api/fwpmtypes#
0条评论
0 / 1000
刘****成
15文章数
0粉丝数
刘****成
15 文章 | 0 粉丝
原创

WFP应用编程实践初探

2024-05-20 01:22:26
68
0

总体概述

上篇文章在简介windows驱动开发时以及到的WFP可应用层编程,从而完成防火墙功能。本文从WFP应用编程流程和API介绍开始,最后给出具体简单编码样例,带入WFP的应用编码大门。

WFP和应用API

Windows Filtering Platform (WFP) 是一个网络流量处理平台,旨在取代Windows XP 和Windows Server 2003 网络流量过滤接口。 WFP 由一组网络堆栈挂钩和一个协调网络堆栈交互的过滤引擎组成。WFP提供了应用层API和驱动层API。
编码主要流程为:
1.建一个WFP会话句柄(会话设置FWPM_SESSION_FLAG_DYNAMIC保障变量生命结束销毁注册的条件)
HANDLE engineHandle = NULL;
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
FwpmEngineOpen(NULL,RPC_C_AUTHN_WINNT,NULL,&session,&engineHandle);
2.开始事务(可选,默认会隐性开启)
FwpmTransactionBegin(engineHandle, 0);
3.设置过滤条件和注册
FWPM_FILTER_CONDITION condition;
condition.fieldKey = FWPM_CONDITION_IP_PROTOCOL;
condition.matchType = FWP_MATCH_EQUAL;
condition.conditionValue.type = FWP_UINT8;
condition.conditionValue.uint8 = IPPROTO_ICMP;
filter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;
filter.action.type = FWP_ACTION_BLOCK;
filter.filterCondition = &condition;
filter.numFilterConditions = 1;
filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY;
FwpmFilterAdd(engineHandle, &filter, NULL, NULL);
4.提交事务(可选,默认会隐性开启)
FwpmTransactionCommit(engineHandle);
以上完成便可生产一条防火墙规则:限制外部ping本机。不过由于是动态会话,session变量一旦销毁,对应规则就失效。可以不设置FWPM_SESSION_FLAG_DYNAMIC,但是需要手动删除规则或重启系统才导致规则失效。

完整代码示例

#include <windows.h>
#include <fwpmu.h>
#include <stdio.h>

#pragma comment(lib, "fwpuclnt.lib")
#pragma comment(lib,"ws2_32.lib")

#define CHECK_ERROR(result, msg)  \
if (result != ERROR_SUCCESS) {  \
    wchar_t error_str[256];  \
    error_str[0] = L'\0';  \
    DWORD errCode = GetLastError();   \
    ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errCode, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), error_str, sizeof(error_str) / sizeof(wchar_t), NULL);   \
    printf("%s failed with error: (%u)(%ls)\n", msg, result, error_str);  \
    goto cleanup;   \
}

int addWfpFilter()
{
DWORD ret = -1;
DWORD result;
HANDLE engineHandle = NULL;
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
FWPM_FILTER filter = { 0 };
FWPM_FILTER_CONDITION condition;
const wchar_t* constName = L"Block ICMP from specific IP";
wchar_t* dstName = NULL;
const wchar_t* constDesc = L"Block ping requests from a specific IP address";
wchar_t* dstDesc = NULL;

result = FwpmEngineOpen(
    NULL,
    RPC_C_AUTHN_WINNT,
    NULL,
    &session,
    &engineHandle
);
CHECK_ERROR(result, "FwpmEngineOpen");

result = FwpmTransactionBegin(engineHandle, 0);
CHECK_ERROR(result, "FwpmTransactionBegin");

condition.fieldKey = FWPM_CONDITION_IP_PROTOCOL;
condition.matchType = FWP_MATCH_EQUAL;
condition.conditionValue.type = FWP_UINT8;
condition.conditionValue.uint8 = IPPROTO_ICMP;

filter.layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4;

dstName = new wchar_t[wcslen(constName) + 1];
wcscpy_s(dstName, wcslen(constName) + 1, constName);
filter.displayData.name = dstName;

dstDesc = new wchar_t[wcslen(constDesc) + 1];
wcscpy_s(dstDesc, wcslen(constDesc) + 1, constDesc);
filter.displayData.description = dstDesc;
filter.action.type = FWP_ACTION_BLOCK;
filter.filterCondition = &condition;
filter.numFilterConditions = 1;
filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY;

result = FwpmFilterAdd(engineHandle, &filter, NULL, NULL);
CHECK_ERROR(result, "FwpmFilterAdd");

result = FwpmTransactionCommit(engineHandle);
CHECK_ERROR(result, "FwpmTransactionCommit");

printf("Filter added successfully.\n");
ret = 0;

printf("add WFP successfully...");
while (true)
{
    Sleep(1000);
}

cleanup:
if (engineHandle != NULL) {
    FwpmEngineClose(engineHandle);
}
    return ret;
}

int main()
{
    DWORD ret = addWfpFilter();
    if (ret)
    {
         printf("add WFP failed, exit.");
         return ret;
    }
     return 0;
}

参考文献

[1] 微软#About Windows Filtering Platform#
[2] 微软#windows/win32/api/fwpmtypes#
文章来自个人专栏
信息安全
15 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
0