Winsock LSP开发与安装问题

llovewolfer llovewolfer 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
小弟初次接触Winsock LSP技术,学习《windows网络与通信程序设计》有关LSP的技术的时候遇到些问题,望各位高手指教。我写了一个完全空白LSP动态链接库,也导出了WSPStartup函数,然后用编写好的LSP安装程序安装在TCP或UDP协议上之后(安装成功),用浏览器完全没有办法上网,我怀疑是安装程序的问题,不知道哪位高手能帮我解决这个问题,困扰了我一个多星期了。代码见下面,


///////////////LSP处理程序(dll)--改编自上述书中源代码///////
#define UNICODE
#define _UNICODE

#include <Winsock2.h>
#include <Ws2spi.h>
#include <Windows.h>
#include <tchar.h>
#include "Debug.h"

#pragma comment(lib, "Ws2_32.lib")

WSPUPCALLTABLE g_pUpCallTable; // 上层函数列表。如果LSP创建了自己的伪句柄,才使用这个函数列表
WSPPROC_TABLE g_NextProcTable; // 下层函数列表
TCHAR g_szCurrentApp[MAX_PATH]; // 当前调用本DLL的程序的名称


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
// 取得主模块的名称
::GetModuleFileName(NULL, g_szCurrentApp, MAX_PATH);
}
break;
}
return TRUE;
}


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);
}

int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFO lpProtocolInfo,
WSPUPCALLTABLE UpcallTable,
LPWSPPROC_TABLE lpProcTable
)
{
ODS1(L" WSPStartup... %s \n", g_szCurrentApp);

if(lpProtocolInfo->ProtocolChain.ChainLen <= 1)
{
return WSAEPROVIDERFAILEDINIT;
}

// 保存向上调用的函数表指针(这里我们不使用它)
g_pUpCallTable = UpcallTable;

// 枚举协议,找到下层协议的WSAPROTOCOL_INFOW结构
WSAPROTOCOL_INFOW NextProtocolInfo;
int nTotalProtos;
LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtos);
// 下层入口ID
DWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries[1];
for(int i=0; i<nTotalProtos; i++)
{
if(pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId)
{
memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(NextProtocolInfo));
break;
}
}
if(i >= nTotalProtos)
{
ODS(L" WSPStartup: Can not find underlying protocol \n");
return WSAEPROVIDERFAILEDINIT;
}

// 加载下层协议的DLL
int nError;
TCHAR szBaseProviderDll[MAX_PATH];
int nLen = MAX_PATH;
// 取得下层提供程序DLL路径
if(::WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR)
{
ODS1(L" WSPStartup: WSCGetProviderPath() failed %d \n", nError);
return WSAEPROVIDERFAILEDINIT;
}
if(!::ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH))
{
ODS1(L" WSPStartup: ExpandEnvironmentStrings() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}
// 加载下层提供程序
HMODULE hModule = ::LoadLibrary(szBaseProviderDll);
if(hModule == NULL)
{
ODS1(L" WSPStartup: LoadLibrary() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}

// 导入下层提供程序的WSPStartup函数
LPWSPSTARTUP pfnWSPStartup = NULL;
pfnWSPStartup = (LPWSPSTARTUP)::GetProcAddress(hModule, "WSPStartup");
if(pfnWSPStartup == NULL)
{
ODS1(L" WSPStartup: GetProcAddress() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}

// 调用下层提供程序的WSPStartup函数
LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo;
if(NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL)
pInfo = &NextProtocolInfo;

int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, pInfo, UpcallTable, lpProcTable);
if(nRet != ERROR_SUCCESS)
{
ODS1(L" WSPStartup: underlying provider's WSPStartup() failed %d \n", nRet);
return nRet;
}

// 保存下层提供者的函数表
g_NextProcTable = *lpProcTable;
FreeProvider(pProtoInfo);
return nRet;
}

////////////////////////LSP安装程序(exe)--同样是书中源代码的改写////////
#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;
// 保存原来的入口ID
dwUdpOrigCatalogId = 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即0
UDPLayeredInfo.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;
}
else
return 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 = 1;
void main()
{
if(binstall)
{
if(InstallProvider(L"LSP.dll") == ERROR_SUCCESS)
{
printf(" Install successully \n");
}
else
{
printf(" Install failed \n");
}
}
else
RemoveProvider();
}

拜托大家了!!!!
...全文

相关推荐

LSP分层服务提供程序

**安全性和兼容性**:由于LSP插件能够影响整个系统的网络行为,因此必须谨慎设计,避免引入安全漏洞或导致与其他网络应用的兼容性问题。6.

HelloA666

全面掌握LSP分层服务提供程序开发

LSP本质上是一个网络通信链上的中间件,它可以插入Winsock协议栈,通过提供附加层来增强网络功能。其核心价值在于其灵活性和扩展性,能够无侵入式地增强或改变网络应用的行为,而无需对应用程序本身进行任何修改。Winsock API,作为Windows平台上的网络通信核心接口,是开发者构建网络应用程序的重要基础。在LSP(Layered Service Provider)的进阶应用中,Winsock API扮演着不可或缺的角色。

含老司开挖掘机

360LSP修复工具:网络问题轻松解决

网络服务接口(Layered Service Provider,LSP)是Windows操作系统中用于网络通信的一种机制,它允许开发者插入自定义的网络服务到系统中的网络堆栈。LSP是一种特殊的网络协议提供者,可以在传输层(TCP/IP协议)与应用层之间加入新的层,执行一些如数据过滤、流量控制和协议转换等操作。它是Windows Sockets 2(Winsock 2)API的一部分,主要目的是提供一种扩展点,使得第三方开发者可以扩展Windows网络服务的功能。

宝贝西

winsock修复软件_WinsockxpFix

这个工具特别适合解决由于安装或卸载软件后,LSP链混乱或损坏引发的网络问题。

leonhua2008

LSP修复工具

这时,就需要使用LSP修复工具来解决这类问题。"金山LSP修复工具"是一款专门针对此类问题设计的实用软件,由知名安全厂商金山公司开发。

qq_14960269
评论
收藏 已收藏
分享
返回顶部
llovewolfer
硬件/系统 2,644 成员 17,229 内容