nt网络过滤(5)--TDI过滤驱动
前言
从本篇开始,将来聊一下网络过滤驱动。
网络分层模型
在谈这个之前,要简单介绍一下网络分层模型。
常见的有 4,5,7层模型。
在4层模型中,将数据链路层和物理层合并为了网络接口层。
一份数据要经由网络传递时,该数据会逐层包装成相应的协议格式提供给各方使用,在到达后又会逐层解包。
之所以会这么做,是为了满足不同需求(有时候需要保证数据正确到达,有时不需要等等各类情况),归根揭底的原因是网络硬件设备并不可靠,传输速度并不够快,所以需要协议来弥补这些缺陷,可以简单认为是硬件不够完美。
其间每一层都肩负着各自的任务,用 c++
的话说,它们是继承关系,下面是父类上面是子类,一顺继承下去,各自又包含各自的方法和属性。
具体可配合RFC手册
,在 wireshark
中抓一个包来查看,本文只是为了建立这样一种概念。
TDI在哪?
本文所讲的 TDI
全称为 Transport Driver Interface
,位于网络模型中的传输层,其分为3个部分,分别是 TDI客户驱动,TDI接口,以及TDI传输驱动。
TDI接口是在联系TDI客户驱动和TDI传输驱动时所构建的一套函数,数据及宏定义。
- AFD.sys,NETBT.sys 和 Http.sys都是TDI 客户驱动。
- TCPIP.sys,NWLINK.sys和TCPIP6.sys都是TDI传输驱动。
- TDI.sys 一般视为为 TDI 接口驱动。
虽然TDI客户驱动一般在TDI传输驱动上层,但也有些TDI客户驱动在网络栈中逻辑上是和TDI传输驱动在同一层甚至在TDI传输驱动下层。
另外由于TDI层较为接近应用层,在TDI层过滤更为容易获得应用程序相关信息。
TDI相关驱动开发
在做TDI相关开发时,一般分为以下两类
- 调用 TDI 接口,在内核模式下进行网络编程
- 针对指定传输层协议做网络流量过滤
自 Windows Vista
起,微软为以上两大用途都提供了新的解决方案。
本文要说明的内容便是 针对指定传输层协议做网络流量过滤 这一种使用方式。
TCP过滤–附加设备
要过滤 “TCP” 协议数据,需要附加到 \Device\TCP
所处的设备栈。
其在 Windows Vista
之前由 “tcpip.sys” 创建,
而之后的版本中则由 “tdx.sys” 创建。TDX
是微软提供的一种妥协方案,旨在为旧TDI驱动提供兼容。
笔者的电脑使用的win10
,可以看到此时该设备由 tdx
创建。
当然这些都不是重点,在附加的时候并不需要这个设备由哪个驱动创建。
既然是传统过滤驱动,要做的事情也很简单
- 打开目标设备
- 创建过滤设备附加到目标设备的设备栈
具体可以参考开源项目 tdifw
。
TCP过滤–IRP请求
由于这类驱动中除了过滤用的设备,还有驱动本身和应用层通信的设备,所以要在派遣函数中分别处理。
通常比较关注的是 MajorFunction
IRP_MJ_INTERNAL_DEVICE_CONTROL
的请求,
其 MinorFunction
包含
TDI_ACCEPT
TDI_LISTEN
TDI_CONNECT
TDI_SEND
TDI_RECEIVE
TDI_DISCONNECT
…
可以过滤诸如 连接,收发等操作。
在 IrpSp->Parameters 中存放着一个相关联的结构,通过该结构就能进一步提取信息,以此决定接下来的操作(例如禁止目标访问网络等),
可以挂起这个请求,也可以完成掉,又或者是继续下发,这点根据实际需求判断即可,在写法上,和其他传统过滤驱动并无太大的区别。
具体的操作说明可到MSDN
中查看。
最后值得注意的是
过滤驱动最好不要卸载,不然很容易BSOD,这是由于无法判断(或者很难判断)是否还存在某线程在执行当前驱动的派遣函数
总结
本文概括TDI过滤驱动的基础实现及相关知识。