NDIS网络防火墙开发经验总结.docx
- 文档编号:6971025
- 上传时间:2023-01-13
- 格式:DOCX
- 页数:8
- 大小:20.03KB
NDIS网络防火墙开发经验总结.docx
《NDIS网络防火墙开发经验总结.docx》由会员分享,可在线阅读,更多相关《NDIS网络防火墙开发经验总结.docx(8页珍藏版)》请在冰豆网上搜索。
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版本有window
200、window200server、windowxp、window
2003、windowvistawindow
7、windown2008server。
你采用的NDIS开发技术直接决定是否能在不同window版本上运行,这是很关键的问题。
目前作者知道的NDIS防火墙技术有两种:
2.1.IP_FIREWALL_HOOK(NDIS防火墙钩子技术适合XP/2003)。
(1)这种技术的特点:
相对miniport的开发、测试、安装简单些。
(2)安装步骤简单见四:
OpenService、CreateService、StartService等函数创建服务形式启动驱动具体用法请查询msdn帮助)
(3)比较典型的案例:
http:
这里网上有许多评论有人说还支持,但本文作者给出答案是不支持,理由msdn(http:
Note:
StartingwithWindowsVista,donotimplementfilter-hookorfirewall-hookdrivers.UseWindowsFilteringPlatformCalloutDriversinstead.翻译成中文大概意思:
从vista以后不再支持”filter-hook”,请使用…)。
(4)你可以在window7或window2008测试下你的钩子防火墙在status=IoCallDriver加入dbprint代码用dbgview.exe截获status的值你会发现在
2000、xp、2003下返回0一切正常,在vista、win
7、2008下返回0xc0002-0xc000d的任意值。
所以钩子防火墙在vista及以后的版本是不能实现的。
所以作者建议在vista以后的版本就要用IPHOOK(ipfirewall)浪费时间啦。
2.2.NDIS(miniport–protocol)中间驱动技术。
这种形式在
2000、xp、
2003、vista、win
7、2008下都可以现实,但原理和代码实现上要比钩子复杂的多,安装测试也比较麻烦。
典型列子是ddk源文件路径下的passthru项目。
但我开发这个项目后,总结下NDIS开发其实并不是很难只是以前对这方面知识缺乏已。
三、NDIS程序结构:
3.1.DriverEntry函数:
这个函数必须存在,它是window驱动的入口函数(IPHOOK与miniport都必须定义的函数,在驱动安装启动是执行)。
3.1.1.这个函数有两个参数:
INPDRIVER_OBJECTDriverObject,
INPUNICODE_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_INFOfilthook;
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都必须定义这个函数)函数的定义规则:
它有两个参数:
INPDEVICE_OBJECTpDeviceObject,
INPIRPpIrp(这个是主要参数,是驱动程序与用户的数据通信接口)PIO_STACK_LOCATIONpIrpSp;必须定义本地IO堆栈变量。
pIrpSp=IoGetCurrentIrpStackLocation(pIrp);//返回输入/输出堆栈位置
ioBuffer=pIrp->AssociatedIrp.SystemBuffer;//获得IO操作缓存区指针
IOCode=pIrpSp->Parameters.DeviceIoControl.IoControlCode;//获得IO操作码下面就根据用户发来的IO操作命令进行处理,处理过程如下:
switch(IOCode){CaseIO控制码1:
自定义操作函数1;
Break;
CaseIO控制码2:
自定义操作函数2;
Break;
CaseIO控制码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中。
例如:
用户EXExxIO操作是:
DeviceIoControl(devhdle,IO操作码,输入数据地址,输入数据长度,输出数据地址,输出数据长度,返回值地址,NULL))
NDIS可以这样读取返回数据:
读取数据:
ibuff=pIrp->AssociatedIrp.SystemBuffer;
返回数据:
oBuffer=pIrp->AssociatedIrp.SystemBuffer;
自定义函数(oBuffer)向oBuffer写数据。
明白啦吗?
还不明白,我还有个办法就是你自己动手实验一万遍。
其实我已经说的很明白啦。
注意:
IO操作码:
这个码必须是可读写的。
至于怎么生产你看DDK。
3.3.驱动卸载函数(UnloadIPHOOK与miniport都必须定义的函数):
这个函数只有一个参数INPDRIVER_OBJECTDriverObject。
作用:
当驱动卸载时释放我们在程序中分配的内存、miniport端口、
IO设备等。
总结:
从NDIS程序结构中我们不难找出NDIS的miniport与iphook开发的区别就是在你驱动中是否注册啦miniport_protocol还是绑定啦IP_SET_FIREWALL_HOOK_INFO钩子,基本结构是一样。
如果你在网上看到NDIS开发文档感到很难时我只能说:
”真正了解一门技术是有一个过程的,过程中遇到些困难是很正常的,关键是你能否坚持到最后!
”。
四.安装NDIS驱动方法:
4.1.IPHOOK驱动安装:
相当简单我这里介绍两种方法:
4.1.1.手动注册表建立服务
WindowsRegistryEditorVersion5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\驱动名]
"Type"=dword:
00001
"Start"=dword:
00003
"ErrorControl"=dword:
00001
"ImagePath"=system32\drivers\驱动文件名.sys
"DisplayName"="驱动名"
"Group"="ExtendedBase"
4.1.2.用”NETSTRAT服务器名”启动/”NETSTOP服务器名”停止服务
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文件到system32\drivers\(具体代码来完成不是很难)。
(2)定义SC_HANDLEhSCManager;变量。
(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.2.但这里有个很大开发安装程序问题:
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:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NDIS 网络 防火墙 开发 经验总结