TDI过滤获取IP及端口
TDI过滤驱动获取IP地址及连接端口要涉及关于TDI的一些结构体,当接收到含有TDI的TDI_CONNECT连接IRP请求时,IRP请求栈顶的的参数parameters就是指向TDI_REQUEST_KERNEL_CONNECT结构体的指针,实际上,这个结构体就是TDI_REQUEST_KERNEL。这个结构体定义在tdikrnl.h中定义如下:
typedef struct _TDI_REQUEST_KERNEL {
ULONG RequestFlags;
PTDI_CONNECTION_INFORMATION RequestConnectionInformation;
PTDI_CONNECTION_INFORMATION ReturnConnectionInformation;
PVOID RequestSpecific;
} TDI_REQUEST_KERNEL, *PTDI_REQUEST_KERNEL;
这里的第二个参数RequestConnectionInformation是一个TDI_CONNECTION_INFORMATION结构体指针,TDI_CONNECTION_INFORMATION在头文件tdi.h中定义如下:
typedef struct _TDI_CONNECTION_INFORMATION {
LONG UserDataLength; //用户数据buffer的长度
PVOID UserData; //指向用户数据buffer的指针
LONG OptionsLength;
PVOID Options;
LONG RemoteAddressLength;
PVOID RemoteAddress; //远程地址
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;
最后一个参数RemoteAddress是一个指向TRANSPORT_ADDRESS结构体的指针。TRANSPORT_ADDRESS的定义如下:
typedef struct _TRANSPORT_ADDRESS {
LONG TAAddressCount; //address的数量
TA_ADDRESS Address[1]; //这里是一个TA_ADDRESS结构体
} TRANSPORT_ADDRESS, *PTRANSPORT_ADDRESS;
结构体TA_ADDRESS定义如下:
typedef struct _TA_ADDRESS {
USHORT AddressLength;
USHORT AddressType; //地址类型
UCHAR Address[1]; //地址信息
} TA_ADDRESS, *PTA_ADDRESS;
参数AddressType是TDI支持的一些协议类型,当为TCP/IP协议类型时最后一个参数Address指向包含IP地址及连接端口信息的结构体TDI_ADDRESS_IP,在这个结构体里面就包含了我们要获去的IP及端口信息。TDI_ADDRESS_IP定义如下:
typedef struct _TDI_ADDRESS_IP {
USHORT sin_port;
ULONG in_addr;
UCHAR sin_zero[8];
} TDI_ADDRESS_IP, *PTDI_ADDRESS_IP;现在大概的思路就清楚了,根据上面的信息要获取IP及端口只需按着顺序往下走即可。大体代码如下:
PIO_STACK_LOCATION StackIrpPointer=NULL;
PTDI_REQUEST_KERNEL_CONNECT TDI_connectRequest ;
PTA_ADDRESS TA_Address_data ;
// 要得到IP和端口
PTDI_ADDRESS_IP TDI_data ;
typedef struct _NETWORK_ADDRESS
{
unsigned char address [4];
unsigned char port [2];
} NETWORK_ADDRESS ;
NETWORK_ADDRESS data ;
unsigned short Port =0;
unsigned long Address =0;
StackIrpPointer=IoGetCurrentIrpStackLocation(Irp);
....
//这里判断如果StackIrpPointer->MinorFunction == TDI_CONNECT的话就输出IP及端口信息
....
TDI_connectRequest =( PTDI_REQUEST_KERNEL_CONNECT )(& StackIrpPointer -> Parameters );
TA_Address_data =( ( PTRANSPORT_ADDRESS )( TDI_connectRequest -> RequestConnectionInformation ->RemoteAddress ))-> Address ;
TDI_data = ( PTDI_ADDRESS_IP ) ( TA_Address_data -> Address );
Address = TDI_data -> in_addr ;
Port = TDI_data -> sin_port ;
data . address [0] = (( char *)& Address )[0];
data . address [1] = (( char *)& Address )[1];
data . address [2] = (( char *)& Address )[2];
data . address [3] = (( char *)& Address )[3];
data . port [0] = (( char *)& Port )[0];
data . port [1] = (( char *)& Port )[1];
Port = data . port [0] + data . port [1];
DbgPrint ("TDIFilter: IP address:port is %d.%d.%d.%d:%d ",data.address [0] ,data.address[1] ,data.address[2] , data.address[3] ,Port );
加载驱动后,打开IE浏览器显示GOOGLE主页并通过Dbgview观察输出信息,注意IP和端口那一行哦。如下:
补充:综合编程 , 其他综合 ,