NDIS网络防火墙开发经验总结

2024-04-30

NDIS网络防火墙开发经验总结(精选2篇)

篇1:NDIS网络防火墙开发经验总结

NDIS网络防火墙开发实践经验总结

一、window软件防火墙开发概述:

在window下开发软件防火墙可以实现:NDIS数据包的截获、NDIS数据包的抓取、NDIS数据包的分析、NDIS数据包过滤、NDIS 驱动对IP与port的过滤、NDIS中间层驱动安装技术等。本文对NDIS开发基本流程、NDIS开发注意事项、NDIS安装过程中出现的各种问题都给予详细说明,希望对做NDIS开发程序员有所帮助。

目前可以实现软件防火墙的方法有:

(1)SOCKET端口形式。

(2)NDIS中间驱动IPHOOK形式(xp/2003)。

(3)NDIS中间驱动miniport形式(xp/2003/vista/win7/win2008)。

三种形式从开发难度到使用范围都有自身的特点。

(4)SOCKET形式是面向应用层开发的,在代码及调试方面相对后两种简单的多,但

SOCKET形式不能捕获所有数据包,所以用socket开发防火墙不是最好的选择。

(5)后两种属于NDIS中间驱动程序开发,是面向驱动层(底层)开发,代码编写及调试较

socket形式上难。(说明:可能大部分采用高级语言程序员根本都没接触过驱动开发)但NDIS形式可以捕获到所有通过网卡的数据包(NDIS中间驱动是插入到协议层与网卡驱动层的中间驱动程序所以数据必须通过)。所以本文作者建议采用NDIS开发软件网络防火墙。

二、DNIS中间驱动开发注意事项:

NDIS中间驱动程序开发window防火墙要注意window版本问题,因为目前用户使用的window版本有window200、window200 server、window xp、window2003、window vistawindow

7、windown 2008 server。你采用的NDIS开发技术直接决定是否能在不同window版本上运行,这是很关键的问题。目前作者知道的NDIS防火墙技术有两种:

2.1.IP_FIREWALL_HOOK(NDIS防火墙钩子技术适合XP/2003)。

(1)这种技术的特点:相对miniport的开发、测试、安装简单些。

(2)安装步骤简单见四:可以采用注册表注册后用net start启动,也可以采用:

OpenService、CreateService、StartService等函数创建服务形式启动驱动具体用法请查询msdn帮助)

(3)比较典型的案例: ewall-Hook-Driv此种方法对window vista 之前window 2000之后的操作系统是没有任何问题。通过作者的开发测试,对于window vista 之后的产品向window 7 window 2008是不支持的(这点一定要注意)。

这里网上有许多评论有人说还支持,但本文作者给出答案是不支持,理由 msdn(http://msdn.microsoft.com/en-us/library/windows/hardware/ff546487(v=vs.8

5).aspx中有这样一句话: Note: Starting with Windows Vista, do not implement filter-hook or firewall-hook drivers.Use Windows Filtering Platform Callout Drivers instead.翻译成中文大概意思:从vista以后不再支持” filter-hook”,请使用…)。

(4)你可以在window 7或window2008测试下你的钩子防火墙在status=IoCallDriver加入dbprint代码用 dbgview.exe截获status的值你会发现

在2000、xp、2003下返回0一切正常,在vista、win7、2008下返回0xc0000002-

0xc000000d的任意值。所以钩子防火墙在vista及以后的版本是不能实现的。

所以作者建议在vista以后的版本就要用IP HOOK(ipfirewall)浪费时间啦。

2.2.NDIS(miniport –protocol)中间驱动技术(XP/2003/vista/win7/2008)。

这种形式在2000、xp、2003、vista、win7、2008下都可以现实,但原理和代码实现上 要比钩子复杂的多,安装测试也比较麻烦。典型列子是ddk源文件路径下的passthru项 目。但我开发这个项目后,总结下NDIS开发其实并不是很难只是以前对这方面知识缺 乏已。

三、NDIS程序结构:

3.1.DriverEntry函数:这个函数必须存在,它是window驱动的入口函数(IPHOOK

与miniport都必须定义的函数,在驱动安装启动是执行)。

3.1.1.这个函数有两个参数:

IN PDRIVER_OBJECTDriverObject,IN PUNICODE_STRINGRegistryPath。

3.1.2.DriverEntry内部常用代码:

NdisMInitializeWrapper(中间驱动miniport):初始化小端口时会用到这连个参数。IoCreateDevice(钩子驱动IPHOOK):建立IO设备时会用到。

3.1.3.建立miniport与protocol端口(中间驱动miniport):

NDIS_PROTOCOL_CHARACTERISTICSPChars;

NDIS_MINIPORT_CHARACTERISTICSMChars;

并分别设置PChars、MChars一系列属性参数指定处理函数。

这里有几个很重要的属性在开发防火墙程序中很重要我说明下其它参数见DDK帮助文档。

MChars.CancelSendPacketsHandler = 自定义截获发送函数;

PChars.ReceivePacketHandler =自定义截获接受函数1;

PChars.ReceiveHandler =自定义截获接受函数2;

(说明:ReceivePacketHandler与ReceiveHandler区别:是针对不同型号网卡分别采用这两个属性接受数据的建议全部设置上你自定义的接受函数。)

3.1.4.如果是IPHOOK驱动需要绑定钩子(钩子驱动IPHOOK):

IP_SET_FIREWALL_HOOK_INFO filthook;

filthook.FirewallPtr = 钩子函数(处理过滤/抓包函数的函数);

filthook.Priority = 1;

filthook.Add = true;

应用这个IoBuildDeviceIoControlRequest函数绑定具体见DDK文档。

3.2.MajorFunction函数任务的指派(IPHOOK与miniport都必须定义的函数):

DriverEntry函数是驱动与操作系统的接口函数,MajorFunction函数是用户通过

应用程序控制驱动的接口。

3.2.1.几个常用的函数(IPHOOK与miniport都必须定义的函数):

DispatchTable[IRP_MJ_CREATE] = 创建函数;

DispatchTable[IRP_MJ_CLEANUP] =清除函数;

DispatchTable[IRP_MJ_CLOSE] = 关闭函数;

DispatchTable[IRP_MJ_DEVICE_CONTROL] =用户IO控制函数(这个函数很重要);

以上三个函数可以指向IO控制函数即:

DispatchTable[IRP_MJ_CREATE] =

DispatchTable[IRP_MJ_CLEANUP] =

DispatchTable[IRP_MJ_CLOSE] =

DispatchTable[IRP_MJ_DEVICE_CONTROL] =用户IO控制函数(这个函数很重要);

3.2.2.用户IO控制函数(DevIoControl):是用户通过指定IOCTOL码向NDIS驱动发出指令要求驱动为自己做事。(具体建立IO控制码见DDK)

3.2.3.DevIoControl(NDIS是一个很重要的函数,IPHOOK与miniport都必须定义这个函数)函数的定义规则:

它有两个参数:

IN PDEVICE_OBJECTpDeviceObject,IN PIRPpIrp(这个是主要参数,是驱动程序与用户的数据通信接口)

PIO_STACK_LOCATIONpIrpSp;必须定义本地IO堆栈变量。

pIrpSp = IoGetCurrentIrpStackLocation(pIrp);//返回输入/输出堆栈位置

ioBuffer = pIrp->AssociatedIrp.SystemBuffer;//获得IO操作缓存区指针

IOCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;//获得IO操作码

下面就根据用户发来的IO操作命令进行处理,处理过程如下:

switch(IOCode)

{

Case IO控制码1:

自定义操作函数1;

Break;

Case IO控制码2:

自定义操作函数2;

Break;

Case IO控制码3:

自定义操作函数3;

pIrp->IoStatus.Information = outputBufferLength;//这里要注意

Break;

}

最后加入下面代码:

if(NtStatus!= STATUS_PENDING)

{ pIrp->IoStatus.Status = NtStatus;IoCompleteRequest(pIrp, IO_NO_INCREMENT);

}

这里我要说下NDIS驱动开发IOCTRL写入或读取数据时要注意两点:

1.上面的pIrp->IoStatus.Information = outputBufferLength句用不好会出问题的。它是用在向用户应用程序返回数据的过程体中,如果这句用不好你应用程序可能接受不到NDIS返回给你的数据。

2.同时接受和返回如何做?

其实读取和写入全是在pIrp->AssociatedIrp.SystemBuffer缓存中我们操作的次序是先把用户发来的数据读出 把要写的的数据写入AssociatedIrp.SystemBuffer中。例如:

用户EXE中IO操作是:

DeviceIoControl(devhdle, IO操作码,输入数据地址,输入数据长度, 输出数据地址, 输出数据长度,返回值地址, NULL))

NDIS可以这样读取返回数据:

读取数据:ibuff=pIrp->AssociatedIrp.SystemBuffer;

返回数据:oBuffer=pIrp->AssociatedIrp.SystemBuffer;

自定义函数(oBuffer)向oBuffer写数据。

明白啦吗?还不明白,我还有个办法就是你自己动手实验一万遍。其实我已经说的很明白啦。

注意:IO操作码: 这个码必须是可读写的。至于怎么生产你看DDK。

3.3.驱动卸载函数(Unload IPHOOK与miniport都必须定义的函数):这个函数只有一个

参数IN PDRIVER_OBJECTDriverObject。作用:当驱动卸载时释放我们在程序中分配的内存、miniport端口、IO设备等。

总结: 从NDIS程序结构中我们不难找出NDIS的miniport与iphook开发的区别就是在你

驱动中是否注册啦miniport_protocol还是绑定啦IP_SET_FIREWALL_HOOK_INFO钩子,基本结构是一样。如果你在网上看到NDIS开发文档感到很难时我只能说:”真正了解一门技术是有一个过程的,过程中遇到些困难是很正常的,关键是你能否坚持到最后!”。

四.安装NDIS驱动方法:

4.1.IPHOOK驱动安装:相当简单我这里介绍两种方法:

4.1.1.手动注册表建立服务

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESYSTEMControlSet001Services驱动名]

“Type”=dword:0000000

1“Start”=dword:0000000

3“ErrorControl”=dword:00000001

“ImagePath”=system32drivers驱动文件名.sys

“DisplayName”=“驱动名”

“Group”=“Extended Base”

4.1.2.用”NET STRAT 服务器名”启动/”NET STOP服务器名”停止服务

4.1.3.安装启动后可以用代码直接使用此服务:

(1)#defineMY_DEVICE_NAME “.驱动名” //驱动名称

(2)HANDLEhdle=CreateFile(MY_DEVICE_NAME,GENERIC_READ |GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,(HANDLE)INVALID_HANDLE_VALUE);

(3)

4.1.4.对于(4.1.1与4.1.2)前步可以完全用代码取代手工来完成:

(1)拷贝.SYS文件到system32drivers(具体代码来完成不是很难)。

(2)定义SC_HANDLE hSCManager;变量。

(3)hSCManager = OpenSCManager(NULL, NULL,SC_MANAGER_ALL_ACCESS);打开服务控制管理器。

(4)如果(3)成功OpenService(hSCManager, lpszServiceName,SERVICE_ALL_ACCESS);打开服务。

(5)如果(4)失败说明驱动服务没有安装开始安装驱动:

hService = CreateService(hSCManager, lpszServiceName, lpszServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpszDriverPath, NULL, NULL, NULL, NULL,NULL);

建立服务。

(6)启动服务器StartService(hService, 0, NULL);

(7)关闭SC_HANDLE:CloseServiceHandle(hSCManager);

(8)再使用4.1.3.中代码访问驱动。

以上说明啦NDIS钩子驱动(不含miniport-protocol端口)的安装使用两种方法。

4.2.NDIS中间驱动(miniport-protocol)安装使用方法:

4.2.1只要你掌握其实也很简单(你可以参考DDK_SRC下的netcfg例子。其中有一个很重要的函数是HrInstallNetComponent你把它看明白安装基本就差不多啦。

4.2.2.但这里有个很大开发安装程序问题:就是netcfg是用ddk编译的,我们有时要把安装代码集成到VC编译器中,有人说include ddk包文件。我这里建议你用DDK编译成dll 接口函数。

4.2.2.其次你最好对inf文件各个键值作用了解详细。我这里要说明

[SourceDisksFiles]这个键,如果你的inf文件与sys在同一个路径下那么

[SourceDisksFiles]键值为空。如下:

[SourceDisksFiles]

Passthru.sys=1 改成;Passthru.sys=1前面加分号

如果不这样在安装sys时可能提示你选择sys路径问题。

4.2.3.值得特别注意的是:无论你安装成功或不成功你最好把用到的所有inf文件和sys

文件拷贝到 windows/inf 路径下。拷贝过去绝对没有坏处,但不拷贝可能

安装过程会出现不成功的现象;这点是本人实践中总结出来的。

至此,本人对DDK开发软件防火墙的两种方法全部介绍完毕。真正想实现防火墙的封包、抓包等一系列功能需要你不断总结和摸索才行。以上内容都是作者本人通过开发过程中实践中总结出的经验可能有些地方与网上其它文章有很大出处,但上面思路在PC机上全部实现过。(本人在开发过程依据是DDK帮助文件和PASSTHRU)。在此,谢谢各位网友网上文档给予了很大的帮助!

2012年11月29日

本文来源: http:///techntxt/20121***705291

篇2:NDIS网络防火墙开发经验总结

资料太少,摸索着实在太辛苦,这是BACnet项目完成之后的一点开发经验,希望对正在摸索的各位同仁,有所帮助。

任务定位:

BACNet分为系统应用和开发应用,购买现有的BACNet设备组网,应用,属于系统应用,放松心情,继续读下去,如果是开发BACNet设备,这里的一点经验就不需耽误时间了。

层次定义:

BACNet既然协议里分了那么多层,我们要做多少呢?

继续放松,BACNet的系统应用来说,我们只需做到应用层+网络层就可以了,不要被协议厚厚的书吓到,我们用到的,很少。

好了,现在知道我们要干什么了,就是拿到BACNet设备进行网络层以上的应用。

资料选择:

BACNet协议,中英文网络上都可以找到,如果网络没搜过到,我的资源里也提供了下载。还推荐一本书,《智能楼宇BACNet原理与应用》董春桥写的,只出版了3000册,如果能搞到,庆幸吧!

知识储备:

既然是网络开发,必备网络编程一点小小的经验,尤其是UDP。

开发工具:

工欲善其事,必先利其器。看协议可以了然于胸,但如果有个智能点的开发工具,效率可以乘以10倍,推荐VTS,网络上应该可以下载到,我的资源里也提供了下载。

软件架构:

对于UDP,相信做这个的不需我多说。

对于BACNet编码,一句话,NPCI+BCLCI+APDU,唯一难一点的,就只有APDU,不过,有VTS的话,轻松很多。

好了,随手涂鸦的几句话,希望对大家有点帮助吧,QQ:404536204,愿与同仁共同进步!

如果上面提到的资料比较难找的话,我的资源里也有提供,开发源码:

VTS:

中文协议:

上一篇:香港中华工商业协会代表团参加厦门中国国际投资贸易洽谈会下一篇:奔忙的身影作文600字