王艳平windows网络与通信程序设计代码求助? 本帖最后由 VisualEleven 于 2011-01-12 15:15:13 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 以下是安装LSP////////////////////////////////////////////////////////// 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函数#pragma comment(lib, "Sporder.lib ") // 要安装的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 = 0;void main(){ if(binstall) { if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS) { printf(" Install successully \n"); } else { printf(" Install failed \n"); } } else RemoveProvider();} 以下是安装LSP////////////////////////////////////////////////////////// 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函数#pragma comment(lib, "Sporder.lib ") // 要安装的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 = 0;void main(){ if(binstall) { if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS) { printf(" Install successully \n"); } else { printf(" Install failed \n"); } } else RemoveProvider();} 没看过,楼上的,帮忙推荐一本windows 网络编程的书,谢谢鸟! 你 WSPSendTo里什么都不做拦截直接调用下一个提供者看看 试过了 不会导致任何问题 就是这几句导致部分dns失效的吧:SOCKADDR_IN sa = *(SOCKADDR_IN*)lpTo; if(sa.sin_port == htons(4567)) { int iError; g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError); *lpErrno = WSAECONNABORTED; ODS(L" deny a sendto "); return SOCKET_ERROR; } 可能DNS解析用这个端口来监听 那这么说代码是没问题的 那假如想禁止登陆qq 就在sendto里禁了目的端口8000就行了吧?可是我试过好多端口号 随便什么端口号都会导致qq无法登陆,这是为什么呢?另外还有输入www.baidu.com是打不开的,输ip可以,搜一些东西也能显示,但是更进一层就打不开了,这是为什么呢?多谢您了! 改成了禁用目的端口8000 输出日志显示确实登录qq的时候8000端口被禁用了 qq很聪明,自动寻找8001端口还是顽强地登录了 lsp 一直我就没找个没bug的代码. 前辈您好,我在王艳平的书里还看到她把lsp装到了raw协议之上,不知道这么做有什么作用呢,另外想请教您如果想截原始数据包,我应该用什么程序去测试呢?上周试了windows自带的远程桌面连接和局域网共享文件夹还有ping程序,都没有成功截获原始数据包,希望前辈能指点一二啊!!!多谢多谢! 王艳平的书里代码第七章基本上还是没有问题的,我试过,只是个别for循环里的局部变量i没声明罢了,我也在学lsp,多多交流~ VC2010 调试无响应 一个连接的问题 ActiveX控件怎样在程序中通过代码改变显示字体? 怎么加载toolbar? 拖动LISTCTRL表头改变列宽度时,响应的是什么函数呀? 界面调整问题:窗口大小调整后如何调整STATIC TEXT控件的位置 如何实现这样的API hook?(500分奉送) 画图--文字输出?? 关于用一个DLL封装另外一个DLL的方法 请问关于 StretchBlt 函数 VC如何将一个界面的内容显示到另一界面中包括控件 vc程序移植到vs2010后弹出创建空文档失败
// 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函数
#pragma comment(lib, "Sporder.lib ") // 要安装的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 = 0;
void main()
{
if(binstall)
{
if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS)
{
printf(" Install successully \n");
}
else
{
printf(" Install failed \n");
}
}
else
RemoveProvider();
}
// 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函数
#pragma comment(lib, "Sporder.lib ") // 要安装的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 = 0;
void main()
{
if(binstall)
{
if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS)
{
printf(" Install successully \n");
}
else
{
printf(" Install failed \n");
}
}
else
RemoveProvider();
}
SOCKADDR_IN sa = *(SOCKADDR_IN*)lpTo;
if(sa.sin_port == htons(4567))
{
int iError;
g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);
*lpErrno = WSAECONNABORTED;
ODS(L" deny a sendto ");
return SOCKET_ERROR;
}
lsp 一直我就没找个没bug的代码.
前辈您好,我在王艳平的书里还看到她把lsp装到了raw协议之上,不知道这么做有什么作用呢,另外想请教您如果想截原始数据包,我应该用什么程序去测试呢?上周试了windows自带的远程桌面连接和局域网共享文件夹还有ping程序,都没有成功截获原始数据包,希望前辈能指点一二啊!!!多谢多谢!
王艳平的书里代码第七章基本上还是没有问题的,我试过,只是个别for循环里的局部变量i没声明罢了,我也在学lsp,多多交流~