以我们通过适当的增加自己的分层协议服务提供者,使其位于SPI的顶端,那么就能将W
s2_32.dll传给服务提供者的数据报拦截下来。由于是MS的官方方法,具体的使用方法在
其Platform SDK里面有详细的例子(LSP),在MSDN里面也有详细的解释。这种方法的优点
是能够获得调用Winsock的进程的详细信息,并能实现Qos和数据加密。所以SPI是用户态
数据拦截的较好地点。缺点同1。
4、Windows2000包过滤接口。由于过滤规则限制太多不灵活而应用不多。
5、网络监视器SDK。MS官方的实时监视分析网络数据的方法。但是由于封装的太复?
樱?
使用起来不灵活。
在核心态下,数据报的监视和拦截方法比较复杂,由于大多个人防火墙都是在核心?
?
实现的,所以在这里比较详细的叙述一下。具体的请参见nt/2kDDK文档。大概有下面几
个方法。
1、 TDI过滤驱动程序(TDI Filter Driver)。
2、 NDIS中间层驱动程序(NDIS Intermediate Driver)。编写IM DRIVER在NDIS中间层
对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进行拦截。这是微软提供的
一种技术。在DDK中MS提供了Passthru例子,很多中间层过滤驱动都可以由之改编。但编
写该过滤程序拦截程序非常的复杂,安装也很麻烦。
3、 Win2k Filter-Hook Driver。
4、 NDIS Hook Driver。这种方法又有两种实现方式。
(1)向NDIS注册假协议(fake protocol)。这是在协议层上的处理。在Windows内核中
,所有已注册的协议是通过一个单向的协议链表来维护的。这个单向链表保存了所有已
注册协议的NDIS_PROTOCOL_BLOCK结构的地址,在这个结构中保存了协议驱动所指定的相
应的派发函数的地址如RECEIVE_HANDLER等。
struct _NDIS_PROTOCOL_BLOCK
{
PNDIS_OPEN_BLOCK OpenQueue; // queue of opens for this protocol
REFERENCE Ref; // contains spinlock for OpenQueue
UINT Length; // of this NDIS_PROTOCOL_BLOCK struct
NDIS50_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics;// handler addresses
struct _NDIS_PROTOCOL_BLOCK * NextProtocol; // Link to next
ULONG MaxPatternSize;
#if defined(NDIS_WRAPPER)
//
// Protocol filters
//
struct _NDIS_PROTOCOL_FILTER * ProtocolFilter[NdisMediumMax+1];
WORK_QUEUE_ITEM WorkItem; // Used during NdisRegisterProtocol to
// notify protocols of existing drivers.
KMUTEX Mutex; // For serialization of Bind/Unbind requests
PKEVENT DeregEvent; // Used by NdisDeregisterProtocol
#endif
};
typedef struct _NDIS_PROTOCOL_BLOCK NDIS_PROTOCOL_BLOCK, *PNDIS_PROTOCOL_BLO
CK;并且,每个协议驱动还对应一个NDIS_OPEN_BLOCK的单向链表来维护其所绑定的网卡
信息。当协议驱动调用NdisRegisterProtocol之后,
EXPORT
VOID
NdisRegisterProtocol(
OUT PNDIS_STATUS Status,
OUT PNDIS_PROTOCOL_BLOCK NdisProtocolHandle, /*注意NDIS_HANDLE所指向的就是PN
DIS_PROTOCOL_BLOCK的结构,不要有什么怀疑。*/
IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,
IN UINT CharacteristicsLength
);
NDIS总是会把新注册的协议放在协议链表的表头并返回这张表,所以只要我们注册一个
新的协议通过新协议注册返回的链表头就可以轻而易举的遍历系统中所有协议表。但是
,如果要成功地挂接派发函数,还需要对协议所对应的NDIS_OPEN_BLOCK结构里的派发函
数进行挂接,因为NDIS并不是直接调用协议驱动在NDIS_PROTOCOL_CHARACTERISTICS所