LSP: layered  service privider  分层服务提供商。

LSP是TCP/IP等协议的接口。

浏览器,聊天工具等等都要通过这个接口来获取相应的信息。

删除不正确的(也称为“buggy”)LSP 可能会导致注册表中的 Winsock 目录损坏,潜在地导致所有网络连接的丢失。 LSP就是TCP/IP等协议的接口.LSP用在正途上可以方便程序员们编写监视系统网络通讯情况的Sniffer,可是现在常见的LSP都被用于浏览器劫持。

LSP(分层服务提供者)

LSP本身是DLL,可以将它安装到winsock目录,以便创建套接字的应用程序不必知道此LSP的任何信息就能调用它。

运行原理:

  套接字创建函数会在winsock目录中寻找合适的协议

  调用此协议,的提供者导出的函数 完成各种功能。

编写目的:

  让用户调用自定义的服务提供者,有自定义的服务提供者调用下层提供者。这样便截获所有的winsock调用了。

服务提供者本身是DLL,导出一些与winsock API相对应的SPI函数。winsock库加载服务提供者时,便依靠这些函数来实现winsockAPI。

LSP也是如此,它向上导出所有的SPI函数供 Ws2_32.dll调用,在内部通过调用基础提供者实现这些SPI。


安装LSP:

实现LSP之前,要先将分层提供者安装到winsock目录,安装包括一个WSAPPROTOCOL_INFOW结构,定义了分层提供者的特性和LSP填写链的方式。(也叫做协议入口)


协议链:

  协议链描述了 分层提供者 加入winsock的目录的顺序。

typedef struct _WSAPROTOCOLCHAIN{int ChainLen;DWORD ChainEntries[Max_PROTOCOL_CHAN];
}WSAPROTOCOLCHAIN,*LPWSAPROTOCOLCHAIN;

ChainLen为0:分层协议  为1 基础协议   大于1 协议链

当ChainLen为0或者1时,ChainEntries数组无意义

大于1时,各个服务提供者的目录ID就包含在数组中。

 

实现LSP的DLL要么被另一个LSP加载,要么直接被WS2_32.DLL加载。取决于它的位置。

如果LSP没有在协议链的顶端,就会被链中位于它上层的LSP加载,否则的话,将被WS2_32.DLL加载。

安装LSP时,必须在winsock目录中安装两种协议:一个分层协议,一个协议链

安装分层协议视为了获取winsock库分配的目录ID号,一边在协议链中标识自己的位置。

协议链才是winsock目录中LSP的真正入口,连中包含了自己分层协议的目录ID号和下层提供者的目录ID号。

在安装时,要先安装一个分层协议,用系统分配给此分层协议的目录ID和下层提供者的目录ID构建一个 ChainEntries数组,进而构建一个WSAPROTOCOL_INFOW结构,然后再安装这个协议链。


安装函数:

提供LSP GUID DLL WSAPROTOCOL_INFOW结构便可。

int WSCInstallProvider(
const LPGUID lpProviderId,
const LPWSTR lpszProviderDllPath,
const LPWSAPROTOCOL_INFOW lpProtocolInfoList,
DWORD dwNumberOfEntries,
LPINT lpErrno
);

每一个安装提供者需要一个GUID来标识它的入口,GUID可以通过命令行工具UUIDGEN或者在编程使用UuidCreate函数来生成。

LSP的WSAPROTOCOL_INFOW结构通常从它要分层的下层提供者拷贝

1 szProtocol域要修改,以包含新提供者的名称

2 如果包含XP1_IFS_HANDLES标识,要从dwServiceFlags1域移除。


重新目录排序  WSCWriteProviderOrder

新安装的LSP会默认安装到winsock目录的结尾,这样系统调用的时候,还是会调用原先调用的LSP,因此只有进行重新的排序才能让系统调用到新安装的LSP。


总结:

  1 安装分层协议入口,以便获取系统分配的目录ID号。

  2 安装一个或者多个协议链,安装的数量取决于要分层的下层协议的数量。

  3 在结尾进行目录排序。


示例代码:

////
// InstDemo.cpp#include <Ws2spi.h>
#include <Sporder.h>                // 定义了WSCWriteProviderOrder函数#include <windows.h>
#include <stdio.h>#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "Rpcrt4.lib")    // 实现了UuidCreate函数// 要安装的LSP的硬编码,在移除的时候还要使用它
GUID  ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3, {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
{DWORD dwSize = 0;int nError;LPWSAPROTOCOL_INFOW pProtoInfo = NULL;// 取得需要的长度if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR){if(nError != WSAENOBUFS)return NULL;}pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);*lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);return pProtoInfo;
}void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
{::GlobalFree(pProtoInfo);
}// 将LSP安装到UDP协议提供者之上
int InstallProvider(WCHAR *wszDllPath)
{WCHAR wszLSPName[] = L"TinyLSP";    // 我们的LSP的名称int nError = NO_ERROR;LPWSAPROTOCOL_INFOW pProtoInfo;int nProtocols;WSAPROTOCOL_INFOW UDPLayeredInfo, UDPChainInfo; // 我们要安装的UDP分层协议和协议链DWORD dwUdpOrigCatalogId, dwLayeredCatalogId;// 在Winsock目录中找到原来的UDP协议服务提供者,我们的LSP要安装在它之上// 枚举所有服务程序提供者pProtoInfo = GetProvider(&nProtocols);for(int i=0; i<nProtocols; i++){if(pProtoInfo[i].iAddressFamily == AF_INET && pProtoInfo[i].iProtocol == IPPROTO_UDP){memcpy(&UDPChainInfo, &pProtoInfo[i], sizeof(UDPLayeredInfo));// UDPChainInfo.dwServiceFlags1 = UDPChainInfo.dwServiceFlags1 & ~XP1_IFS_HANDLES;  // 保存原来的入口IDdwUdpOrigCatalogId = pProtoInfo[i].dwCatalogEntryId;break;}}  // 首先安装分层协议,获取一个Winsock库安排的目录ID号,即dwLayeredCatalogId// 直接使用下层协议的WSAPROTOCOL_INFOW结构即可memcpy(&UDPLayeredInfo, &UDPChainInfo, sizeof(UDPLayeredInfo));// 修改协议名称,类型,设置PFL_HIDDEN标志wcscpy(UDPLayeredInfo.szProtocol, wszLSPName);UDPLayeredInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL;        // LAYERED_PROTOCOL即0UDPLayeredInfo.dwProviderFlags |= PFL_HIDDEN;// 安装if(::WSCInstallProvider(&ProviderGuid, wszDllPath, &UDPLayeredInfo, 1, &nError) == SOCKET_ERROR)return nError;// 重新枚举协议,获取分层协议的目录ID号FreeProvider(pProtoInfo);pProtoInfo = GetProvider(&nProtocols);for(i=0; i<nProtocols; i++){if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0){dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;break;}}// 安装协议链// 修改协议名称,类型WCHAR wszChainName[WSAPROTOCOL_LEN + 1];swprintf(wszChainName, L"%ws over %ws", wszLSPName, UDPChainInfo.szProtocol);wcscpy(UDPChainInfo.szProtocol, wszChainName);if(UDPChainInfo.ProtocolChain.ChainLen == 1){UDPChainInfo.ProtocolChain.ChainEntries[1] = dwUdpOrigCatalogId;}else{for(i=UDPChainInfo.ProtocolChain.ChainLen; i>0 ; i--){UDPChainInfo.ProtocolChain.ChainEntries[i] = UDPChainInfo.ProtocolChain.ChainEntries[i-1];}}UDPChainInfo.ProtocolChain.ChainLen ++;// 将我们的分层协议置于此协议链的顶层UDPChainInfo.ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; // 获取一个Guid,安装之GUID ProviderChainGuid;if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK){if(::WSCInstallProvider(&ProviderChainGuid, wszDllPath, &UDPChainInfo, 1, &nError) == SOCKET_ERROR)return nError;}elsereturn GetLastError();// 重新排序Winsock目录,将我们的协议链提前// 重新枚举安装的协议FreeProvider(pProtoInfo);pProtoInfo = GetProvider(&nProtocols);DWORD dwIds[20];int nIndex = 0;// 添加我们的协议链for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;}// 添加其它协议for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||(pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;}// 重新排序Winsock目录nError = ::WSCWriteProviderOrder(dwIds, nIndex);FreeProvider(pProtoInfo);return nError;
}void RemoveProvider()
{    LPWSAPROTOCOL_INFOW pProtoInfo;int nProtocols;DWORD dwLayeredCatalogId;// 根据Guid取得分层协议的目录ID号pProtoInfo = GetProvider(&nProtocols);int nError;for(int i=0; i<nProtocols; i++){if(memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0){dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;break;}}if(i < nProtocols){// 移除协议链for(i=0; i<nProtocols; i++){if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId)){::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);}}// 移除分层协议::WSCDeinstallProvider(&ProviderGuid, &nError);}
}////int binstall = 0;
void main()
{if(binstall){if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS){printf(" Install successully \n");}else{printf(" Install failed \n");}}elseRemoveProvider();
}

分类: 【17】Windows
绿色通道:好文要顶关注我收藏该文与我联系

xingoo
关注 - 41
粉丝 - 348

+加关注

0
0
(请您对文章做出评价)

« 上一篇:Winsock协议目录
» 下一篇:0-1背包-回溯法

posted @ 2012-10-23 21:52 xingoo 阅读(986) 评论(0) 编辑 收藏

什么是LSP???如何看待LSP???相关推荐

  1. 怎么修复LSP,LSP修复命名及工具——新手上路

    什么是LSP? LSP即分层服务提供商,LSP即Layered Service Provider,Winsock 作为应用程序的 Windows 的网络套接字工具,可以由称为"分层服务提供商 ...

  2. 解决LSP问题导致无法上网

    判断LSP是否损坏,以及修复方式的微软网址: http://support.microsoft.com/?scid=kb%3Bzh-cn%3B811259 Winsock LSP全称Windows S ...

  3. [翻译]LSP程序的分类

    翻译的太垃圾,不建议其它人阅读本文. Note:LSP现在已经不推荐使用.自windows8和windows Server2012开始,使用Windows Filtering Platform. Wi ...

  4. cad渐开线齿轮轮廓绘制_CAD画齿轮的渐开线程序 (lsp)和渐开线齿轮关系

    一. CAD 中齿轮画法 有下面一段渐开线程序: ;;;begain suprgear.lsp ;************************************************* ; ...

  5. 2022-06-25 网工进阶(十一)IS-IS-三大表(邻居表、路由表、链路状态数据库表)、LSP、CSNP、PSNP、LSP的同步过程

    三大表 IS-IS协议与OSPF一样也有三大表. 邻居表 <R3>display isis peer Peer information for ISIS(1)System Id Inter ...

  6. hcie 论述-mpls lsp

    第八题 MPLS LSP 问题一  四台设备运行ospf,igp是互联互通的,在这些网络中建立mpls lsp 隧道,发现隧道建立失败,影响lsp隧道建立失败的因素有那些 第一点,Lsrid 没有宣告 ...

  7. LSP标识符(LSP ID)

    LSP标识符(LSP ID)        路由器生成的每个LSP都有一个LSP标识符(LSP ID),LSP主要用来标识不同的LSP和生成LSP的源路由器.就像OSPF中一样,每个LSA都使用通告路 ...

  8. ISIS——LSP讲解

    目录 LSP作用 LSP类型 LSP包含信息 LSP唯一标识符 通过LSDB建立拓扑路由信息 LSP新旧判断 哪些情况下会产生LSP LSP作用 LSP类似于OSPF的LSA,承载的是链路状态信息,包 ...

  9. ISIS之LSP详解

    ISIS LSP详解   LSP的分类:            从报文角度看分为L1,L2            从用途或者说从发布者来说分为实节点LSP,伪节点LSP.  LSP产生的原因:     ...

最新文章

  1. Saiku的下载与安装(一)
  2. undefined reference to 'pthread_mutex_trylock'
  3. perl对文件和目录进行操作
  4. 使用 Source Generator 自动生成 WEB API
  5. layui绑定json_JSON绑定:概述系列
  6. CSS之background-position属性
  7. VS2017动态链接库(.dll)的生成与使用
  8. 新手也能看懂的 SpringBoot 异步编程指南
  9. 如何遍历或枚举JavaScript对象?
  10. 简单RAM存储器分析
  11. 惊叹 | 膜拜一下清华大学特等奖学金的学霸大佬们的简历! -- 我们没有理由不努力!...
  12. 浅谈怎样入侵服务器,仅供学习用
  13. (附源码)spring boot学科竞赛活动报名系统 毕业设计 012239
  14. 谷歌日语输入法、中文输入法之间的切换
  15. 树莓派有线网络设置_树莓派的基本网络配置
  16. 成都旅游住宿购物交通攻略87
  17. 模板引擎Beet的6大创新点
  18. img标签图片的刷新,删除
  19. blender绑定后,姿态模式 骨骼动 模型不动
  20. 计算机考研报名专业是哪个,考研报名毕业专业计算机怎么填?

热门文章

  1. ubuntu IP地址配置
  2. Excel INDEX MATCH教程之 什么是INDEX MATCH,有什么用(教程含案例)
  3. 用GitHub Actions制作Docker镜像
  4. 数字拆分问题算法回溯_回溯算法
  5. JJ Ying:越来越跨界的界面设计
  6. Word修改默认字体
  7. 开源或免费音频视频编辑软件推荐
  8. MATLAB阈值获取函数*
  9. LeetCode-Python 栈专题(学习笔记+代码)
  10. Spark学习(6)——scala数组操作