首页
社区
课程
招聘
[原创]WFP网络流量监控系统
发表于: 2016-8-10 21:32 43206

[原创]WFP网络流量监控系统

2016-8-10 21:32
43206

摘 要:WFP是随VISTA OS之后出现的一种新型防火墙编写技术,以简单稳定为基础,使用起来方便快速,是微软推出的新型网络过滤平台。WFP的框架庞大繁琐,较之以前的技术有着很大的改进,是微软呕心沥血的新过滤框架。WFP的通用性强,既可以基于R0,又可以基于R3进行开发。在R3,WFP有着类似于R0的函数,同时也能做到基于R0的大部分功能。
本设计正是基于WFP的R0层编写设计而成,它采用了新型的WFP底层技术以及使用绚丽方便的DuiLib来设置界面,界面的设置模仿QQ电脑管家而成。程序实现了对总体的网络流量的监控,对单个进程的上传下载速度的监控,以及进程的网络占用程度的监控等等。
关键字:WFP,流量监控,Duilib,QQ电脑管家,进程监控
1. 绪论        4
1.1课题背景        4
1.2 WFP简介        4
1.2.1  垫片        5
1.2.2 callout        6
1.2.3 分层        6
1.2.4 子层        6
1.3 相关技术        6
1.3.1 DuiLib核心结构        7
1.3.2 DuiLib消息流程        7
1.3.3 DuiLib流程        8
1.3.4 DuiLib的XML描述        9
1.3.5 WFP流程        9
2 概要设计        9
2.1 设计思路        9
2.2  主要功能        9
2.3 软件情况        10
2.4 流程图        10
3 程序详细说明        11
3.1 界面设计        11
3.1.1 进程数统计        11
3.1.2 进程的上传下载速度统计        11
3.13 进程的创建与销毁        12
3.2 驱动WFP的设计        12
3.2.1 进程处理        12
3.2.3 数据流量的处理        12
3.3 驱动与应用层数据交互        12
4.总结        14
结束语        15
参考资料:        16
1.绪论
1.1课题背景
随着计算机行业的快速发展,技术日新月异。新技术的出现,旧技术的淘汰,已成为社会快速发展的定律。于是,在这种定律下,WFP应运而生。对于网络防火墙,以往的技术不能同时实现对单个进程的网络流量的监控,需要借用两种或两种以上的技术来实现,同时对于VISATA已经以后的OS,经过改版,已不再支持曾经的防火墙设计技术,从而以前的技术已慢慢的被取代,于是WFP应运而生。
1.2 WFP简介
WFP全称Windows Filtering Platform,即Windows过滤平台。随着网络的高速发展,网络安全问题越来越受到重视,同时随着Windows OS的快速更新换代,以往的网络过滤框架已经不能满足需要,于是导致了WFP的出现。WFP是Visata中引入的API集,也是从Vista系统后新增的一套系统API和服务,在新版的操作系统中,开发人员可以通过这套API集将Windows防火墙嵌入到开发软件中,可以恰到好去的处理Windows防火墙的一些设置。
WFP为网络数据包过滤提供了架构支持,是微软在VISTA之后,替代之前的基于包过滤的防火墙设计,如Transport Driver Interface(TDI)过滤,Network Driver Interface Specification(NDIS)过滤,Winsock layered Service Providers(LSP)。
在VISITA及以后的系统中,系统防火墙的过滤钩子驱动不在适用,只能使用WFP。WFP允许程序猿编写代码和操作系统的网络协议栈进行交互,同时在网络数据到达最后的归宿前,将数据进行过滤,拦截,修改等。流程如下图:
              
WFP的框架分为两层,一部分为用户态,另一部为内核态,及用户态对应着用户态过滤引擎,内核态对应着内核过滤引擎。对于用户态过滤引擎,所需的API以及RPC接口都被封装在模块fwpuclnt.dll中。值得注意的是,无论程序猿使用用户态过滤引擎还是内核态过滤引擎,最终都是与内核态过滤引擎交互。最终结果如下图所示:

在上面已经介绍了WFP的网络处理流程以及框架结构,不难发现,Filter Engine是WFP的核心所在,他提供了基于TCP/IP网络数据的过滤操作。无论是用户态过滤引擎,还是内核态过滤引擎,最终都是与内核态过滤引擎进行交互,内核态过滤引擎是整个WFP的主体,同时被分为很多层,不同的分层代表着网络协议栈特定的层,每个分层又可以存在子层和过滤器。当过滤引擎检查到网络数据包命中了过滤器的规则,就会执行过滤器中的指定动作。对应一般的应用,过滤器的动作只有两个:放行和拦截。但在真正的应用中,Filter Engine会存在很多层,很多过滤器,这些层和过滤器,可能会同时命中,这样就会存在多个过滤动作,对于这些过滤动作可能不相同,于是WFP引入了过滤仲裁器模块,这个模块将最终结果给Filter Engine,而Filter Engine将结果给垫片。
1.2.1  垫片
这里出现了一个新概念:垫片。何为垫片?垫片是特殊的内核模块,这特殊的模块被插进系统的网络协议栈的不同层中,用来获取网络协议栈的数据。垫片还能将内核态过滤引擎的过滤结构反馈给网络协议栈,是网络协议栈与WFP的通信桥梁。但是,在真正的应用中,垫片是透明存在的,不需程序猿操作处理。
1.2.2 callout
在上图中,我们还发现Filter Engine对应了多个callout,callout为何物?callout为一种数据结构,是对WFP功能的扩展,是由一系列回调函数组成,由过滤器指定。对应callout结构体,在其中包含了一个GUID值,这个值是用来识别唯一的callout(这个值,可以在开始菜单中搜索GUID,找到一个GUID生成器来生成)。在callout中,还存在三个回调函数,对于这三个函数,只有一个是事前回调函数,其余两个是事后回调函数,一般只用事前回调函数,这些回调函数当被命中时会被调用。
对于事前回调函数参数比较多,主要是三参数,第一个,第二个,最后一个,具体的可参照MSDN。对于第一个参数,是一个传入参数,可以从此参数获取到访问端口,本地端口,本地连接IP,远程连接IP等。对于第二个参数,可以获取到,进程ID,进程路径,数据流等。对于最后一个参数,用来反馈结果,比如拦截,不做任何动作,允许等。
1.2.3 分层
从上图中,我们发现过滤引擎由很多层组成。每一层代表了网络协议栈的一个层。分层是一个容器,里面包含了0或多个过滤器,或一个或多个子层。每个分层都有一个唯一标识的UID(内核中使用64位LUID,用户层使用128位GUID)。
1.2.4 子层
子层由分层划分而来,是分层的一个更小单位,一个分层中包含了多个或零个子层,而子层之间的优先级由权重来区分,权重越大,优先级越高。
注:以上内容参考《Windows内核安全与驱动开发》一书,了解详情,请查看此书。
1.3 相关技术
驱动:驱动可分为两类:传统驱动和微过滤驱动。传统型驱动的特点是所有的IRP都需要自己处理,自己实现针对不同IRP的派发函数;有两种类型,NT模式和WDM模式;NT模式通过注册系统服务来加载,不支持即插即用;WDM模式不通过INF文件加载,它支持即插即用。对应微过滤驱动,它是微软推出的一个驱动框架,将一些操作全部封装,方便操作,用户只需针对不同的IRP处理好他们响应的前后操作和用户态和内核态通信,类似用户态的API HOOK。同时,也可以看着驱动是为上层服务提供一些调用列程,分为用户模式驱动和内核模式驱动,内核模式驱动又分为文件系统驱动,即插即用驱动和非即插即用驱动。
DuiLib:DuiLib是一款强大的界面开发工具,可以将用户界面和处理逻辑彻底的分离,极大提高了用户界面的开发效率。DuiLib是DirectUI的一种,DirectUI取名自微软的一个窗口名”DirectUIHWND”,意为Paint on parent dc directly, 即子窗口不以窗口句柄的形式创建,只是逻辑上的窗口,绘制在父窗口之上。DuiLib是使用XML来描述界面风格,界面布局,可以很方便的构建高效,绚丽,非常易于扩展的界面,能很好的将界面或逻辑分离,易于实现各种超炫的界面。DuiLib解决了传统MFC界面开发软件不美观,界面细节处理不好,使用硬编码,开发效率低,生成程序体积大等问题。DuiLib界面完成基于GDI在窗口上自绘,无其他依赖,未使用特殊或危险的系统调用,而且完全兼容ActicveX控件。
1.3.1 DuiLib核心结构
DuiLib核心结构图如下:

主要分为控件,容器,UI构建析构器(XML解析),窗口管理器(消息循环,消息映射,窗口管理等),渲染引擎几大部分。
1.3.2 DuiLib消息流程
DuiLib消息循环非常灵活,响应方式如下:
1)实现IMessageFilterUI接口,调用CPaintManagerUI:: AddPreMessageFilter,进行消息发送到窗口过程前的过滤
2)重载HandleMessage函数,当消息发送到窗口过程中时,最先进行过滤
3)实现INotifyUI,调用CPaintManagerUI::AddNotifier,将自身加入Notifier队列
4)添加消息代理(其实就是将成员函数最为回到函数加入),MakeDelegate(this, &CFrameWindowWnd::OnAlphaChanged);,当程序某个地方调用了CPaintManagerUI::SendNotify,并且Msg.pSender正好是this,我们的类成员回调函数将被调用
消息传递给控件后,主要通过control_from_point,通过鼠标的座标点进行判断是哪个控件,并将由该控件进行响应鼠标消息,如下图

1.3.3 DuiLib流程
DuiLib先加载XML,通过CMarkup库解析XML文件,生成XML的DOM节点树,然后递归各个节点,生成DUI对象。对象生成生成顺序为,先全局资源(如IMAGE,font等),然后Windows属性,后各个顶级控件,最后对各个控件递归构造其子控件对象。大概流程为先生成一个XML,再生成一个WindowImpBase,然后加载XML,最后显示窗口,所述如下图:

1.3.4 DuiLib的XML描述
Duilib主要是通过XML来进行界面的布局配置,程序通过读取并解析XML文件来创建对应的窗体。DuiLib的页面布局分为三类:窗体(Window)、容器(Contain)和控件(Control);窗体就是要创建的窗口,容器则相当于是窗体内的一个子窗体,可以在容器内添加容器或者控件,控件就是一些常用的Button、Edit、Label等窗体上的基本元素。
1.3.5 WFP流程
前面已经介绍了WFP的一些基本概念,那WFP的流程是什么勒?WFP的流程可分为以下几个步骤:
1)调用API函数FwpmEngineOpen获取句柄
2)调用FwpmTransactionBegin更改过滤权限
3)注册呼出接口,添加过滤内容,对象和回调函数
4)调用FwpmTransactionCommit提交所添加内容,监控网络流量
5)程序退出,卸载删除呼出接口,过滤对象,添加的分层
2 概要设计
2.1 设计思路
本程序主要是通过驱动,过滤拦截网络数据包,在驱动层获取所产生的数据包的长度,进程名,进程ID,上传,下载等信息;获取后,将此信息上传到应用层,应用层获取这些数据后,通过计算,将其显示在界面上,从而方便直观的看到当前数据流量情况。
2.2  主要功能
驱动层通过WFP,获取网络数据传给应用层,应用层获取这些数据,显示在界面上。主要功能如下:
2)驱动层获取网络数据包的方向(上传或下载)
3)驱动层获取进程信息,如进程PID,进程名,进程全路径
4)驱动层获取当前系统所创建的所有信息,枚举进程
5)驱动层监控进程的创建与退出
6)应用层显示所有进程,并添加创建进程,删除退出进程
7)应用层现在每个进程每秒钟流量情况
8)应用层计算每秒钟所有进程的流量情况
9)应用层统计当前有多少进程处于监控状态
2.3 软件情况
1) 软件名称:WFP流量监控系统
2) 开发平台:VS 2013
3) 运行环境:WIN 7 64位操作系统
4) 本程序由于包含驱动,所以运行时需驱动签名或禁止驱动签名
2.4 流程图
(1)软件交互

(2)程序流程
运行界面EXE程序,加载驱动,驱动加载失败,退出程序,并显示相应的错误信息。程序驱动加载成功,驱动遍历进行,获取进程信息,存放到链表中,通知应用程序获取数据并显示在界面上。驱动监控进程创建与销毁,存放链表中,有程序的创建或销毁,通知应用层获取数据,应用层得到数据后,查找当前基础是否存在界面中,不存在添加入界面,存在若是销毁从界面中删除,若是生成不做处理。驱动监控网络流量,若产生网络流量信息,将数据存放于链表中,通知应用层获取数据,应用层得到数据后,通过计算匹配,以大约每秒产生的流量做统计,显示到界面上。如若没有数据产生,继续监控。
流程如下图所示:

3 程序详细说明
3.1 界面设计
界面设计简单明了,主要包含进程统计,所有进程产生上传流量显示,所有进程产生下载流量显示,当前系统所有进程流量监控,单个进程的下载流量监控,上传的流量监控,PID的监控,路径的监控等。
其中,在界面设计中,创建了四个线程,2个VECTOR来处理存放驱动层产生的数据。四个线程的主要工作是:从驱动层获取线程数据ThreadGetProcess,从驱动层获取网络数据ThreadGetData,维护进程的创建和销毁ThreadDeleteData,每秒显示当前流量情况ThreadSetUIDisplay;两个VECTOR的作用是:存放驱动层传入的进程数据m_vtProcessList,存在驱动层传入的网络流量数据m_vtDataList。界面如下:

—_—,界面是不是有点面熟?额,不错,界面是仿照QQ电脑管家的界面制作而成的!
3.1.1 进程数统计
进程数的统计是在R3层(应用层界面)实现的,在类中定义了一个静态私有变量m_nProcessCount,用于记录进程的总数。此变量在进程类型为创建时自加,在进程类别为销毁时自检。此变量在线程 ThreadDeleteData中进行处理。
3.1.2 进程的上传下载速度统计
进程的上传下载速度统计分为两种,一种是所有进程,另一种是当进程的上传下载速度统计,对于这两种速度的统计显示,都是在线程ThreadSetUIDisplay中进行处理,而对于两种流量数据统计测在线程ThreadGetData中进程记录处理。对于总流量的统计,声明了两个变量m_uToalDownFlow和m_uToalUpFlow,在线程m_ThreadGetData获得R0层数据时将产生数据流量的每个进程数据长度相加,从而得到整个线程的中的所有流量,同时每秒钟清零重新记录一次,这样就得到了每秒钟所有进程的总流量数。
同理,对应单个进程的流量统计,在m_vtDataList中找到当前产生流量的进程,然后与此进程前一流量累计相加,没秒钟清零一次,显示时遍历m_vtDataList,将数据显示到界面。
3.13 进程的创建与销毁
对于进程的创建与销毁,在R3从R0通过线程ThreadGetProcess将数据获取后,存放在m_vtProcessList中,然后线程通过遍历ThreadDeleteData通过遍历m_vtProcessList从中取出数据,然后根据进程类型,做响应的处理。若进程是创建,且在m_vtDataList不存在,那么将此进程插入m_vtDataList,并在界面显示;反之,进程是销毁,则将数据从m_vtDataList中删除,并移除界面。
3.2 驱动WFP的设计
对应驱动,采用的是NT模式。设置IRP,符号链接等后,则进行进程的枚举,WFP的注册,进程的监控。驱动层维护这三张链表:一张记录进程枚举,创建,销毁g_lProcessList,一张记录流量数据与进程端口,进程名等的绑定g_lBindDataToProcessList,,一张记录流量的上下文g_lFlowContextList。
3.2.1 进程处理
进程处理包含三部分,进程的枚举,创建,销毁。进程枚举是使用PspCidTable枚举法,从PID4开始枚举,每次加四,通过函数PsLookupProcessByProcessId来判断当前的PID是否返回成功,返回成功,则此PID有对应的进程,否则不存在。进程的创建和删除,通过PsSetCreateProcessNotifyRoutineEx创建回调函数来对进程的创建和销毁进程监控。
3.2.3 数据流量的处理
数据流量的处理,是基于WFP技术进行处理。对应数据流量的处理,首先驱动注册了两个callout,一个用于获取IP地址,端口,进程ID,进程路径等数据信息,另一个用于获取数据包信息,如数据包长度,数据包内容,数据方向等数据。分别得到数据后,需要将它们关联起来,此时关联它们用到的函数是FwpsFlowAssociateContext,关联之后,将数据存入链表中,发向R3层,这样就得到了进程与进程所产生流量的信息。
3.3 驱动与应用层数据交互
R0与R3的交互,此处只有R0的数据传入到R3,无R3的数据传到R0。R3与R0的通信方式为DO_BUFFERED_IO方式,R3层通过函数DeviceIoControl想R0发送控制码,从而获取数据。程序中的控制码一共有两种:一种是获取进程信息的数据,数据码为MONITOR_IOCTL_PROCESS_MONITOR,另一种是获取流信息的数据,数据码为MONITOR_IOCTL_DATA_MONITOR。同时,程序中采取信息量的方式向R3传送数据,即当有数据产出是,发送信号量,R3的都信号量后,开始向R0获取数据;为了保证所有数据都能被R3获取到,在R0创建了一线程,定时的向R3发送信号量。
4.总结

结束语

参考资料:
1.http://blog.csdn.net/z18_28_19/article/details/12586523
2.http://wenku.baidu.com/link?url=TInoWfaiKIq_joQ4_nI8xbfSQngHSAqzIPeEBqnyYMGeMQywL-mzEUwIQoj3lf1KRkoNM_oxV0NcypUfCGqaXsKZCA559Bu2VmJy_aXM2Ri
3.http://bbs.pediy.com/showthread.php?t=173871&highlight=WFP+%E9%98%B2%E7%81%AB+%E7%81%AB%E5%A2%99
4.http://blog.csdn.net/baggiowangyu/article/details/7786825
5.http://blog.chinaunix.net/uid-11640640-id-3221572.html
6.http://baike.baidu.com/link?url=gYO09tgsmg1qKuYouBK1U3n7ltonjMgcwdySOUDMIa66Vb-XBsqzFMxyrlMhx9JdvJqJh-49NRbydrYQnyRGKK
7.http://blog.csdn.net/kerwinash/article/details/38556069
8.http://wenku.baidu.com/link?url=9C40AoCTrSNIfGCVB3nwTdJY8L-BN85wPs5UczuVSfbuQT_yuYljz-EsKAhG0yL2B7WlmPJAkZb8g0zQwMJXj4wGaIMjyMTEfNCWleJc3qS
9.http://wenku.baidu.com/link?url=kNHtQC8Pmy_CP_vP2hJHJdhwfE4EEUNKslhV4ftmLC2LjtNWrpF3RSY4s-8ApWsQYksyziDPERVfBUxLJ_8vlCLjjnO9H_z71sRQcHvcG3S
10.书籍<Windows内核安全与驱动开发>
*转载请注明来自看雪论坛@PEdiy.com


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 10
支持
分享
最新回复 (35)
雪    币: 2325
活跃值: (4913)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
前排 支持下·!
2016-8-10 21:38
0
雪    币: 256
活跃值: (48)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
支持楼主 话说WFP真的很方便,不过一般都还在用TDI和NDIS
2016-8-10 21:51
0
雪    币: 407
活跃值: (1816)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
后排支持
2016-8-10 21:56
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
用TDI的还是很多,因为都兼容,,不够以后肯定是WFP的了
2016-8-11 00:26
0
雪    币: 346
活跃值: (45)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
我基本 上都tdi
2016-8-11 08:38
0
雪    币: 0
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
多谢分享
2016-8-11 08:55
0
雪    币: 1726
活跃值: (1580)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢分享,拿走学习了
2016-8-11 09:19
0
雪    币: 39
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
昨天领导还在安排我做一个流量控制任务,今天就看到你的文章了
2016-8-11 09:27
0
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
谢谢楼主,先收藏!
2016-8-11 09:37
0
雪    币: 27
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
前排占座,这部分资料太少了。顺便吐槽一下谭文新书的第15章写得跟“屎”一样,应该不是他本人写的
2016-8-11 09:56
0
雪    币: 0
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢楼主分享
2016-8-11 16:09
0
雪    币: 212
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
收藏,收藏!!!
2016-8-12 09:12
0
雪    币: 39
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
看了你的例子,好像找不到控制流量的相关功能只能看到监视流量变化的功能,请问怎么控制流量的速度?
2016-8-12 18:01
0
雪    币: 314
活跃值: (171)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
15
两种方法,一种将数据存放在链表中,创建线程来处理这张链表,加上sleep来延迟数据发送。另一种方法是做丢包处理!
2016-8-16 19:50
0
雪    币: 2044
活跃值: (237)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
mark.....
2016-8-16 22:35
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
发布一下吧。只想先看看效果的 路过
2016-8-18 10:45
0
雪    币: 235
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
TDI在X64之后就不支持了,还是WFP正道
2016-8-24 09:49
0
雪    币: 436
活跃值: (2668)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
酷帖子,mark一下,感谢分享。~~~
2016-9-9 22:35
0
雪    币: 47
活跃值: (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
看了你的例子,好像找不到控制流量的相关功能只能看到监视流量变化的功能,请问怎么控制流量的速度?
2016-9-10 06:22
0
雪    币: 436
活跃值: (2668)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark一下。感谢分享。
2016-10-11 16:49
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
请问,要想控制某进程的上行或下行流量,不让其超过一个固定数值,该怎么做
2016-11-8 09:39
0
雪    币: 12
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
udp限速有啥好办法没....tcp丢包可以..udp怎么办?
2017-2-27 11:01
0
雪    币: 37
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
不知道为什么,我在windows7上测试的好多地方蓝屏,改了几处了,还有蓝屏,还在改……
2017-12-15 14:09
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
不光需要下载 代码.rar ,还要下载exe.rar,否则自己编译代码后运行不起来。窗口布局资源在exe.rar中
2018-8-9 16:26
0
游客
登录 | 注册 方可回帖
返回
//