过河的卒子

我们都是过了河的卒子,不能回头!!!
关于spi滤包技术的研究

最近我对spi滤包技术(就是防火墙基于用户级的滤包)做了一番研究,也自己编程进行了实现,到现在,也算是有些心得了吧。因此,写出这篇算是总结也算是心得的东西拿出来和大家分享,希望对大家有用。在进入正题之前,我先要感谢那些无私共享出自己研究成果的前辈们,尤其是safechina的TOo2y,他的文章《基于SPI的数据报过滤原理与实现》可以说是我研究spi滤包技术的良师,说得不好听,我这个源代码实际上就是他那篇源代码的翻版。
    说到spi滤包,首先要了解一下winsock2 spi。spi中文名叫服务提供者接口。winsock2 spi允许开发两种服务提供者:传输提供者和名字空间提供者,在这里我们要用到的是传输提供者。winsock2 spi与winsock2 api相对应,分别在winsock的两端。它们的具体结构如下图:
-------------------------------------
|Windows socket 2 应用程序|
-----------------------------------------Windows socket 2 API
|       WS2_32.DLL        |
---------------------------------------- Windows socket 2 SPI
| 分层提供者 |
-------------------SPI
| 分层提供者 |
----------------------------------- SPI
|      基础提供者       |
-----------------------------------

    对于大部分winsock2 api函数,都对应一个winsock2 spi函数。调用这些winsock2 api函数时,ws2_32.dll会将其映射到一个winsock2 spi函数然后执行,以实现我们的正常通信(如WSASend映射到WSPSend)。而这些spi函数,在需要时以加载dll的形式进入内存。所以,每一个服务提供者就对应一个dll,在需要该服务提供者时,ws2_32.dll就会加载其对应的dll。但是,由上图可以看出来,传输服务提供者可以不止一个(事实上一个系统中的服务提供者都不会只有一个),允许存在多层的服务提供者,那么,我们在实现通信应用程序时,会加载哪一个服务提供者的dll呢?这就是ws2_32.dll的工作了。winsock 2有一个系统配置表,里面存放着系统中所有传输服务提供者的信息。在应用程序建立套接字时,ws2_32.dll在这个winsock 2系统配置表中按顺序搜索第一个与套接字相匹配的传输服务提供者,然后加载此提供者对应的dll。
    以上就是应用服务提供者的基本原理了,但是我们现在是要滤包,究竟应该怎么去实现呢?其实,只要我们能自己构建一个服务提供者,然后把它放到所有服务提供者的顶端,那么,ws2_32.dll在需要时就会加载我们自己的服务提供者,就会加载我们自己打造的dll,那么,我们只要在我们自己的这个dll里面实现滤包就行了。但是,具体应该怎么做呢?还是让我们先回到上图吧。从图中可以看出,服务提供者可以是分层的。比如,我们现在加载的是第一层的服务提供者的dll,在这个dll中,有一个唯一的入口函数是WSPStartup,这个函数与api WSAStartup相对应,其函数原型如下:
int WSPAPI WSPStartup(WORD  wversionrequested,
        LPWSPDATA  lpwspdata,
        LPWSAPROTOCOL_INFOW  lpprotoinfo,
        WSPUPCALLTABLE  upcalltable,
        LPWSPPROC_TABLE  lpproctable);
前面说了,这个函数是传输服务提供者的唯一的入口函数,而其他的与api相对应的spi函数是由参数lpproctable给出的。lpproctable是一个指针,指向一个结构,而这个结构中就存放着另外那些spi函数的指针。好了,回到原题,假设我们现在加载第一层服务提供者的dll,那么,当应用程序调用api比如WSASend时,就会通过WSPStartup函数的lpproctable参数,寻找spi函数WSPSend然后执行。一般情况下,在这一层spi的WSPSend函数中,在执行其特定操作之后,就会调用下一层服务提供者的WSPSend函数,实现往下一层的传递(这要通过加载下一层spi的dll,找到它的WSPStartup函数来实现)。这就是正常的通信。现在,我们是要滤包,那么,只要我们在这一层的WSPSend函数中不调用下一层的WSPSend不就行了?正确!这就是我这个spi滤包的思路了。
    下面给出源代码,包括安装部分和dll部分,欢迎大家批评。

1.安装部分

Code

        
文章写的粗浅,望大家见谅。如果大家有什么不明白,请参看TOo2y的《基于SPI的数据报过滤原理与实现》以及《windows网络编程技术》第14章 winsock 2 服务提供者接口。

posted on 2008-12-14 15:08  过河的卒子  阅读(587)  评论(0)    收藏  举报