基于NDIS的内核态防火墙设计

来源:互联网 发布:玲珑炒股软件 编辑:程序博客网 时间:2024/05/12 13:15

1.      安装与编译NDIS Filter框架

NDIS Filter框架集成在WDK中,微软提供的最新的是WDK8.1,需要搭配VS2013使用。如果强行在VS2012或更低版本中进行编译将被疯狂提示编译错误。

安装WDK8.1和VS2013时有一点要注意,先安装VS2013,然后再安装WDK8.1,这样在VS中新建工程时可以在目录里找到NDIS Filter框架。

创建以后在编译工具栏里选择Win8.1 Debug

然后按F5编译,之后我们就会惊讶地发现尽管使用的是原版的框架,竟然也无法编译通过。不过不要惊慌,我们需要一边竖起大拇指感叹微软6666666,一边要观赏编译错误信息以便解决相关问题。

有两条编译错误信息,如图

错误一提示无法找到签名,错误二提示无法找到.sys文件。既然是签名问题肯定要在签名的方面着手解决。右键点击ndislwf5,选择属性,打开对话框

对话框如下图

看到Driver Signing就知道应该如何处理这件事情了,在右边的Test Certificate里点击下拉按钮,会有一个Create Test Certificate,点击之后就完成了签名注册。

而第二个编译错误,我擅自猜测由于错误一的原因,无法生成.sys文件,而在修复错误一之后,编译之后系统疯狂生成.sys文件导致编译错误而被迫被解决。

这样安装与编译部分就顺利完成了。

2.      虚拟机安装与操作系统设置

由于调试过程中需要重启电脑,以便发送信息给调试器WinDbg,而如果不使用虚拟机,直接在本机调试,将在重启电脑时顺便重启WinDbg,这样在重启之后的WinDbg中将持续提醒重启系统,使我们陷入重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》重启-》的困境,无奈之下只好使用虚拟机调试。

在这里我选择使用VMWare虚拟机系统,因为我只会这个。

在VMWare中安装win8.1操作系统,然后需要在新的系统中进行设置。

首先把系统设置为调试模式。

运行msconfig,选择引导选项卡,选择高级选项,根据下图进行相应设置

然后更改注册表项使系统可以显示调试信息。

运行regedit,打开注册表,

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager中添加DebugPrint Filter项,然后在该项中增加DEFAULT值,并把值设为f。

最后设置虚拟机设置界面中删去打印机以及增加串行端口并使用以便两个系统之间能够疯狂通信。

最后设置网络,将网络模式设置为桥接,如图

这样虚拟机的以及调试环境就到此搭建完成。

3.      WinDbg调试的使用

我也不想用调试器但是如果不使用调试器就无法看到程序的输出。

但是这个调试器比较高冷,和控制台以及GUI编程完全不同,甚至需要花费高达1113255分钟设置它。

首先在VS2013菜单上选择如下图的选项

输入虚拟中的计算机名称,在这里的名称是Orgline,然后点击下一步选择第三项手动设置,再点击下一步,将内核设置成下图所示,点击完成。

设置完成以后选择菜单中的调试选项中的附加到进程

传输选择内核传输,限定符选择虚拟机中的Orgline。可用进程选择内核,点击完成。然后就可以顺利看到调试信息。

然后重启虚拟机中的操作系统WinDbg就可以疯狂输出调试信息。

4.      NDIS Filter框架中函数的选择与使用

框架中大约仅有13654884112个函数,但并不是每一个都可以用到。既然是过滤网络数据包,我们需要的只有这一个函数FilterSendNetBufferListsComplete(

         NDIS_HANDLE         FilterModuleContext,

         PNET_BUFFER_LIST    NetBufferLists,

         ULONG               SendCompleteFlags

    )与FilterReceiveNetBufferLists(

         NDIS_HANDLE         FilterModuleContext,

         PNET_BUFFER_LIST    NetBufferLists,

         NDIS_PORT_NUMBER    PortNumber,

         ULONG               NumberOfNetBufferLists,

         ULONG               ReceiveFlags

)

前者保存网卡中数据包的信息,后者负责监听接收网卡中得到的数据包。

之后修改这两个函数以达到预期的要求。

5.      截取与翻译数据包

数据包传输到网卡上时是原始的包,并不是每一个人都能看懂,所以这时候需要对其进行翻译,以帮助我们拦截数据包。

首先需要知道以太网数据包以及IP数据包的格式,在这里不多说,网上有很多资料。了解之后就知道怎么翻译数据包了。

首先建立两个结构体包含以太网结构体以及ip协议数据报文结构体。在代码的头文件中都有描述,然后把接收的数据包转换成我们需要的形式。

在以太网结构体中找到以太网类型为8的数据包,也就是IP协议数据包,由于ip数据包是紧跟以太网数据包之后,所以将以太网数据包之后的地址强制转换为ip报文结构体。

截获ip报头之后,将其中的源ip地址提取出来,然后进行最后的翻译过程。

由于地址是由十六进制构成,且顺序与ip地址顺序相反,我采用的方法是对其以256取模然后再除以256去掉最后两位,得到两位十六进制再翻译为十进制,得到全部四位以后再组合为字符串,以便完成过滤功能。

6.      过滤数据包

在FilterReceiveNetBufferLists后默认调用NdisFIndicateReceiveNetBufferLists(

                   pFilter->FilterHandle,

                   NetBufferLists,

                   PortNumber,

                   NumberOfNetBufferLists,

ReceiveFlags)函数将数据包传送给上层,如果在得到一个特定的ip地址不想将其传给上一层,只需在这个函数里增加return语句即可。

7.      设置黑名单白名单过滤规则

黑名单与白名单可以对ip进行相应过滤。并提供选择黑名单或者白名单功能。

黑名单开启时,黑名单中的ip将被过滤。

白名单开启时,白名单中的ip将不被过滤。

由于是由文件读取,所以配置程序可以单独拿出来作为一个单独的程序。

8.      过滤规则设置UI设计

用C#写的,比较简单,就不多说啦。效果如下图。

0 0
原创粉丝点击