简介
WFP框架整体代码比较死板,直接使用其封装好的API调用,此项目代码整体框架源于WFP网络过滤驱动——限制网站访问,利用WFP框架和IRP通信框架由应用层发送指定的目标IP到驱动层进行封禁访问,也可以对端口、源IP等进行封禁,其中对其代码框架做了初步修改,修改内容如下:
修改内容
增加了封禁和解除封禁目标网站功能,应用层代码从MFC窗口程序转换为普通C项目程序
代码
驱动层Rule.h
#pragma once
#define WFP_TAG 'wfpT'
#pragma pack(push)
#pragma pack(1)
typedef struct _tagWfp_NetInfo
{
USHORT m_uSrcPort; //源端口
USHORT m_uRemotePort; //目标端口
ULONG m_ulSrcIPAddr; //源地址
ULONG m_ulRemoteIPAddr; //目标地址
ULONG m_ulNetWorkType; //协议
USHORT m_uDirection;//数据包的方向,0表示发送,1表示接收
BOOLEAN m_Open;//开启过滤
} ST_WFP_NETINFO, *PST_WFP_NETINFO;
typedef struct _tagWfp_NetInfoList
{
LIST_ENTRY m_linkPointer;
ST_WFP_NETINFO m_stWfpNetInfo;
}ST_WFP_NETINFOLIST,*PST_WFP_NETINFOLIST;
#pragma pack(pop)
BOOLEAN InitRuleInfo();
BOOLEAN UninitRuleInfo();
BOOLEAN AddNetRuleInfo(PVOID pRuleInfo,ULONG uLen);
BOOLEAN IsHitRule(ULONG uRemotePort);
驱动层WfpSample.h
#pragma once
#define FILTER_MAJOR_NDIS_VERSION 6
#if defined(NDIS60)
#define FILTER_MINOR_NDIS_VERSION 0
#elseif defined(NDIS620)
#define FILTER_MINOR_NDIS_VERSION 20
#elseif defined(NDIS630)
#define FILTER_MINOR_NDIS_VERSION 30
#endif
#ifndef MAX_PATH
#define MAX_PATH (260)
#endif
#define WFP_DEVICE_NAME L"\\Device\\wfp_sample_device"
#define WFP_SYM_LINK_NAME L"\\DosDevices\\wfp_sample_device"
#define WFP_SAMPLE_ESTABLISHED_CALLOUT_DISPLAY_NAME L"WfpSampleEstablishedCalloutName"
#define WFP_SAMPLE_SUB_LAYER_DISPLAY_NAME L"WfpSampleSubLayerName"
#define WFP_SAMPLE_FILTER_ESTABLISH_DISPLAY_NAME L"WfpSampleFilterEstablishName"
#define HTTP_DEFAULT_PORT 55485
#define HTTP_DEFAULT_PORT2 60210
#define IOCTL_WFP_SAMPLE_ADD_RULE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
// {D969FC67-6FB2-4504-91CE-A97C3C32AD36}
DEFINE_GUID(WFP_SAMPLE_ESTABLITSHE_CALLOUT_V4_GUID, 0xd969fc67, 0x6fb2, 0x4504, 0x91, 0xce, 0xa9, 0x7c, 0x3c, 0x32, 0xad, 0x36);
// {ED6A516A-36D1-4881-BCF0-ACEB4C04C21C}
DEFINE_GUID(WFP_SAMPLE_SUBLAYER_GUID,
0xed6a516a, 0x36d1, 0x4881, 0xbc, 0xf0, 0xac, 0xeb, 0x4c, 0x4, 0xc2, 0x1c);
/*函数原型声明*/
void DriverUnload(__in struct _DRIVER_OBJECT *DriverObject);
PDEVICE_OBJECT CreateDevice( __in struct _DRIVER_OBJECT* DriverObject );
NTSTATUS WfpSampleIRPDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS WfpRegisterCalloutImple(
IN OUT void* deviceObject,
IN FWPS_CALLOUT_CLASSIFY_FN ClassifyFunction,
IN FWPS_CALLOUT_NOTIFY_FN NotifyFunction,
IN FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN FlowDeleteFunction,
IN const GUID* calloutKey,
IN UINT32 flags,
OUT UINT32* calloutId
);
NTSTATUS WfpRegisterCallouts( IN OUT void* deviceObject );
VOID NTAPI Wfp_Sample_Established_ClassifyFn_V4(
IN const FWPS_INCOMING_VALUES0 *inFixedValues,
IN const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
IN OUT VOID *layerData,
IN OPTIONAL const void *classifyContext,
IN const FWPS_FILTER1 *filter,
IN UINT64 flowContext,
OUT FWPS_CLASSIFY_OUT0 *classifyOut
);
NTSTATUS NTAPI Wfp_Sample_Established_NotifyFn_V4( IN FWPS_CALLOUT_NOTIFY_TYPE notifyType, IN const GUID* filterKey, IN const FWPS_FILTER* filter);
VOID NTAPI Wfp_Sample_Established_FlowDeleteFn_V4( IN UINT16 layerId, IN UINT32 calloutId, IN UINT64 flowContext );
NTSTATUS WfpAddCallouts();
NTSTATUS WfpRegisterCallouts(IN OUT void* deviceObject);
NTSTATUS WfpAddSubLayer();
NTSTATUS WfpAddFilters();
VOID WfpUnRegisterCallouts();
VOID WfpRemoveCallouts();
VOID WfpRemoveSubLayer();
VOID WfpRemoveFilters();
HANDLE OpenEngine();
void CloseEngine();
NTSTATUS InitWfp();
VOID UninitWfp();
VOID DeleteDevice();
驱动层Rule.c
#include "fltkernel.h"
#include "Rule.h"
LIST_ENTRY g_WfpRuleList = {0};
KSPIN_LOCK g_RuleLock = 0;
BOOLEAN InitRuleInfo()
{
InitializeListHead(&g_WfpRuleList);
KeInitializeSpinLock(&g_RuleLock);
return TRUE;
}
BOOLEAN UninitRuleInfo()
{
do
{
KIRQL OldIRQL = 0;
PLIST_ENTRY pInfo = NULL;
PST_WFP_NETINFOLIST pRule = NULL;
if( g_WfpRuleList.Blink == NULL ||
g_WfpRuleList.Flink == NULL )
{
break;
}
KeAcquireSpinLock(&g_RuleLock,&OldIRQL);
while( !IsListEmpty(&g_WfpRuleList) )
{
pInfo = RemoveHeadList(&g_WfpRuleList);
if( pInfo == NULL )
{
break;
}
pRule = CONTAINING_RECORD(pInfo,ST_WFP_NETINFOLIST,m_linkPointer);
ExFreePoolWithTag(pRule,WFP_TAG);
pRule = NULL;
pInfo = NULL;
}
KeReleaseSpinLock(&g_RuleLock,OldIRQL);
}
while (FALSE);
return TRUE;
}
BOOLEAN AddNetRuleInfo(PVOID pBuf,ULONG uLen)
{
BOOLEAN bSucc = FALSE;
PST_WFP_NETINFO pRuleInfo = NULL;
do
{
PST_WFP_NETINFOLIST pRuleNode = NULL;
KIRQL OldIRQL = 0;
pRuleInfo = (PST_WFP_NETINFO)pBuf;
if( pRuleInfo == NULL )
{
break;
}
if( uLen < sizeof(ST_WFP_NETINFO) )
{
break;
}
//代表准备决定是否插入的链表
pRuleNode = (PST_WFP_NETINFOLIST)ExAllocatePoolWithTag(NonPagedPool,sizeof(ST_WFP_NETINFOLIST),WFP_TAG);
if( pRuleNode == NULL )
{
break;
}
memset(pRuleNode,0,sizeof(ST_WFP_NETINFOLIST));
pRuleNode->m_stWfpNetInfo.m_uSrcPort = pRuleInfo->m_uSrcPort;
pRuleNode->m_stWfpNetInfo.m_uRemotePort = pRuleInfo->m_uRemotePort;
pRuleNode->m_stWfpNetInfo.m_ulSrcIPAddr = pRuleInfo->m_ulSrcIPAddr;
pRuleNode->m_stWfpNetInfo.m_ulRemoteIPAddr = pRuleInfo->m_ulRemoteIPAddr;
pRuleNode->m_stWfpNetInfo.m_ulNetWorkType = pRuleInfo->m_ulNetWorkType;
pRuleNode->m_stWfpNetInfo.m_uDirection = pRuleInfo->m_uDirection;
pRuleNode->m_stWfpNetInfo.m_Open = pRuleInfo->m_Open;
KeAcquireSpinLock(&g_RuleLock,&OldIRQL);
BOOLEAN exit = FALSE;
//searchValueInList(&g_WfpRuleList,)
do
{
if (g_WfpRuleList.Blink == NULL ||
g_WfpRuleList.Flink == NULL)
{
DbgPrint("q");
break;
}
PLIST_ENTRY pEntry = NULL;
pEntry = g_WfpRuleList.Flink;
while (pEntry != &g_WfpRuleList)
{
//pInfo代表当前存在的链表
PST_WFP_NETINFOLIST pInfo = CONTAINING_RECORD(pEntry, ST_WFP_NETINFOLIST, m_linkPointer);
//判断链表是否存在,存在就进入里面
if (pRuleNode->m_stWfpNetInfo.m_ulRemoteIPAddr == pInfo->m_stWfpNetInfo.m_ulRemoteIPAddr)
{
pInfo->m_stWfpNetInfo.m_Open = pRuleNode->m_stWfpNetInfo.m_Open;
exit = TRUE;
break;
}
pEntry = pEntry->Flink;
}
} while (FALSE);
if (exit == FALSE)
{
InsertHeadList(&g_WfpRuleList, &pRuleNode->m_linkPointer);
}
exit = FALSE;
KeReleaseSpinLock(&g_RuleLock,OldIRQL);
bSucc = TRUE;
break;
}
while (FALSE);
return bSucc;
}
BOOLEAN IsHitRule(ULONG ulRemoteIPAddress)
{
BOOLEAN bIsHit = FALSE;
do
{
KIRQL OldIRQL = 0;
PLIST_ENTRY pEntry = NULL;
if( g_WfpRuleList.Blink == NULL ||
g_WfpRuleList.Flink == NULL )
{
DbgPrint("q");
break;
}
KeAcquireSpinLock(&g_RuleLock,&OldIRQL);
pEntry = g_WfpRuleList.Flink;
while( pEntry != &g_WfpRuleList )
{
PST_WFP_NETINFOLIST pInfo = CONTAINING_RECORD(pEntry,ST_WFP_NETINFOLIST,m_linkPointer);
if ((ulRemoteIPAddress == pInfo->m_stWfpNetInfo.m_ulRemoteIPAddr) && pInfo->m_stWfpNetInfo.m_Open == TRUE)
{
bIsHit = TRUE;
break;
}
pEntry = pEntry->Flink;
}
KeReleaseSpinLock(&g_RuleLock,OldIRQL);
}
while (FALSE);
return bIsHit;
}
驱动层WfpSample.c
#define NDIS620
#include<ntifs.h>
#include <fwpmk.h>
#include<fwpmk.h>
#include <fwpsk.h>
#define INITGUID
#include <guiddef.h>
#include "WfpSample.h"
//#include "Fwpmu.h"
#include "Rule.h"
#include<fwpmu.h>
/*
本例子只是为了介绍WFP的用法,在实际应用中,如果只是根据简单的规则拦截数据包的话,
可以通过添加过滤器的方法实现。
*/
PDEVICE_OBJECT g_pDeviceObj = NULL;
UINT32 g_uFwpsEstablishedCallOutId = 0;
UINT32 g_uFwpmEstablishedCallOutId = 0;
UINT64 g_uEstablishedFilterId = 0;
HANDLE g_hEngine = NULL;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT* DriverObject, __in PUNICODE_STRING RegistryPath )
{
NTSTATUS nStatus = STATUS_UNSUCCESSFUL;
UNREFERENCED_PARAMETER(RegistryPath);
do
{
if( DriverObject == NULL )
{
break;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = WfpSampleIRPDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = WfpSampleIRPDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WfpSampleIRPDispatch;
if( FALSE == InitRuleInfo() )
{
break;
}
g_pDeviceObj = CreateDevice(DriverObject);
if( g_pDeviceObj == NULL )
{
break;
}
if( InitWfp() != STATUS_SUCCESS )
{
break;
}
DriverObject->DriverUnload = DriverUnload;
nStatus = STATUS_SUCCESS;
}
while (FALSE);
if( nStatus != STATUS_SUCCESS )
{
UninitWfp();
DeleteDevice();
UninitRuleInfo();
}
return nStatus;
}
NTSTATUS WfpSampleIRPDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS nStatus = STATUS_SUCCESS;
ULONG ulInformation = 0;
UNREFERENCED_PARAMETER(DeviceObject);
do
{
PIO_STACK_LOCATION IrpStack = NULL;
PVOID pSystemBuffer = NULL;
ULONG uInLen = 0;
if( Irp == NULL )
{
break;
}
pSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
IrpStack = IoGetCurrentIrpStackLocation( Irp );
if( IrpStack == NULL )
{
break;
}
uInLen = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
if( IrpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL )
{
break;
}
// 开始处理DeivceIoControl的情况
switch( IrpStack->Parameters.DeviceIoControl.IoControlCode )
{
case IOCTL_WFP_SAMPLE_ADD_RULE:
{
BOOLEAN bSucc = FALSE;
bSucc = AddNetRuleInfo( pSystemBuffer ,uInLen );
if( bSucc == FALSE )
{
nStatus = STATUS_UNSUCCESSFUL;
}
break;
}
default:
{
ulInformation = 0;
nStatus = STATUS_UNSUCCESSFUL;
}
}
}
while (FALSE);
if( Irp != NULL )
{
Irp->IoStatus.Information = ulInformation;
Irp->IoStatus.Status = nStatus;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return nStatus;
}
PDEVICE_OBJECT CreateDevice( __in struct _DRIVER_OBJECT* DriverObject )
{
UNICODE_STRING uDeviceName = {0};
UNICODE_STRING uSymbolName = {0};
PDEVICE_OBJECT pDeviceObj = NULL;
NTSTATUS nStatsus = STATUS_UNSUCCESSFUL;
RtlInitUnicodeString(&uDeviceName,WFP_DEVICE_NAME);
RtlInitUnicodeString(&uSymbolName,WFP_SYM_LINK_NAME);
nStatsus = IoCreateDevice(DriverObject,0,&uDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObj);
if( pDeviceObj != NULL )
{
pDeviceObj->Flags |= DO_BUFFERED_IO;
}
IoCreateSymbolicLink(&uSymbolName,&uDeviceName);
return pDeviceObj;
}
VOID DeleteDevice()
{
UNICODE_STRING uSymbolName = {0};
RtlInitUnicodeString(&uSymbolName,WFP_SYM_LINK_NAME);
IoDeleteSymbolicLink(&uSymbolName);
if( g_pDeviceObj != NULL )
{
IoDeleteDevice(g_pDeviceObj);
}
g_pDeviceObj = NULL;
}
NTSTATUS InitWfp()
{
NTSTATUS nStatus = STATUS_UNSUCCESSFUL;
do
{
g_hEngine = OpenEngine();
if( g_hEngine == NULL )
{
break;
}
//注册呼出接口
if (STATUS_SUCCESS != WfpRegisterCallouts(g_pDeviceObj) )
{
break;
}
//添加呼出接口
if( STATUS_SUCCESS != WfpAddCallouts() )
{
break;
}
//添加子层
if( STATUS_SUCCESS != WfpAddSubLayer() )
{
break;
}
//添加过滤引擎
if( STATUS_SUCCESS != WfpAddFilters() )
{
break;
}
nStatus = STATUS_SUCCESS;
}
while (FALSE);
return nStatus;
}
VOID UninitWfp()
{
WfpRemoveFilters();
WfpRemoveSubLayer();
WfpRemoveCallouts();
WfpUnRegisterCallouts();
CloseEngine();
}
void DriverUnload(__in struct _DRIVER_OBJECT *DriverObject)
{
UninitWfp();
DeleteDevice();
UninitRuleInfo();
return;
}
HANDLE OpenEngine()
{
FWPM_SESSION0 Session = {0};
HANDLE hEngine = NULL;
FwpmEngineOpen(NULL,RPC_C_AUTHN_WINNT,NULL,&Session,&hEngine);
return hEngine;
}
void CloseEngine()
{
if( g_hEngine != NULL )
{
FwpmEngineClose(g_hEngine);
}
g_hEngine = NULL;
}
NTSTATUS WfpRegisterCalloutImple(
IN OUT void* deviceObject,
IN FWPS_CALLOUT_CLASSIFY_FN ClassifyFunction,
IN FWPS_CALLOUT_NOTIFY_FN NotifyFunction,
IN FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN FlowDeleteFunction,
IN const GUID* calloutKey,
IN UINT32 flags,
OUT UINT32* calloutId
)
{
FWPS_CALLOUT sCallout;
NTSTATUS status = STATUS_SUCCESS;
memset(&sCallout, 0, sizeof(FWPS_CALLOUT));
sCallout.calloutKey = *calloutKey;
sCallout.flags = flags;
sCallout.classifyFn = ClassifyFunction;
sCallout.notifyFn = NotifyFunction;
sCallout.flowDeleteFn = FlowDeleteFunction;
status = FwpsCalloutRegister(deviceObject, &sCallout, calloutId);
return status;
}
NTSTATUS WfpRegisterCallouts(IN OUT void* deviceObject)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
do
{
if( deviceObject == NULL )
{
break;
}
//注册呼出接口
status = WfpRegisterCalloutImple(deviceObject,
Wfp_Sample_Established_ClassifyFn_V4,
Wfp_Sample_Established_NotifyFn_V4,
Wfp_Sample_Established_FlowDeleteFn_V4,
&WFP_SAMPLE_ESTABLITSHE_CALLOUT_V4_GUID,
0,
&g_uFwpsEstablishedCallOutId);
if( status != STATUS_SUCCESS )
{
break;
}
status = STATUS_SUCCESS;
}
while (FALSE);
return status;
}
VOID WfpUnRegisterCallouts()
{
FwpsCalloutUnregisterById(g_uFwpsEstablishedCallOutId);
g_uFwpsEstablishedCallOutId = 0;
}
NTSTATUS WfpAddCallouts()
{
NTSTATUS status = STATUS_SUCCESS;
FWPM_CALLOUT fwpmCallout = {0};
fwpmCallout.flags = 0;
do
{
if( g_hEngine == NULL )
{
break;
}
fwpmCallout.displayData.name = (wchar_t * )WFP_SAMPLE_ESTABLISHED_CALLOUT_DISPLAY_NAME;
fwpmCallout.displayData.description = (wchar_t * )WFP_SAMPLE_ESTABLISHED_CALLOUT_DISPLAY_NAME;
fwpmCallout.calloutKey = WFP_SAMPLE_ESTABLITSHE_CALLOUT_V4_GUID;
fwpmCallout.applicableLayer = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4;
status = FwpmCalloutAdd(g_hEngine, &fwpmCallout, NULL, &g_uFwpmEstablishedCallOutId);
if( !NT_SUCCESS(status) && (status != STATUS_FWP_ALREADY_EXISTS) )
{
break;
}
status = STATUS_SUCCESS;
}
while (FALSE);
return status;
}
VOID WfpRemoveCallouts()
{
if( g_hEngine != NULL )
{
FwpmCalloutDeleteById(g_hEngine,g_uFwpmEstablishedCallOutId);
g_uFwpmEstablishedCallOutId = 0;
}
}
NTSTATUS WfpAddSubLayer()
{
NTSTATUS nStatus = STATUS_UNSUCCESSFUL;
FWPM_SUBLAYER SubLayer = {0};
SubLayer.flags = 0;
SubLayer.displayData.description = WFP_SAMPLE_SUB_LAYER_DISPLAY_NAME;
SubLayer.displayData.name = WFP_SAMPLE_SUB_LAYER_DISPLAY_NAME;
SubLayer.subLayerKey = WFP_SAMPLE_SUBLAYER_GUID;
SubLayer.weight = 65535;
if( g_hEngine != NULL )
{
nStatus = FwpmSubLayerAdd(g_hEngine,&SubLayer,NULL);
}
return nStatus;
}
VOID WfpRemoveSubLayer()
{
if( g_hEngine != NULL )
{
FwpmSubLayerDeleteByKey(g_hEngine,&WFP_SAMPLE_SUBLAYER_GUID);
}
}
NTSTATUS WfpAddFilters()
{
NTSTATUS nStatus = STATUS_UNSUCCESSFUL;
do
{
FWPM_FILTER0 Filter = {0};
FWPM_FILTER_CONDITION FilterCondition[1] = {0};
FWP_V4_ADDR_AND_MASK AddrAndMask = {0};
if( g_hEngine == NULL )
{
break;
}
Filter.displayData.description = WFP_SAMPLE_FILTER_ESTABLISH_DISPLAY_NAME;
Filter.displayData.name = WFP_SAMPLE_FILTER_ESTABLISH_DISPLAY_NAME;
Filter.flags = 0;
Filter.layerKey = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4;
Filter.subLayerKey = WFP_SAMPLE_SUBLAYER_GUID;
Filter.weight.type = FWP_EMPTY;
Filter.numFilterConditions = 1;
Filter.filterCondition = FilterCondition;
Filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
Filter.action.calloutKey = WFP_SAMPLE_ESTABLITSHE_CALLOUT_V4_GUID;
FilterCondition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS;
FilterCondition[0].matchType = FWP_MATCH_EQUAL;
FilterCondition[0].conditionValue.type = FWP_V4_ADDR_MASK;//要检测的类型
FilterCondition[0].conditionValue.v4AddrMask = &AddrAndMask;//要检测的值
nStatus = FwpmFilterAdd(g_hEngine,&Filter,NULL,&g_uEstablishedFilterId);
if( STATUS_SUCCESS != nStatus )
{
break;
}
nStatus = STATUS_SUCCESS;
}
while (FALSE);
return nStatus;
}
VOID WfpRemoveFilters()
{
if( g_hEngine != NULL )
{
FwpmFilterDeleteById(g_hEngine,g_uEstablishedFilterId);
}
}
VOID NTAPI Wfp_Sample_Established_ClassifyFn_V4(
IN const FWPS_INCOMING_VALUES0* inFixedValues,
IN const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
IN OUT VOID* layerData,
IN OPTIONAL const void* classifyContext,
IN const FWPS_FILTER1* filter,
IN UINT64 flowContext,
OUT FWPS_CLASSIFY_OUT0* classifyOut
)
{
WORD wDirection = 0;
WORD wRemotePort = 0;
WORD wSrcPort = 0;
WORD wProtocol = 0;
ULONG ulSrcIPAddress = 0;
ULONG ulRemoteIPAddress = 0;
if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE))
{
return;
}
//wDirection表示数据包的方向,取值为 //FWP_DIRECTION_INBOUND/FWP_DIRECTION_OUTBOUND
wDirection = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION].value.int8;
//wSrcPort表示本地端口,主机序
wSrcPort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_PORT].value.uint16;
//wRemotePort表示远端端口,主机序
wRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT].value.uint16;
//ulSrcIPAddress 表示源IP
ulSrcIPAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS].value.uint32;
//ulRemoteIPAddress 表示远端IP
ulRemoteIPAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS].value.uint32;
DbgPrint("remote ip is %x\n", ulRemoteIPAddress);
//wProtocol表示网络协议,可以取值是IPPROTO_ICMP/IPPROTO_UDP/IPPROTO_TCP
wProtocol = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL].value.uint8;
//默认"允许"(PERMIT)
classifyOut->actionType = FWP_ACTION_PERMIT;
if (IsHitRule(ulRemoteIPAddress))
{
classifyOut->actionType = FWP_ACTION_BLOCK;
}
//清除FWPS_RIGHT_ACTION_WRITE标记
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
return ;
}
NTSTATUS NTAPI Wfp_Sample_Established_NotifyFn_V4(
IN FWPS_CALLOUT_NOTIFY_TYPE notifyType,
IN const GUID* filterKey,
IN const FWPS_FILTER* filter)
{
return STATUS_SUCCESS;
}
VOID NTAPI Wfp_Sample_Established_FlowDeleteFn_V4(
IN UINT16 layerId,
IN UINT32 calloutId,
IN UINT64 flowContext
)
{
}
应用层代码
#include<stdio.h>
#include<ws2tcpip.h>
#include<windows.h>
#pragma comment(lib,"ws2_32.lib")
typedef struct _tagWfp_NetInfo
{
USHORT m_uSrcPort; //源端口
USHORT m_uRemotePort; //目标端口
ULONG m_ulSrcIPAddr; //源地址
ULONG m_ulRemoteIPAddr; //目标地址
ULONG m_ulNetWorkType; //协议
USHORT m_uDirection;//数据包的方向,0表示发送,1表示接收
BOOLEAN m_Open;//开启过滤
} ST_WFP_NETINFO, * PST_WFP_NETINFO;
#define IOCTL_WFP_SAMPLE_ADD_RULE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_READ_ACCESS | FILE_WRITE_ACCESS)
int main()
{
// TODO: Add your control notification handler code here
//获取端口号
char** pptr;
char temp[100] = {0};
char str[INET_ADDRSTRLEN];
printf("请输入你要禁用的网站地址:");
scanf("%s", temp);
printf("\r\n");
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf_s("初始化网络库错误\n");
system("pause");
return -1;
}
hostent * host = gethostbyname(temp);
switch (host->h_addrtype) {
case AF_INET:
for (pptr = host->h_addr_list; *pptr != NULL; pptr++) {
printf("\taddress: %s\n",
inet_ntop(host->h_addrtype, *pptr, str, sizeof(str)));
}
break;
default:
printf("unknown address type\n");
break;
}
ULONG a[10] = { 0 };
int x = 0;
for (x;; x++)
{
ULONG c1 = inet_addr(inet_ntoa(*((in_addr*)host->h_addr_list[x])));
a[x] = htonl(c1);
if (host->h_addr_list[x] + host->h_length >= host->h_name)
{
break;
}
}
printf("解除禁用过滤请输入0,开启禁用过滤请输入1\r\n");
int open = 1;
scanf("%d", &open);
HANDLE hFile = CreateFile(L"\\\\.\\wfp_sample_device", GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf_s("打开文件wfp_sample_device失败\r\n");
system("pause");
return -1;
}
// 读者可以在此基础上增加其他域的过滤,如IP,协议类型、数据包方向等
// Info.m_uRemotePort = uPort;
for (x; x >= 0; x--)
{
ST_WFP_NETINFO Info = { 0 };
Info.m_ulRemoteIPAddr = a[x];
DWORD dwNeedSize = 0;
if (open == 0)
{
Info.m_Open = FALSE;
}
else
{
Info.m_Open = TRUE;
}
BOOL rValue = DeviceIoControl(hFile, IOCTL_WFP_SAMPLE_ADD_RULE, (LPVOID)&Info, sizeof(Info), NULL, 0, &dwNeedSize, NULL);
if (rValue == 0)
{
printf_s("failed in x:%d\r\n", x);
system("pause");
return -1;
}
else
{
char* str[] = { "解除禁用","禁用"};
printf_s("目标主机 %x %s成功\r\n", a[x], str[open]);
}
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
system("pause");
return 0;
}