网络编程之Winsock2 服务提供者接口(SPI)
来源:互联网 发布:关于域名说法正确的是 编辑:程序博客网 时间:2024/06/01 09:49
【1】Winsock2 服务提供者接口(SPI):
一、简述:
2、因为Winsock服务体系符合Windows开放服务体系.所以,它支持第三方服务提供者插入到其中.
3、只要上层和下层的边缘支持Winsock2 SPI,即可向他们中间安装第三方提供者程序.4、普通开发者一般都是开发SPI的LSP(分层服务提供者),即第三方提供者,可用于监控Winsock API执行,HOOK Winsock API,甚至利用LSP技术注入DLL.
5、基础协议(TCP、UDP、原始)的提供者其实就是DLL,编写分层协议提供者就是在编写DLL,然后安装在Winsock目录上,让系统上的所有使用基础协议的网络程序调用.
【重点】网络程序是如何调用Winsock2 服务提供者进行网络通讯:
1、当网络程序使用WSAStartup加载库时,系统并不做什么.
2、而是当程序真正创建套接字时,会先调用WSCEnumProtocols函数,遍历系统内安装的所有提供者(分层、基础、协议链),当先找到一个与要求使用的协议符合的,那么导出此提供者的DLL,才开始调用提供者的WSPStartup初始化函数,才能使用send,recv(TCP协议提供者的DLL)或sendto,recvfrom(UDP协议提供者的DLL)等函数的功能.
二、SPI(服务提供者接口)由两个部分组成:
一、传输服务提供者:
1、提供建立连接、传输数据、流控制、出错控制。
2、共两种类型:
基础服务提供者:
实现传输协议的细节,导出Winsock接口(此接口直接实现协议). //TCP、UDP、原始
一般都有与之关联的内核模式协议驱动,TCP、UDP由系统内的Tcpip.sys驱动。
分层服务提供者(LSP):
将自己安装到Winsock目录(Winsock目录的概念在下面)中基础提供者(TCP/UDP)的上一层,也可能安装在其他提供者之间,可截获程序的Winsock API。
依靠基础服务提供者作为通信基础,实现更高层的通信函数。
二、命名空间服务提供者:
1、与传输服务提供者相似,可截获名称解析API(gethostbyname、WSALookupServiceBegin)的调用.
2、此类提供者需在命名空间目录安装自己.【2】SPI(服务提供者)函数集合类型:
头文件:ws2spi.h
SPI函数类型总数:4种类型,每一种类型都有自己所属的开头,例如WSC、WSP
WSC安装、移除、修改分层服务提供者和命名空间提供者程序WSP分层服务提供者的APIWPU分层服务提供者使用的支持函数NSP命名空间服务提供者的API
【3】Winsock协议目录的概念:
一、SPI提供三种协议:
1、分层协议:处在基础协议的上一层,依靠基础协议作为通信基础。
2、基础协议:能够独立、安全、远程端点实现数据通信的协议。3、协议链:将一系列基础协议和分层协议按特定顺序连接在一起。
注意:只有管理员用户组能够安装、移除Winsock目录入口!
二、WSAPROTOCOL_INFO结构体:
说明:描述某个协议(分层协议、基础协议)的完整信息,一个WSAPROTOCOL_INFO结构体称为一个Winsock目录入口。
typedef struct _WSAPROTOCOL_INFOW { DWORD dwServiceFlags1; //描述[协议]提供的服务的位掩码 DWORD dwServiceFlags2; //保留 DWORD dwServiceFlags3; //保留 DWORD dwServiceFlags4; //保留 DWORD dwProviderFlags; //此[协议]在[Winsock目录]中的[表示方式] GUID ProviderId; //由[服务提供商]安排的GUID唯一标示符 DWORD dwCatalogEntryId; //WS2_32.DLL为每一个WSAPROTOCOL_INFOW结构安排的唯一标示符(目录入口ID) WSAPROTOCOLCHAIN ProtocolChain; /*1)与[此协议]相关联的WSAPROTOCOLCHAIN结构. 2)说明了[此协议]在[分层协议]中所处的位置.*/ int iVersion; //[协议]版本标示符 int iAddressFamily; //传递给socket/WSASocket函数的[地址加载参数] int iMaxSockAddr; //地址的最大长度(以字节为单位) int iMinSockAddr; //地址的最小长度(以字节为单位) int iSocketType; //传递给socket函数的[套接字类型参数] int iProtocol; //传递给socket函数的[协议参数] int iProtocolMaxOffset; //添加到iProtocol的最大值 int iNetworkByteOrder; //顺序类型:大尾顺序(BIGENDIAN),小尾顺序(LITTLEENDIAN) int iSecurityScheme; //安全方案 DWORD dwMessageSize; /*[此协议]支持的最大消息长度(以字节为单位) 1)0为基于流协议(如TCP),没有最大长度的概念. 2)1为发送消息的最大长度依赖于下层网络的MTU(最大传输单元),在套接字绑定后,应使用SO_MAX_MSG_SIZE套接字选项. 获取发送消息的最大长度. 3)-1为此协议是基于消息的,但是对发送的消息没有最大长度的限制. */ DWORD dwProviderReserved; //保留给服务提供者使用. WCHAR szProtocol[WSAPROTOCOL_LEN+1]; //随意编辑的,此协议的可读字符串.一般用于说明是什么协议} WSAPROTOCOL_INFOW, FAR * LPWSAPROTOCOL_INFOW;
【4】遍历系统所有已安装的协议:
一、使用的API函数:int WSAEnumProtocols(
LPINT lpiProtocols,
LPWSAPROTOCOL_INFO lpProtocolBuffer,
LPDWORD lpdwBufferLength
);
参数1:一个数组
1、NULL为函数将返回所有协议.
2、否则只检索数组中列出的那些协议.
参数2:取信息的缓冲区
参数3:参数2缓冲区的长度
1、如果参数2为NULL,参数3为0,执行后,WSAENOBUFS错误,参数3包含了所需的缓冲区长度.
注意:此函数仅能够遍历基础协议、协议链,但是不能遍历分层协议.
二、支持遍历分层协议的函数,功能与上面相同:
函数:intWSCEnumProtocols(
LPINT lpiProtocols,
LPWSAPROTOCOL_INFOW lpProtocolBuffer,
LPDWORD lpdwBufferLength,
LPINT lpErrno
);
返回值、参数1~参数3:与WSAEnumProtocols函数相同。
参数4:相当于WSAGetLastError()执行的结果
注意:因为SPI是用于开发系统组件的函数,所以他只使用Unicode字符串,与Windows系统相对应。
【5】遍历系统内安装的所有协议例子:
头文件:
#pragma once#include <iostream>#include <winsock2.h> #include <ws2tcpip.h>#include <mstcpip.h>#include <string.h>#include <tchar.h>using namespace std;#pragma warning(disable:4996)#pragma comment(lib, "Ws2_32.lib")//系统安装协议遍历实验class ProtocolTraversestheExperiment{public:ProtocolTraversestheExperiment(){WSADATA wsa;WSAStartup(MAKEWORD(2, 2), &wsa);}~ProtocolTraversestheExperiment(){WSACleanup();}LPWSAPROTOCOL_INFO GetProvider(LPINT lpnTotalProtocols){DWORD dwSize = 0;LPWSAPROTOCOL_INFO pProtoInfo = NULL;if (WSAEnumProtocols(NULL, pProtoInfo, &dwSize) == SOCKET_ERROR){if (WSAGetLastError() != WSAENOBUFS)return NULL;}pProtoInfo = (LPWSAPROTOCOL_INFO)new WSAPROTOCOL_INFO[dwSize / sizeof(WSAPROTOCOL_INFO)];if (!pProtoInfo)return NULL;ZeroMemory(pProtoInfo, dwSize);*lpnTotalProtocols = WSAEnumProtocols(NULL, pProtoInfo, &dwSize);return pProtoInfo;}void FreeProvider(LPWSAPROTOCOL_INFO pProtoInfo,int i){if(i == 1)delete pProtoInfo;else delete[] pProtoInfo;}};
源文件:
#include "Hello.h"int main(int argc,char** argv){system("color 4e");ProtocolTraversestheExperiment s;int ProtocolsCount = 0;LPWSAPROTOCOL_INFO info = s.GetProvider(&ProtocolsCount);if (ProtocolsCount != 0){for (int i = 0; i < ProtocolsCount; i++){wprintf(_T("Protocol:%s \r\n"), info[i].szProtocol);wprintf(_T("CatalogEntryId:%d ChainLen:%d \n\n"), info[i].dwCatalogEntryId, info[i].ProtocolChain.ChainLen);}s.FreeProvider(info, ProtocolsCount);}getchar();return 0;}
执行:
下一篇文章讲解安装LSP(分层服务提供者): //SPI的使用
1、由于基础传输提供者和命名空间提供者一般仅对操作系统开发商、传输堆栈商有效
一般开发者只能开发分层服务提供者(所谓的第三方系统组件)
2、黑客通常安装LSP,拦截Winsock API,对用户进行浏览器劫持、监控使用者信息等等.
3、地址:http://blog.csdn.net/aaron133/article/details/78028942
- 网络编程之Winsock2 服务提供者接口(SPI)
- 网络编程之Winsock2 服务提供者接口(SPI)
- 第7章 Winsock 服务提供者接口 (SPI)
- SPI(service provider interface 服务提供者接口)
- 【winsock2】windows网络编程 之 UDP/IP
- winsock2 网络编程
- Winsock2 SPI网络封包截获技术
- 【winsock2】windows网络编程 之 TCP/IP Server
- 【winsock2】windows网络编程 之 TCP/IP Client
- 【winsock2】Windows Socket 网络编程
- 网络封包过滤之分层服务提供者(LSP)(1)
- 网络封包过滤之分层服务提供者(LSP)
- 网络封包过滤之分层服务提供者(LSP)
- 网络封包过滤之分层服务提供者(LSP)
- 使用WinSock2 SPI进行网络控制访问内容
- 利用WinSock2 SPI进行网络内容访问控制
- Windows winsock2 SPI使用
- java之服务提供者框架
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛: B. Coin
- ActiveMQ(一)-消息中间件概述
- mysql— EXPLAIN命令的总结
- SGISTL源码探究-关联式容器:set
- Java语法基础练习题
- 网络编程之Winsock2 服务提供者接口(SPI)
- Java工具包之图片水印-yellowcong
- java帐号管理系统(窗体MD5加密)
- 使用C语言实现单链表
- JAVA学习笔记-序列化
- ubuntu 16.04 server版安装VirtualBox Guest Additions 的解决过程
- myBatis 传递参数源码分析
- Spark自定义分区(Partitioner)
- 在小数点后某一位四舍五入,即保留几位小数(MATLAB)