应用层读取wfp防火墙阻断记录
前言
之前的文档中,描写了如何对WFP防火墙进行操作[链接在此],这篇文档中,描述如何获取WFP防火墙进行阻断的操作记录。
需要注意的坑点
- 使用FWPM_NET_EVENT_TYPE获取防火墙日志时,需要注意,只有丢弃和内核丢弃,以及几个错误信息是所有操作系统都可用,其它类型无法应用到所有操作系统。所以我们一般不会使用FWPM_NET_EVENT_TYPE来获取防火墙的放行日志。如果有需要读取放行日志的话,可以查询安全日志5156的方式进行(下次专门写文档来描述常用的三种读取方式)。
- 使用主动读取的方式,在极个别系统上可能存在少量内存泄露(在保障所有内存都按照MSDN的要求释放的基础上,24小时有几十K的级别,没有仔细进行过日志条数的量化。有明白的也请指教)
- 订阅的方式仅支持win7/2008 R2以上操作系统,建议使用loadlibrary动态加载,避免模块在vista或2008(SP2)操作系统上整体运行失败。
读取阻断日志(方案一:主动读取)
阻断日志即防火墙返回FWP_ACTION_BLOCK动作的记录信息,读取流程大体上分为:创建枚举句柄、执行枚举、释放枚举句柄简单的三步。
创建枚举句柄
DWORD FwpmNetEventCreateEnumHandle0( HANDLE engineHandle, const FWPM_NET_EVENT_ENUM_TEMPLATE0 *enumTemplate, HANDLE *enumHandle );
- 输入参数:
- engineHandle:防火墙句柄,前一章提到过,使用FwpmEngineOpen0打开
- enumTemplate:枚举的限制条件,常用的是枚举起止时间,也可以设置网络条件以供筛选。
- enumHandle:输出函数,用于输出枚举句柄
- 输出参数:
- 成功返回0,错误时返回WFP Error Codes
执行枚举操作
DWORD FwpmNetEventEnum0( HANDLE engineHandle, HANDLE enumHandle, UINT32 numEntriesRequested, FWPM_NET_EVENT0 ***entries, UINT32 *numEntriesReturned );
- 输入参数:
- engineHandle:防火墙句柄,FwpmEngineOpen0打开
- enumHandle:枚举句柄,由上一步创建
- numEnteiesRequested:本次想要枚举的最大数量,如果想要一次性返回所有,可以传-1(0xffffffff)
- entries:用于输出事件数组,需要使用FwpmFreeMemory0释放
- numEntriesReturned:用于输出事件数目,用于枚举entries
- 输出参数:
- 成功返回0,错误时返回WFP Error Codes
释放枚举句柄
DWORD FwpmNetEventDestroyEnumHandle0( HANDLE engineHandle, HANDLE enumHandle );
- 输入参数:
- 没啥好说的,两个句柄,参照上面
- 输出参数:
- 同上
相关函数1:启用防火墙事件采集
默认防火墙事件采集就是处于开启状态,因此不调用这个函数在大多数系统上可以正常进行事件读取。但是也发现过某些系统需要调用后才可以进行事件读取,建议还是增加此函数的调用
DWORD FwpmEngineSetOption0( HANDLE engineHandle, FWPM_ENGINE_OPTION option, const FWP_VALUE0 *newValue );
- 输入参数
- engineHandle:防火墙句柄,由FwpmEngineOpen0打开
- 需要设置的参数,这个地方可以设置的类型还是蛮多的,可以参考
- 设置参数对应的值,当option为FWPM_ENGINE_COLLECT_NET_EVENTS时,newValue为1则代表启用。
- 输出参数
- 成功返回ERROR_SUCCESS, 失败返回 WFP Error Codes
参考代码
void enumDemoCode()
{FWPM_SESSION0 session = { 0 };ZeroMemory(&session, sizeof(session));session.displayData.name = demoSession;session.txnWaitTimeoutInMSec = INFINITE;session.flags = FWPM_SESSION_FLAG_DYNAMIC;HANDLE hEngine = NULL;DWORD dwResult = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &session, &hEngine);if (dwResult != ERROR_SUCCESS || hEngine == NULL){std::cout << "FwpmEngineOpen0 Failed. ec:" << GetLastError() << std::endl;return;}FWP_VALUE0 inValue = {FWP_EMPTY};inValue.type = FWP_UINT32;inValue.uint32 = 1;FwpmEngineSetOption0(hEngine, FWPM_ENGINE_COLLECT_NET_EVENTS, &inValue);FWPM_NET_EVENT_ENUM_TEMPLATE0 enumTemplate = {0};SYSTEMTIME nowSystemTime;ZeroMemory(&nowSystemTime, sizeof(nowSystemTime));GetLocalTime(&nowSystemTime);FILETIME nowFileTime;ZeroMemory(&nowFileTime, sizeof(nowFileTime));if (SystemTimeToFileTime(&nowSystemTime, &nowFileTime)){enumTemplate.endTime.dwLowDateTime = nowFileTime.dwLowDateTime;enumTemplate.endTime.dwHighDateTime = nowFileTime.dwHighDateTime;}enumTemplate.startTime.dwHighDateTime = 0;enumTemplate.startTime.dwLowDateTime = 0;enumTemplate.numFilterConditions = 0;HANDLE hEnumHandle = NULL;dwResult = FwpmNetEventCreateEnumHandle0(hEngine, &enumTemplate, &hEnumHandle);if (dwResult != ERROR_SUCCESS || hEnumHandle == NULL){std::cout << "Create Enum Handle Failed, ec:" << GetLastError() << std::endl;FwpmEngineClose0(hEngine);hEngine = NULL;return;}FWPM_NET_EVENT0** netEvents = NULL;UINT32 uEventNumber = 0;dwResult = FwpmNetEventEnum0(hEngine, hEnumHandle, INFINITE, &netEvents, &uEventNumber);if (uEventNumber > 0){for (int eventPos = 0; eventPos < uEventNumber; eventPos++){FWPM_NET_EVENT0* sigEvent = netEvents[eventPos];if (sigEvent->type != FWPM_NET_EVENT_TYPE_CLASSIFY_DROP){continue;}if (sigEvent->header.ipVersion == FWP_IP_VERSION_V4){std::wstring wstrLocalIp = ip2str(sigEvent->header.localAddrV4);std::wstring wstrRemoteIp = ip2str(sigEvent->header.remoteAddrV4);std::wstring wstrProtocol;switch (sigEvent->header.ipProtocol){case 1:wstrProtocol = L"ICMP";break;case 6:wstrProtocol = L"TCP";break;case 17:wstrProtocol = L"UDP";break;default:wstrProtocol = L"Other:";wstrProtocol.append(std::to_wstring(sigEvent->header.ipProtocol));break;}std::wcout << wstrLocalIp << "[" << sigEvent->header.localPort << "] ==> " << wstrRemoteIp << "[" << sigEvent->header.remotePort << "] protocol:" << wstrProtocol << std::endl;}}}if (netEvents){FwpmFreeMemory0((void**)&netEvents);netEvents = NULL;}if (hEnumHandle){FwpmNetEventDestroyEnumHandle0(hEngine, hEnumHandle);hEnumHandle = NULL;}if (hEngine){FwpmEngineClose0(hEngine);hEngine = NULL;}return;
}
执行结果
读取阻断日志(方案二:事件订阅)
使用事件订阅的方式在防火墙中读取日志,只需要开启和取消事件订阅即可
启动事件订阅
DWORD FwpmNetEventSubscribe0( HANDLE engineHandle, const FWPM_NET_EVENT_SUBSCRIPTION0 *subscription,FWPM_NET_EVENT_CALLBACK0 callback, void *context, HANDLE *eventsHandle );
- 输入参数
- engineHandle:防火墙句柄,由FwpmEngineOpen0打开
- subscription:需要订阅的通知类型
- callback:订阅的回调
- context:自定义指针,原封不动传递导callback函数
- eventsHandle:订阅句柄,在FwpmNetEventUnsubscribe0中取消订阅
- 输出参数
- 成功返回ERROR_SUCCESS, 失败返回 WFP Error Codes
取消事件订阅
DWORD FwpmNetEventUnsubscribe0( HANDLE engineHandle, HANDLE eventsHandle );
- 输入参数
- engineHandle:防火墙句柄,由FwpmEngineOpen0打开
- eventsHandle:订阅句柄,由FwpmNetEventSubscribe0返回
- 输出参数
- 成功返回ERROR_SUCCESS, 失败返回 WFP Error Codes
回调函数定义
void CALLBACK FuncFwpmNetEventCallback0(PVOID FwContext, FWPM_NET_EVENT1* FwEvent)
- 输入参数
- FwContext:自定义指针,FwpmNetEventSubscribe0函数的context指针
- FwEvent:订阅的事件
- 输出参数
- 无
参考代码
void CALLBACK FuncFwpmNetEventCallback0(_Inout_ PVOID FwContext, _In_ const FWPM_NET_EVENT1* FwEvent)
{if (FwEvent == NULL){return;}if (FwEvent->header.ipVersion == FWP_IP_VERSION_V4){std::wstring wstrLocalIp = ip2str(FwEvent->header.localAddrV4);std::wstring wstrRemoteIp = ip2str(FwEvent->header.remoteAddrV4);std::wstring wstrProtocol;switch (FwEvent->header.ipProtocol){case 1:wstrProtocol = L"ICMP";break;case 6:wstrProtocol = L"TCP";break;case 17:wstrProtocol = L"UDP";break;default:wstrProtocol = L"Other:";wstrProtocol.append(std::to_wstring(FwEvent->header.ipProtocol));break;}std::wcout << wstrLocalIp << "[" << FwEvent->header.localPort << "] ==> " << wstrRemoteIp << "[" << FwEvent->header.remotePort << "] protocol:" << wstrProtocol << std::endl;}return;
}void subscribeEvents()
{FWPM_SESSION0 session = { 0 };ZeroMemory(&session, sizeof(session));session.displayData.name = demoSession;session.txnWaitTimeoutInMSec = INFINITE;session.flags = FWPM_SESSION_FLAG_DYNAMIC;HANDLE hEngine = NULL;DWORD dwResult = FwpmEngineOpen0(NULL, RPC_C_AUTHN_DEFAULT, NULL, &session, &hEngine);if (dwResult != ERROR_SUCCESS || hEngine == NULL){std::cout << "FwpmEngineOpen0 Failed. ec:" << GetLastError() << std::endl;return;}FWP_VALUE0 inValue = { FWP_EMPTY };inValue.type = FWP_UINT32;inValue.uint32 = 1;FwpmEngineSetOption0(hEngine, FWPM_ENGINE_COLLECT_NET_EVENTS, &inValue);HANDLE hSubScribeHandle = NULL;FWPM_NET_EVENT_ENUM_TEMPLATE0 eventTemplate = { 0 };eventTemplate.numFilterConditions = 0;FWPM_NET_EVENT_SUBSCRIPTION0 subscription = { 0 };subscription.enumTemplate = &eventTemplate;subscription.sessionKey = session.sessionKey;FwpmNetEventSubscribe0(hEngine, &subscription, FuncFwpmNetEventCallback0, NULL, &hSubScribeHandle);std::cout << "Event Subscribe Started....." << std::endl;getchar();FwpmNetEventUnsubscribe0(hEngine, hSubScribeHandle);if (hEngine){FwpmEngineClose0(hEngine);hEngine = NULL;}
}
运行效果
相关文章:
应用层读取wfp防火墙阻断记录
前言 之前的文档中,描写了如何对WFP防火墙进行操作[链接在此],这篇文档中,描述如何获取WFP防火墙进行阻断的操作记录。 需要注意的坑点 使用FWPM_NET_EVENT_TYPE获取防火墙日志时,需要注意,只有丢弃和内核丢弃&…...
web基础和tomcat的安装,部署jpress应用
目录 1. 简述静态网页和动态网页的区别。 2. 简述 Webl.0 和 Web2.0 的区别。 3. 安装tomcat8,配置服务启动脚本,部署jpress应用。 1. 简述静态网页和动态网页的区别。 【1】定义区别 请求响应信息,发给客户端进行处理,由浏览…...
idea git命令使用
这个标签标识单签分支:(标签图标) 标识关联分支:(五角星) 本地切换分支:如当前分支是dev ,git branch 显示的是dev ,然后通过 git checkout -b release 切换到release分支 git checkout re…...
软件测试技术之单元测试—工程师 Style 的测试方法
什么是单元测试? Wikipedia 对单元测试的定义: 在计算机编程中,单元测试(Unit Testing)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。 在实际…...
C#学习....
1.基础 //引用命名空间using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;//项目名或者命名空间 namespace _01_MY_First_Demo {//Program类class Program{//程序的主入口或者Main函数static void Main(S…...
C语言暑假刷题冲刺篇——day2
目录 一、选择题 二、编程题 🎈个人主页:库库的里昂 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏✨收录专栏:C语言每日一练 ✨其他专栏:代码小游戏C语言初阶🤝希望作者的文章能对你…...
springcloud3 hystrix实现服务降级的案例配置2
一 服务降级的说明 1.1 服务降级说明 "服务器忙,请稍后在试"不让客户达等待,立即返回一个友好的提示。 1.2 服务降级的触发情况 1.程序运行异常; 2.超时; 3.服务熔断触发服务降级;4 .线程池/信号量打…...
第 3 章 稀疏数组和队列(1)
3.1 稀疏 sparsearray 数组 3.1.1先看一个实际的需求 编写的五子棋程序中,有存盘退出和续上盘的功能。 分析问题: 因为该二维数组的很多值是默认值 0.因此记录了很多没有意义的数据.->稀疏数组 3.1.2基本介绍 当一个数组中大部分元素为 0,或者为同…...
7-10 奇偶分家
分数 10 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 给定N个正整数,请统计奇数和偶数各有多少个? 输入格式: 输入第一行给出一个正整N(≤1000);第2行给出N个非负整数,以空格分隔。 输…...
使用词向量以数学方式查找具有相似含义的单词
摄影:Nika Charakova 一、说明 简而言之,词向量只不过是表示自然语言词含义的一系列实数。这项技术是有用的NLP功能的重要推动力,使机器能够“理解”人类语言。本文讨论如何使用词向量以编程方式计算文本的语义相似性,例如&#x…...
opencv实现以图搜图
这里写目录标题 1. 步骤1.1 导入OpenCV库:1.2 加载图像1.3 提取特征1.4 匹配特征1.5 显示结果 2. 完整代码3. 测试图片及效果 1. 步骤 1.1 导入OpenCV库: 在您的C代码中,首先需要导入OpenCV库。您可以使用以下语句导入核心模块:…...
爬虫工作中代理失效了怎么处理?
Hey!亲爱的爬虫小伙伴们,是不是经常在爬虫的工作中遇到代理IP失效的问题?别着急,今天我来分享一些应对代理失效的妙招!这些方法简单易行,让你爬虫顺利进行. 一、为什么代理会失效? 在爬虫过程…...
使用虚拟环境conda安装不同版本的cuda,cudnn,pytorch
背景:在学习深度学习时,我们不可避免的需要跑多个神经网络,而不同的神经网络环境都不一样,所以必须要使用到虚拟环境(如conda)去做环境隔离,安装属于自己的环境。在这环境中,大多神经网络都必须要用到cuda&…...
【24择校指南】华东师范大学计算机考研考情分析
华东师范大学(B) 考研难度(☆☆☆☆) 内容:23考情概况(拟录取和复试分数人数统计)、院校概况、23考试科目、23复试详情、各科目及专业考情分析。 正文2563字,预计阅读:3分钟。 2023考情概况…...
什么是LAXCUS分布式操作系统?
相较Linux、Windows,Laxcus是同时在多台计算机上运行的操作系统,处理大规模、高并发、高性能业务,其特点是资源共享和任务并行,并实现【数存算管】超融合一体化。环境中的资源:CPU、GPU、内存、硬盘、网络,…...
Redis数据结构——链表list
链表是一种常用的数据结构,提供了顺序访问的方式,而且高效地增删操作。 Redis中广泛使用了链表,例如:列表的底层实现之一就是链表。 在Redis中,链表分为两部分:链表信息 链表节点。 链表节点用来表示链表…...
[自学记录06|*百人计划]Gamma矫正与线性工作流
一、前言 Gamma矫正其实也属于我前面落下的一块内容,打算把它补上,其它的没补是因为我之前写的GAMES101笔记里已经涵盖了,而Gamma矫正在101里面确实没提到,于是打算把它补上,这块内容并不难,但是想通透的理…...
【数据结构】二叉树链式结构的实现及其常见操作
目录 1.手搓二叉树 2.二叉树的遍历 2.1前序、中序以及后序遍历 2.2二叉树的层序遍历 3.二叉树的常见操作 3.1求二叉树节点数量 3.2求二叉树叶子节点数量 3.3求二叉树第k层节点个数 3.3求二叉树的深度 3.4二叉树查找值为x的节点 4.二叉树的销毁 1.手搓二叉树 在学习…...
从零实战SLAM-第九课(后端优化)
在七月算法报的班,老师讲的蛮好。好记性不如烂笔头,关键内容还是记录一下吧,课程入口,感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…...
Python Opencv实践 - 图像金字塔
import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape)#图像上采样 #cv.pyrUp(src, dstNone, dstsizeNone, borderTypeNone) #参考资料:https://blo…...
ubuntu秘钥生成PKCS1 格式秘钥
openssl genrsa -out key 2048 openssl rsa -in key -out key2 -traditional...
Pixel Aurora Engine真实案例:用‘蒸汽朋克猫武士’生成整套游戏美术资源
Pixel Aurora Engine真实案例:用蒸汽朋克猫武士生成整套游戏美术资源 1. 项目背景与工具介绍 Pixel Aurora Engine(像素极光引擎)是一款基于AI扩散模型的高端像素艺术生成工具。它采用复古的8-bit游戏机风格界面,却能产出专业级…...
RAG系统的需求分析
这个是一个基于私有知识库的智能对话平台,允许用户上传文档构建专属知识库,并通过自然语言交互的方式查询和获取知识。它结合了大语言模型和向量检索技术,让用户通过对话的形式与自己的知识库进行高效交互应用场景个人用户场景:学习助手&…...
2026 年提词器 App 的新方向:AI 改稿 + 语速匹配,正在重新定义“读稿“这件事
核心结论:2026 年提词器 App 已经从"滚字幕"进化到"懂你怎么说"。AI 语速匹配、智能跟读、违禁词检测正在成为新标配,而在综合体验上,拍摄提词器是目前把这些能力整合得最完整的一款产品。一、提词器 App 正在经历一次代…...
第一次降AIGC率不知道从哪入手?这份保姆级操作手册帮你
第一次操作的话,照着下面的步骤来,15分钟内搞定降AIGC率、降AI工具保姆级测评2026、降AI。 工具选嘎嘎降AI(www.aigcleaner.com),达标率99.26%,有退款保障,操作也不复杂。 准备工作 需要准备的…...
基于MCGS嵌入版7.7的全自动洗车机组态仿真程序编写与流程图详解
MCGS洗车程序 MCGS嵌入版7.7组态仿真程序 全自动洗车机,脚本程序编写 有完整的流程图"这洗车机PLC程序怎么又卡在喷淋环节了?"凌晨两点的工控车间里,我盯着MCGS嵌入版的仿真界面直挠头。全自动洗车机的脚本调试真是个磨人的小妖精&…...
3步解锁网易云音乐:ncmdumpGUI让你的NCM文件重获自由
3步解锁网易云音乐:ncmdumpGUI让你的NCM文件重获自由 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经遇到过这样的烦恼?在网…...
DevOps实践:如何让开发、测试、运维不再“打架”?
质量不再是孤岛在追求快速迭代的现代软件开发中,开发、测试与运维团队之间的隔阂与摩擦,常常被戏称为“部门战争”。开发团队渴望快速交付新功能,测试团队需要足够的时间来保障质量,而运维团队则首要追求系统的稳定与可靠。当发布…...
别再死磕英文手册了!手把手带你用Lisflood-FP跑通第一个洪水模拟案例(附T001_buscot实战)
从零到一:Lisflood-FP洪水模拟实战指南(T001_buscot案例详解) 刚接触水文模型的研究者常被英文手册劝退——密密麻麻的公式、晦涩的术语、复杂的参数配置让人望而生畏。其实,掌握Lisflood-FP的关键不在于死磕理论,而在…...
Stable Diffusion v1.5功能体验:Guidance Scale参数实测,教你调出最佳效果
Stable Diffusion v1.5功能体验:Guidance Scale参数实测,教你调出最佳效果 1. 引言:为什么Guidance Scale如此重要? 如果你用过Stable Diffusion生成图片,一定遇到过这样的情况:同样的提示词,…...

