1、第一章引言11.1课题背景与意义11.2设计实现的主体功能11.3本课题的研究方法2第二章 WINSOCK 2 SPI编程技术42.1 Winsock 2 SPI基础42.2 传输服务提供者4第三章开发平台与开发工具5第四章系统设计与模块划分64.1本课题要实现的具体功能64.2程序工作流程图64.3模块划分74.3.1模块划分原则74.3.2模块结构84.3.3模块接口定义94.4编码规则104.5控管规则文件结构设计104.5.1控管规则文件需要存储的内容114.5.2控管规则文件结构124.6界面设计134.6.1制定界面风格134.6.2界面设计文档13第五章核心功能的代码实现175.
2、1 DLL的封包截获175.2 DLL的访问控管205.2.1对服务提供者函数做管制的函数205.2.2封包处理函数215.2.3 管制函数225.2.4 设置函数25第六章 测试26结 论28参考文献29致 谢30第一章 引言1.1 课题背景与意义Internet的出现及迅速发展给现代人们的生产和生活都带来了前所未有的飞跃。互连网已经成为扩展个人和企业发展的重要工具,人们已经进入了信息时代.互连网将整个人类社会缩小成了一个村落“地球村”,促进了信息的交流,提高了人们的工作效率,丰富了人们的生活。人们享受着信息时代带来的种种便利,体验着互联网带来的生活上的全新感受。但凡事有利必有一弊,随着对网
3、络的依赖越来越大,网络安全问题也越来越明显。由于黑客攻击和信息泄露并不是直接对系统造成损害,所以往往不能引起人们的注意。人们总是在网络安全问题发生带来严重后果后,才意识到网络安全的重要.随着网络的进一步普及,网络安全产品逐渐地进入人们的视野,而防火墙作为把守用户安全大门的重要工具,越来越受到人们的重视。自从1986年美国Digital公司在Internet上安装了全球第一个商用防火墙系统,提出了防火墙概念后,防火墙技术得到了飞速的发展。国内外已有数家公司推出了功能各不相同的防火墙产品系列。目前的防火墙产品主要有堡垒主机、包过滤路由器、应用层网关(代理服务器)以及电路层网关、屏蔽主机防火墙、双宿
4、主机等类型。作为内部网络与外部公共网络之间的第一道屏障,防火墙是最先受到人们重视的网络安全产品之一。虽然从理论上看,防火墙处于网络安全的底层,负责网络间的安全认证与传输,但随着网络安全技术的整体发展和网络应用的不断变化,现代防火墙技术已经逐步走向网络层之外的其他安全层次,不仅要完成传统防火墙的过滤任务,同时还能为各种网络应用提供相应的安全服务。另外还有多种防火墙产品正朝着数据安全与用户认证、防止病毒与黑客侵入等方向发展。虽然防火墙是目前保护网络免遭黑客袭击的有效手段,但也有明显不足:无法防范通过防火墙以外的其它途径的攻击,不能防止来自内部变节者和不经心的用户们带来的威胁,也不能完全防止传送已感
5、染病毒的软件或文件,以及无法防范数据驱动型的攻击。目前市场上大多数的防火墙产品仅仅是网关型的,虽然它们的功能相当强大,但由于它们基于下述的假设:内部网是安全可靠的,所有的威胁都来自网外。因此,他们防外不防内,难以实现对企业内部局域网内主机之间的安全通信,也不能很好的解决每一个拨号用户所在主机的安全问题,而大多数个人上网之时,并没有置身于得到防护的安全网络内部。个人上网用户多使用Windows操作系统,而Windows操作系统本身的安全性就不高。各种Windows漏洞不断被公布,对主机的攻击也越来越多。一般都是利用操作系统设计的安全漏洞和通信协议的安全漏洞来实现攻击。如假冒IP包对通信双方进行欺
6、骗;对主机大量发送IP数据包进行轰炸攻击,使之崩溃;以及蓝屏攻击等。因此,为了保护主机的安全通信,研究有效的个人防火墙技术很有必要。1.2 设计实现的主体功能现在防火墙的花样与种类繁多,让人眼花缭乱。但是防火墙的主要功能是防止外部网络的攻击以达到保护主机的目的。我认为哪些未知的网络IP可能对主机产生攻击可能我们都不知道。只要试验过才知道。所以现在防火墙一般与防病毒软件配合使用。这样才能安全的保护主机。1实现的主要的核心功能如下定义:1. 根据应用程序访问规则可对应用程序连网动作进行过滤;2. 对应用程序访问规则具有自学习功能;3. 可实时监控、监视网络活动。1.3 本课题的研究方法本课题由两大
7、模块构成,分别为DLL模块和EXE模块。首先利用Winsock 2 SPI技术建立winsock钩子用来截获winsock调用从而拦截TCP/IP封包,并做相应处理。然后设置控管规则访问控制,通过控管规则的检查认证,确定socket连接是否允许通过。最后是TCP/IP的封包分析,利用TIP/IP的封包结构分析截获的数据,提取需要的数据。这些封装在DLL里面。EXE模块主要是用户页面的制作。这里介绍与DLL通信的地方。EXE中与DLL直接通信的小模块主要有两个。一个是完成应用程序初始化的类CPropertyApp,它继承自CWinApp,是EXE的入口,其实里面封装了WinMain函数;另一个是
8、主窗口模块CMainFrame,这个主窗口并不是EXE显示出来的那个属性页窗口,而是一个隐藏的窗口,它继承自CMrameWnd,是一个无模式窗口,他隐藏显示,充当接受机,用来接受DLL及其他模块发送过来的消息,然后对消息进行相应的处理。2每一个连网的程序连网之前都会建立一个Socket连接。这时钩子程序就会起作用,把截获的底层服务进行“过滤”。及先调用自定义的函数再转给下层服务提供者函数。我就是在这一层实现封包过滤的。把规则与功能写到这一层。这一层的实现是本课题的核心。3第二章 WINSOCK 2 SPI编程技术Winsock 2是Windows Sockets的2.0版本,在此之前的版本是1
9、.1。与1.1版本相比,2.0版本引入了一种新的叫做SPI的编程接口。利用这种技术可以在Socket中插入一曾层,从而可以完成诸如扩展TCP/IP协议栈,网络安全控制等功能,所以这是一个非常强大而且有用的接口,下面介绍这种编程技术。42.1 Winsock 2 SPI基础Winsock是为上层应用程序提供的一种标准网络接口,上层应用程序不用关心Winsock实现的细节,它为上层应用程序提供透明的服务。Winsock 2 引入的一个新的功能就是打破服务提供者的透明,让开发者可以编写自己的服务提供者接口程序,即SPI程序。SPI以动态链接库的形式存在,它工作在应用层,为上层API调用接口函数。Wi
10、nsock 2是一个接口,不是一个协议。作为接口,它只能发现和利用底层传输协议完成通信。5自己编写的SPI程序安装到系统之后,所有的Winsock请求都会发送到这个程序并由它完成网络调用。由于系统提供的SPI已经可以完成网络传输功能,所以自己编写的SPI没有必要重新编写这部分功能。一般可以直接调用系统函数完成网络传输,这样工作的效果就是“钩子程序”。Winsock 2 SPI除了有完成网络传输的传输服务提供者,还有提供友好名称服务的名字空间服务提供者。传输服务提供者能够提供建立通信、传输数据、流量控制和错误控制等服务。名字空间服务提供者把一个网络协议的地址属性和一个或多个用户友好名称关联起来,
11、这样可以起用与协议无关的名字解析方案。62.2 传输服务提供者传输服务提供者又分为基础服务提供者和分层服务提供者。基础服务提供者和分层服务提供者都开放相同的SPI接口,所不同的是基础服务提供者位于提供者的最底层。所以编写基础服务提供者和分层服务提供者基本相同。但安装是却需要将基础服务提供者安装在服务提供者加载顺序链的最底端,而分层服务提供者则根据需要分布在顺序链的中间。第三章 开发平台与开发工具开发平台如题说明,以Windows平台为主,重点讨论开发工具的选择。根据不同的工程选择不同的开发工具,可以有效地提高工作效率。不同的开发工具各有各的优点同时又各有各的不足,在开发中要扬长避短。目前常用的
12、Windows开发工具有VS 5.0/6.0、VS.net(包括VB、BC、VFP、VJ、C#等一组开发工具)、delphi、C+ Builder,JBuilder、PB等。在这些开发工具里面,VFP和PB一般用来专门开发数据库系统,它们具有灵活的数据库接口。VB和Delphi既可以方便地做出复杂的数据库管理系统,又能轻松地完成操作系统级的任务。最优秀的是很容易做出漂亮的界面。VC和Borland C+着重于系统编程,它们开放接口较多,也最为灵活,而且编译出的程序体积较小,所以比较适合做系统工具类软件。缺点是短时间不容易掌握。其中Borland 使用的VCL类库是为Delphi准备的,并不是真
13、正用C+实现的。7VJ、Jbuilder和Java语言主要面向互联网应用。最大的优势是跨平台。本课题为防火墙软件,较多的使用系统接口,而且界面简单。另外,防火墙主要传播渠道是互联网,这就要求体积应尽量的小,安装尽量方便。所以选择VC为开发工具。第四章 系统设计与模块划分4.1本课题要实现的具体功能本设计实现的具体功能如下:1. 封包监视(1) 提供封包监视页面。(2) 提供清空监视列表,停止/开始监视及停止/开始滚动功能。2. 控管规则设置(1) 手工添加,删除及修改控管规则。(2) 自学习添加控管规则。(3) 控管规则中目的网络IP地址段的设置。(4) 提供控管规则设置页面。3. 封包过滤(
14、1) DLL给出设置工作模式和设置控管规则的接口函数。工作模式分为3种形式:放行所有,拒绝所有和过滤。(2) DLL根据工作模式和控管规则对过往封包进行过滤。(3) DLL将通过的网络封包通知EXE取走 。64.2程序工作流程图Winsock 2 SPI是一个DLL程序,它工作在API和DRIVER之间,为上层应用程序提供服务。EXE与DLL构成软件的主题,也是编写软件的主要工作。流程图如图4.1所示。9图4.1防火墙工作流程图4.3模块划分4.3.1模块划分原则模块划分是系统分析中非常重要的一部分,下面是模块划分时的基本原则。1. 独立性:让模块直接内的关系减到最少。理想的状态就是模块之间没
15、有关系,但这种情况不符合现实。既然是同一个工程,模块之间自然都会存在一定的联系,只要想办法让模块之间的关系尽量简单就可以了。2. 接口简单化:让模块之间的接口尽量单纯、简单、易用。即让公用函数和公用变量尽量地少。3. 分层处理:吸取Windows操作系统对模块做分层处理的经验。建立一些中间模块,让两端的模块来完成相互调用的透明化。4. 容易合并:容易将划分的模块进行合并。例如将一个工程的各个功能模块分别设计成可执行文件,然后用一个总模块将这些模块关联起来组成一个工程。这种情况下,对模块独立性要求较高,模块之间几乎没有任何关系。5. 可测试性:尽量使每个模块都可以单独进行测试10。上面的5条是参
16、考原则,既然是参考原则就不会完全执行,完全按照一个教条去执行真的很困难。只要在做模块划分的时候能经常记起这些原则,然后稍加注意就OK了。另外,在这5条原则中,第一条是根本,能把这一条做好,下面的一些就容易实现了。在做模块划分时一定要始终贯穿独立性的思想。4.3.2模块结构根据4.1节的功能定义和4.2节的工作流程图,需要对模块做进一步细化,得出更详细的模块结构。这些模块结构是编程的蓝本,在编写代码的过程中,就要以这些结构为指导。111. 模块1.1:用户界面,4.5节详细说明。2. 模块1.2:EXE的安装模块,。建立CXInstall类,C+源文件Install.h和Install.cpp。
17、安装函数InstallProvider和卸载函数RemoveProvider3. 模块1.3:EXE读写控管规则模块,建立CAclFile类,C+源文件File.h和File.cpp。读控管规则文件ReadAcl,保存控管规则文件SaveAcl,增加一条控管规则AddAcl和删除一条控管规则DelAcl。4. 模块1.4:EXE设置DLL的控管规则模块,设置控管规则单独的函数,调用模块1.3读写控管规则模块得到控管规则数据,调用DLL的函数FloControl设置DLL的控管规则。5. 模块1.5:EXE设置DLL的工作模式,设置工作模式单独的函数,调用模块1.3读写控管规则模块得到控管规则数
18、据,调用DLL的函数FloControl设置DLL的工作模式。6. 模块2.1:DLL封包过滤模块,有分为3块,2.1.1一组Winsock 2SPI钩子函数C+源文件TcpipDog.h和TcpipDog.cpp;模块2.1.2根据控管规则判断是否可以通行的类CCheckAcl,C+源文件CheckAcl.h和CheckAcl.cpp;模块2.1.3对网络数据包进行分析的类CProtocolInfo,C+源文件ProtocolInfo.h和ProtocolInfo.cpp。l 模块2.1.1:服务提供者函数模块,入口函数WSPSartup,发送询问消息到EXE,由EXE提供询问界面函数Que
19、ryAccess。截获的8个服务提供者函数。设置工作模式、控管规则等设备工作接口函数FloControl。l 模块2.1.2:访问控管模块,通过检查工作模式和控管规则得到是否放行的函数GerAccessInfo。l 模块2.1.3:协议解析模块,得到协议信息处理函数GetProtocolInfo 7. 模块2.2:DLL更改控管规则模块,设置DLL控管规则数据SetAcl,设置控管规则m_Aclfile,设置工作模式m_iWorkMode。8. 模块2.3:DLL更改工作模式模块,设置DLL工作模式函数SetWorkMode。4.3.3模块接口定义模块之间接口有3种方式:1. 函数接口函数接口
20、是最常用而且独立性和封装性最好的接口方式。函数之间通过参数传递进行模块之间的通信,处理过程保持相互独立,函数处理完成把处理结果返回到调用模块。如果每个函数都有单独的接口,那么,函数多了,接口也就多了,也就越来越复杂了。C+利用类的饿概念解决这个问题。类可以将一组函数和变量封装起来,这样就将许许多多的函数转化成一个对象的形式。外部模块使用这个类的实例来引用封装在里面的成员函数个变量。把功能相似、相关的函数分成一组,然后封装在一起,使接口间的关系清晰了很多。类的成员函数和成员变量有公有和私有之分。对于公有函数和变量,外部模块可以直接调用;对于私有函数和变量,外部模块则不能直接调用。利用这种特性,可
21、以把一些只在类里面使用的函数定义为私有函数;把外部模块需要直接调用的函数定义为公有函数。类似于DLL的导出函数(Export),这样,模块之间的直接接触就会进一步减小,独立性更进一步增加。2. 全局变量接口全局变量接口是一种不提倡的方式。虽然它使用起来确实很过瘾。全局变量多了非常容易出问题。任何地方都可能会对全局变量进行赋值,变量的可控性大大降低,不知道什么时候变量的值就被莫名其妙地改掉了。当然,只要不被那些模块执行的先后顺序和循环语句弄昏头,还是可以使用全局变量的。虽然不提倡使用,但是有些地方使用全局变量与是不可避免的,而且有时候可以减少很多麻烦。使用全局变量的时候需要注意一点,读取变量的多
22、少和位置对程序稳定性的影响并不很大,关键是尽量让赋值的地方单一,改变变量的次数和位置应尽量得到控制。3. Windows消息接口Windows消息接口是一种特殊的接口形式,它是基于Windows操作系统的消息机制。这种接口形式适合于应用程序之间。应用程序是相对独立的模块,如果这两个模块需要通信,则消息接口就是一种理想型的选择。这种接口类似于函数接口,只不过通过操作系统的消息机制来中转一下。Windows消息接口也是一种接口方式,特别是DLL和EXE之间经常用到。在DLL与EXE之间通信使用消息是一种优势,多个应用程序虽然调用同一个DLL,但是它们都拥有独立的模块副本。这时候如果这些模块副本都需
23、要让同一个应用程序做一件事时,就不好处理,因为DLL的重要性和应用程序保护机制导致这些模块副本无法直接调用同一个应用程序的执行模块。这时候就可以通过消息的方式来解决。发送消息是基于窗口句柄的,只要得到这个窗口句柄,不同的DLL副本都向同一个窗口句柄发送消息,自然所有的消息都可以被同一个应用程序接收。以上3种接口方式以函数接口为优先进行考虑,以增强模块的独立性和可读性。4.4编码规则变量命名规则如下: 变量采用代表中文意思的英文单词或单词组合。 变量一般不用缩写,用英文单词全称。较长的更为习惯的缩写。 自定义全局变量用m_开头。 自定义过程变量不用m_开头。 变量的前缀用变量类型的第一个字母标志
24、变量类型。如,指针类型在前面多加一个字母P。 如果是对象,前缀用对象的名称,第一个字母大写。 变量中有多个单词时,单词的第一个字母大写,其余用小写。有了自己的编码规则后,不会出现自己的弄不清楚自己定义的函数之类的是什么意思。不知道函数是干什么的。以至于思维混乱。4.5控管规则文件结构设计控管规则文件用来存储控管规则数据,命名为acl.cfg;该数据文件为二进制文件。4.5.1控管规则文件需要存储的内容控管规则文件需要存储的内容如下:(1) 系统设置(2) 控管设置(3) 控管规则附加数据,授权访问的远端网络IP地址记录1. 控管规则记录结构控管规则记录结构说明(1) 规则编号字段是控管规则的唯
25、一性编号。保留字段,没有使用。(2) 应用程序名称及路径字段用来保持应用程序的名称和路径。(3) 远端网络类型,数值的含义如下。0:表示所有网络1:局域网2:约束的网络(自定义)3:信任的网络(自定义)4:自定义的网络(自定义)(4) 管制动作,数值的含义如下。0:放行1:拒绝(5) 进出方向,数值的含义如下。0:出1:入2:双向(6) 服务类型,数值的含义如下。0:全部1:TCP(端口为任意,可编辑)2:UDP(端口为任意,可编辑)3:FTP(端口为21,不可编辑)4:TELNET(端口为23,不可编辑)5:HTTP(端口为任意,可编辑)6:NNTP(端口为119,不可编辑)7:POP3(端
26、口为110,不可编辑)8:SMTP(端口为25,不可编辑)(7) 服务端口,数值的含义如下。0:表示全部其他值:表示端口值2. 授权访问的远端IP地址记录结构授权访问的远端网络IP地址结构如表4.1所示。表4.1 授权访问的远端网络IP地址段记录结构 字段 类型 长度 开始IP 无符号长整型 4 结束IP无符号长整型 44.5.2控管规则文件结构根据需要存储的内容将控管规则文件划分为3段。文件头用来存储系统设置,IP地址范围记录和控管规则记录的地址偏移量及其他信息;IP地址范围记录存储区用来存储IP地址范围记录;控管规则记录存储区用来存储控管规则记录。1. 控管规则结构控管规则结构如表4.2所
27、示。表4.2 控管规则记录结构表08162432404856控管规则编号应用程序路径和名称远端网络动作方向服务类型端口2. IP地址结构IP地址段记录结构如表4.3所示。表4.3 IP地址段记录结构表08162432404856开始IP地址结束IP地址开始IP地址结束IP地址4.6界面设计4.6.1制定界面风格界面上反映的功能有:封包监视、控管规则设置。这是两个平行的功能,所以选用Windows的属性页。4.6.2界面设计文档界面设计如下所示。1. 封包监视界面封包监视界面用来显示截获的网络封包。每个网络封包的具体内容根据实际需要而定。如图4.2。图4.2 封包监视界面封包的字段有:(1) 应
28、用程序路径和名称(2) 管制动作(放行或拒绝)(3) 访问起始/结束时间(4) 使用网络协议(5) 进/出流量(6) 本地和远端IP地址/端口(7) 备注信息封包监视界面实时接收DLL发送过来的网络封包并立刻显示。在封包监视界面上设计了几个附加按钮。“停止/开始滚动”用来设置监视列表是否自动滚动;“开始/停止监视”用来设置是否实时监视;“清除”按钮用来清除当前列表。这些功能按钮方面操作。 2. 控管规则界面控管规则界面用来显示和设置控管规则(如图4.3)。需要说明的是,应用程序设置的优先级高于控管规则设置,只是在应用程序设置为询问时,下面的控管规则设置才有效。图4.3 控管规则界面控管规则的设
29、计目的是为了制订对网络访问的控制,所以控管规则的字段可以决定防火墙防范的严密性和灵活程度。控管规则的记录结构为:l 应用程序l 远端网络l 管制动作l 进出方向l 协议类型l 使用端口控管规则界面给出了“增加”、“删除”、“修改”3个功能按钮用来对控管规则进行不同的操作。其中选择增加和修改时都会弹出控管规则设置界面。1. 控管规则设置界面控管规则设置界面是用来设置控管规则的各个字段(如图4.4)。在“应用程序”栏输入或选择要进行控管的应用程序的完整路径和文件名。“远端网络”用IP地址范围表示,用来定义网络类型的IP地址范围。本软件工划分为5个类型:所有网络、局域网、受约束的网络、信任的网络和自
30、定义网络。12“动作”用来确定符合这一条控管规则的网络访问动作是放行还是拒绝。“方向”用来确定这一条控管规则适合于网络访问的连接方向。本机向远端服务器发出连接请求就是出;远端主机向本机发出连接请求则为进。“类型”是控管规则约定的协议类型。“端口”是协议所使用的端口。图4.4 控管规则设置界面2. 网络设置界面网络设置界面用来对各种网络类型的IP地址段进行设置(如图4.5),在上节有关于远端网络类型的介绍。在这个界面上提供对IP地址段的增加、修改和删除功能图4.5 网络设置界面第五章 核心功能的代码实现本课题的核心功能实现封装在DLL里面。下面分析DLL的主要内容。5.1 DLL的封包截获BOO
31、L WINAPI DllMain是DLL的入口函数,系统调用时的标准接口。做一些初始化工作。主要工作是得到调用这个程序的进程路径和名称并设置DLL调用次数的计数器。WSPStartup是Windows Sockets应用程序调用SPI的初始化函数。是服务提供者的标准入口函数。这里的工作是根据lpProtocolInfo找出已经被替换的服务提供者路径,然后加载,并利用被替换服务提供者的WSPStartup得到30个服务函数指针。需要先保存这些函数指针,然后将lpProcTable结构中的30个服务函数指针都设置成自己的。这样,相应的函数请求会首先经过我们自己的函数,然后用这些函数可以做适当的处理
32、,再调用原来的,将请求转发,完成整个通信。12int WSPAPI WSPStartup(WORDwVersionRequested,LPWSPDATAlpWSPData,LPWSAPROTOCOL_INFOWlpProtocolInfo,WSPUPCALLTABLEupcallTable,LPWSPPROC_TABLElpProcTable)ODS(_T(WSPStartup.);if(!m_CheckAcl.m_bIsWin9x & m_CheckAcl.CheckStartup() = XF_QUERY & !QueryAccess()return SOCKET_ERROR;TCHARs
33、LibraryPath512; LPWSPSTARTUP WSPStartupFunc = NULL;HMODULEhLibraryHandle= NULL; INT ErrorCode = 0; if(!GetHookProvider(lpProtocolInfo,sLibraryPath)| (hLibraryHandle =LoadLibrary(sLibraryPath)=NULL|(WSPStartupFunc=(LPWSPSTARTUP)GetProcAddress(hLibraryHandle, WSPStartup) = NULL)return WSAEPROVIDERFAIL
34、EDINIT;if(ErrorCode=WSPStartupFunc(wVersionRequested,lpWSPData,lpProtocolInfo, upcallTable, lpProcTable) != ERROR_SUCCESS)return ErrorCode; if( !lpProcTable-lpWSPAccept |!lpProcTable-lpWSPAddressToString |!lpProcTable-lpWSPAsyncSelect |!lpProcTable-lpWSPBind |!lpProcTable-lpWSPCancelBlockingCall | !
35、lpProcTable-lpWSPCleanup |!lpProcTable-lpWSPCloseSocket |!lpProcTable-lpWSPConnect |!lpProcTable-lpWSPDuplicateSocket |!lpProcTable-lpWSPEnumNetworkEvents |!lpProcTable-lpWSPEventSelect |!lpProcTable-lpWSPGetOverlappedResult |!lpProcTable-lpWSPGetPeerName |!lpProcTable-lpWSPGetSockName |!lpProcTable
36、-lpWSPGetSockOpt |!lpProcTable-lpWSPGetQOSByName |!lpProcTable-lpWSPIoctl |!lpProcTable-lpWSPJoinLeaf |!lpProcTable-lpWSPListen | !lpProcTable-lpWSPRecv |!lpProcTable-lpWSPRecvDisconnect |!lpProcTable-lpWSPRecvFrom |!lpProcTable-lpWSPSelect |!lpProcTable-lpWSPSend |!lpProcTable-lpWSPSendDisconnect |
37、!lpProcTable-lpWSPSendTo |!lpProcTable-lpWSPSetSockOpt |!lpProcTable-lpWSPShutdown |!lpProcTable-lpWSPSocket |!lpProcTable-lpWSPStringToAddress )return WSAEINVALIDPROCTABLE;EnterCriticalSection(&gCriticalSection);NextProcTable = *lpProcTable;lpProcTable-lpWSPSocket= WSPSocket;lpProcTable-lpWSPCloseS
38、ocket= WSPCloseSocket;lpProcTable-lpWSPConnect= WSPConnect;lpProcTable-lpWSPAccept= WSPAccept;lpProcTable-lpWSPSend= WSPSend;lpProcTable-lpWSPSendTo= WSPSendTo;lpProcTable-lpWSPRecv= WSPRecv;lpProcTable-lpWSPRecvFrom= WSPRecvFrom;/以上是我们截获并要用自己定义的函数。LeaveCriticalSection(&gCriticalSection);return 0;Xf
39、IoControl是供EXE调用的。用来设置DLL的配置信息和得到DLL的反馈信息,这个函数为EXE提供接口,EXE通过这个函数来设置工作模式,或得到截获的网络封包信息。QueryAccess是在应用程序提交连网请求时,如果发现控管规则中没有关于这个应用程序的控管规则,并且工作模式为询问,则向拥护发出询问,是否让这个程序通行。GetHookProvider用来读取注册表得到系统的SPI的DLL路径和文件信息。这个信息是安装时自己写入的。根据pProtocolInfo信息取出自己保存的、已经被本程序替换的服务提供者路径。GetRightEntryIdItem是供GetHookProvider()
40、调用的扩展函数,用来得到保存系统服务提供者路径的注册表键名。及得到已经被本程序替换的服务提供者的dwCatalogEntryId。XfShutdown调用系统服务提供者函数WSPShutdown,关闭一个Socket连接。并设置相应的错误代码。截获的服务提供者函数:过滤WSPSocket。WSPSocket是用来创建Socket的函数,首先调用底层函数得到新创建的Socket,然后设置新建Socket的协议信息,并调用自定义函数CheckSocket为这个Socket建立Session,然后保存相应的信息。过滤WSPCloseSocket。转发之前首先调用自定义函数CheckCloseSock
41、et删除相应的Session。过滤WSPConnect。当一个Socket建立连接后调用这个函数,转发之前先调用访问控制函数CheckConnect,检查是否放行。如果不放行,返回错误;如果放行,调用底层WSPConnect函数进行转发。过滤WSPAccept。用来接受一个连接请求。首先调用底层函数,然后对连接的合法性进行检查,如果不允许通过,关闭这个连接。过滤WSPSend。这个函数用来发送面向连接的数据,先检查是否允许通过,然后进行转发。过滤WSPSendTo。这个函数用来发送面向无连接的数据,先检查是否允许通过,然后进行转发。过滤WSPRecv。这个函数用来接收面向连接的数据。首先判断是
42、不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。过滤WSPRecvFrom。这个函数用来接收面向连接的数据。首先判断是不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。5.2 DLL的访问控管编写一个CCheckAcl。它封装了一组对访问权限
43、进行控制的函数。访问权限主要是由控管规则设置决定。另外还封装了一组网络封包操作函数。下面是一些主要函数及相应代码。5.2.1对服务提供者函数做管制的函数CheckStartup:应用程序连网前的访问控制权限。在服务提供者函数WSPStartup中对访问权限进行控制。WSPStartup是Winsock 2 SPI入口函数,每个应用程序连网时调用且仅调用一次这个函数。CheckSocket:检查WSPSocket函数,Socket用来创建Socket,在Socket创建时没有必要进行控管,所以仅仅用来创建Session并保存协议信息。CheckCloseSocket:WSPCloseSocket
44、函数的预处理函数,用来删除相应的Session。CheckConnet:检查连接是否合法。在服务提供者函数WSPConnet调用系统WSPConnet函数建立之前,用CheckConnet调用SetSession填充一些网络封包信息,然后调用GetAccessInfo判断这个连接是否被允许通过。CheckAccept:检查是否允许接受这个Socket连接。在服务提供者函数WSPAccept调用系统函数WSPAccept接受一个Socket连接后,用CheckAccept调用SetSession设置网络封包信息,然后调用GetAccessInfo检查这个Socket连接是否允许通过。CheckS
45、end:在发送面向连接的数据前检查是否放行。在服务提供者函数WSPSend调用系统函数WSPSend发送数据前,用CheckSend调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个发送操作通过。CheckSendTo:在发送面向连接的数据前检查是否放行。在服务提供者函数WSPSendTo调用系统函数WSPSendTo发送数据前,用CheckSendTo调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个发送操作通过。CheckRecv:在接收面向连接的数据时检查是否放行。