TDI 过滤~
一、与TDI过滤有关的东西。。收发数据那块先从略了。。
TCP怎么填充头部,怎么保证发送的成功和顺序正确,那都是协议的东西了。。详见《TCP-IP详解》(17章开始是TCP)。协议的东西有空再看看~
TDI 过滤没什么难度,WDK详尽到罗嗦的程度,教程也很多了,简单mark一下
上文看到Winsock库函数和afd.sys几乎是一一对应的,有时是一对多。但afd并不是将所有的请求都下发。
Afd是功能辅助模块,面向的对象是endpoint。TCP/UDP 是传输层,负责给两端的两个应用程序传输数据,面向的对象是一个传输控制块 TCB。
FsContext统一是TCP_CONTEXT结构,FsContext2 表示这个文件对象具体代表什么(地址、连接、或者一个控制)
到了tcp层,提供的服务有(其中有一些可过滤的地方):
绑定
afd!AfdBind -> tcpip!TCPCreate
当EA中是TdiTransportAddress 时,表示是打开一个本地的地址对象,调用TdiOpenAddress。
TdiOpenAddress将分配一个正确的本地地址和端口,并创建一个地址对象(AddrObj),存放于tcpContext->Handle.AddressHandle。
为FileObject->FsContext填充一个 _TCP_CONTEXT结构,FsContext2设置为TDI_TRANSPORT_ADDRESS_FILE(代表这是一个地址对象)
过滤这里可以得到绑定的本地ip地址和端口号(在irp完成之后)。
连接
afd!AfdCreateConnection -> tcpip!TCPCreate
EA名字是TdiConnectionContext,表示是打开一个连接对象,调用TdiOpenConnection,
将创建一个TCPConn结构并分配一个connectID存放于tcpContext->Handle.ConnectionContext,FsContext2设置为TDI_CONNECTION_FILE(代表这是一个连接对象)
在楚狂人的教程中,这里的过滤操作是自己建表将文件对象和ConnectionContext相关联,毕竟TCP_CONTEXT结构不公开。
TDI_ASSOCIATE_ADDRESS
TdiAssociateAddress将地址对象AO存到连接对象中。
在这里可以得到链接地址。
TDI_CONNECT
正式建立连接了。得到链接地址很容易。
TdiConnect
这里开始出现一个传输层的重要结构 传输控制块TCB 记录了一个传输的所有信息 地位相当于进程管理器中的EPROCESS 。这里调用了InsertTCB将TCB放入了全局链表TCBTable。
这里初始化这个结构并且填充各种信息,最终调用SendSYN,即握手的第一步。返回TDI_PENDING。
监听和接受连接
TDI_SET_EVENT_HANDLER 中的 TDI_EVENT_CONNECT
设置一个回调来接受连接,替换之 可得到连接本机的事件
接受数据
TDI_EVENT_RECEIVE
TDI_EVENT_RECEIVE_DATAGRAM
TDI_EVENT_RECEIVE_EXPEDITED
拦截三个事件回调,回调是从中断一层一层解析并递交上来的。
TDI_ RECEIVE
TdiReceive来缓冲数据
发送数据
TDI_SEND
最终调用TdiSend 填充协议头部,调用LocalNetInfo.ipi_xmit发送数据了
还有UDP的TDI_SEND_DATAGRAM 和 TDI_RECEIVE_DATAGRAM
收发数据 可以做的工作 拒绝接受/过滤数据/统计流量 等等
360netmon 是一个很简单的TDI过滤驱动,实现的就是 实时统计了每个进程收发的数据流量,提供禁止某个进程收发数据的功能。不过里面有5、6个自定义结构,搞得我花了一点时间去猜都是什么。。。
附上IDB和 其DeviceIoCtrlInternal 的 还原代码(因为这个f5看起来不太方便~)IDB是5.5的,在localtype里定义了那些自定义结构~ IDB下载
二、连接的枚举
顺便说一下枚举系统内建立的连接,正常的就是用IPHELP API(netstat用的),
底层一点不过是用IOCTL_TCP_QUERY_INFORMATION_EX 曾经rootkits那本书中写过irp hook这里隐藏链接
XT也是发送了这个irp,至于更底层,其实没太大必要。定位TCBTable就比较麻烦,不过TCB这个结构。有了NT4的参考还是很好逆出来的。
XP下
#pragma pack(push, 1)
struct TCB
{
_BYTE f0[8];
_DWORD dword8;
_DWORD tcb_daddr;
_DWORD tcb_saddr;
_WORD tcb_dport;
_WORD tcb_sport;
_DWORD pid;
…….略去
NT4查连接属于哪个进程比较麻烦,TCB中好像不存储pid,但xp的版本就有这么一句:
TdiConnect:
TCB->pid = PsGetCurrentProcessId();
PS:迅雷的智能限速竟然都NDSI小端口了,真和谐啊,暂时还看不了。。。
PPS:利用第三方带签名的驱动的bug挺和谐。。。一些非安全厂商的驱动相当不安全。。
一、与TDI过滤有关的东西。。收发数据那块先从略了。。
TCP怎么填充头部,怎么保证发送的成功和顺序正确,那都是协议的东西了。。详见《TCP-IP详解》(17章开始是TCP)。协议的东西有空再看看~
TDI 过滤没什么难度,WDK详尽到罗嗦的程度,教程也很多了,简单mark一下
上文看到Winsock库函数和afd.sys几乎是一一对应的,有时是一对多。但afd并不是将所有的请求都下发。
Afd是功能辅助模块,面向的对象是endpoint。TCP/UDP 是传输层,负责给两端的两个应用程序传输数据,面向的对象是一个传输控制块 TCB。
FsContext统一是TCP_CONTEXT结构,FsContext2 表示这个文件对象具体代表什么(地址、连接、或者一个控制)
到了tcp层,提供的服务有(其中有一些可过滤的地方):
绑定
afd!AfdBind -> tcpip!TCPCreate
当EA中是TdiTransportAddress 时,表示是打开一个本地的地址对象,调用TdiOpenAddress。
TdiOpenAddress将分配一个正确的本地地址和端口,并创建一个地址对象(AddrObj),存放于tcpContext->Handle.AddressHandle。
为FileObject->FsContext填充一个 _TCP_CONTEXT结构,FsContext2设置为TDI_TRANSPORT_ADDRESS_FILE(代表这是一个地址对象)
过滤这里可以得到绑定的本地ip地址和端口号(在irp完成之后)。
连接
afd!AfdCreateConnection -> tcpip!TCPCreate
EA名字是TdiConnectionContext,表示是打开一个连接对象,调用TdiOpenConnection,
将创建一个TCPConn结构并分配一个connectID存放于tcpContext->Handle.ConnectionContext,FsContext2设置为TDI_CONNECTION_FILE(代表这是一个连接对象)
在楚狂人的教程中,这里的过滤操作是自己建表将文件对象和ConnectionContext相关联,毕竟TCP_CONTEXT结构不公开。
TDI_ASSOCIATE_ADDRESS
TdiAssociateAddress将地址对象AO存到连接对象中。
在这里可以得到链接地址。
TDI_CONNECT
正式建立连接了。得到链接地址很容易。
TdiConnect
这里开始出现一个传输层的重要结构 传输控制块TCB 记录了一个传输的所有信息 地位相当于进程管理器中的EPROCESS 。这里调用了InsertTCB将TCB放入了全局链表TCBTable。
这里初始化这个结构并且填充各种信息,最终调用SendSYN,即握手的第一步。返回TDI_PENDING。
监听和接受连接
TDI_SET_EVENT_HANDLER 中的 TDI_EVENT_CONNECT
设置一个回调来接受连接,替换之 可得到连接本机的事件
接受数据
TDI_EVENT_RECEIVE
TDI_EVENT_RECEIVE_DATAGRAM
TDI_EVENT_RECEIVE_EXPEDITED
拦截三个事件回调,回调是从中断一层一层解析并递交上来的。
TDI_ RECEIVE
TdiReceive来缓冲数据
发送数据
TDI_SEND
最终调用TdiSend 填充协议头部,调用LocalNetInfo.ipi_xmit发送数据了
还有UDP的TDI_SEND_DATAGRAM 和 TDI_RECEIVE_DATAGRAM
收发数据 可以做的工作 拒绝接受/过滤数据/统计流量 等等
360netmon 是一个很简单的TDI过滤驱动,实现的就是 实时统计了每个进程收发的数据流量,提供禁止某个进程收发数据的功能。不过里面有5、6个自定义结构,搞得我花了一点时间去猜都是什么。。。
附上IDB和 其DeviceIoCtrlInternal 的 还原代码(因为这个f5看起来不太方便~)IDB是5.5的,在localtype里定义了那些自定义结构~ IDB下载
二、连接的枚举
顺便说一下枚举系统内建立的连接,正常的就是用IPHELP API(netstat用的),
底层一点不过是用IOCTL_TCP_QUERY_INFORMATION_EX 曾经rootkits那本书中写过irp hook这里隐藏链接
XT也是发送了这个irp,至于更底层,其实没太大必要。定位TCBTable就比较麻烦,不过TCB这个结构。有了NT4的参考还是很好逆出来的。
XP下
#pragma pack(push, 1)
struct TCB
{
_BYTE f0[8];
_DWORD dword8;
_DWORD tcb_daddr;
_DWORD tcb_saddr;
_WORD tcb_dport;
_WORD tcb_sport;
_DWORD pid;
…….略去
NT4查连接属于哪个进程比较麻烦,TCB中好像不存储pid,但xp的版本就有这么一句:
TdiConnect:
TCB->pid = PsGetCurrentProcessId();
PS:迅雷的智能限速竟然都NDSI小端口了,真和谐啊,暂时还看不了。。。
PPS:利用第三方带签名的驱动的bug挺和谐。。。一些非安全厂商的驱动相当不安全。。