当前位置:编程学习 > 网站相关 >>

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和端口那一行哦。如下:


补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,