基于SPI的LSP网络封包截获
2015-07-13 22:02
691 查看
、、、首先我不是原创、、、、、
转载别人的然后自己学习,网上有很多资料。大家可以先看《windows防火墙与网络封包截获》然后再看“基于SPI 的网络封包截获”。应该就差不多了
我会在地址下方给出这些资料链接、、、、
还有源码。
首先先安装LSP:
将输出路径改为:
转载别人的然后自己学习,网上有很多资料。大家可以先看《windows防火墙与网络封包截获》然后再看“基于SPI 的网络封包截获”。应该就差不多了
我会在地址下方给出这些资料链接、、、、
还有源码。
首先先安装LSP:
#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的硬编码,在卸载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; //用于申请存放服务提供者结构的内存空间; // 取得需要的长度,即通过将WSCEnumProtocols函数的dwSize参数置0进行第一次调用,后 //以获得枚举服务提供者所需的缓冲区大小,置于dwSize变量中; if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR) { if(nError != WSAENOBUFS) return NULL; } //根据dwSize中的值来申请内存空间; pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize); //第二次通过WSCEnumProtocols()正式枚举到各服务提供者并存放于pProtoInfo(数组)中, //并将服务提供者的个数存到lpnTotalProtocols中; *lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError); //将pProtoInfo返回给函数调用者; return pProtoInfo; } void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo) { //释放用于存放服务提供者数组的内存空间,pProtoInfo; ::GlobalFree(pProtoInfo); } //枚举现有的各服务提供者; void query() { LPWSAPROTOCOL_INFOW pProtoInfo; int nProtocols; pProtoInfo = GetProvider(&nProtocols); for(int i=0; i<nProtocols; i++) { printf(" Protocol: %ws \n", pProtoInfo[i].szProtocol); printf(" CatalogEntryId: %d ChainLen: %d \n\n", pProtoInfo[i].dwCatalogEntryId, pProtoInfo[i].ProtocolChain.ChainLen); } } //安装LSP int InstallProvider(WCHAR *pwszPathName) { //标识我们自定义安装的LSP的名字; WCHAR wszLSPName[]=L"^_^LSP"; LPWSAPROTOCOL_INFOW pProtoInfo; int nProtocols; WSAPROTOCOL_INFOW OriginalProtocolInfo[3]; DWORD dwOrigCatalogId[3]; int nArrayCount=0; DWORD dwLayeredCatalogId; int nError; //枚举所有的服务提供者; pProtoInfo=GetProvider(&nProtocols); //通过以下三个布尔变量,来判断是否找到对应服务提供者; BOOL bFindTcp=FALSE; BOOL bFindUdp=FALSE; BOOL bFindRaw=FALSE; //遍历pProtoInfo数据里的每个服务提供者,并将TCP、UDP、RAW对应的服务提供者结构保存; for(int i=0;i<nProtocols;i++) { if(pProtoInfo[i].iAddressFamily==AF_INET) { if(!bFindTcp&&pProtoInfo[i].iProtocol==IPPROTO_TCP) { memcpy(&OriginalProtocolInfo[nArrayCount],&pProtoInfo[i],sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1=OriginalProtocolInfo[nArrayCount].dwServiceFlags1&(~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++]=pProtoInfo[i].dwCatalogEntryId; bFindTcp=TRUE; //表示已找到对应服务提供者; } if(!bFindUdp&&pProtoInfo[i].iProtocol==IPPROTO_UDP) { memcpy(&OriginalProtocolInfo[nArrayCount],&pProtoInfo[i],sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1=OriginalProtocolInfo[nArrayCount].dwServiceFlags1&(~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++]=pProtoInfo[i].dwCatalogEntryId; bFindUdp=TRUE; } if(!bFindRaw&&pProtoInfo[i].iProtocol==IPPROTO_IP) { memcpy(&OriginalProtocolInfo[nArrayCount],&pProtoInfo[i],sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1=OriginalProtocolInfo[nArrayCount].dwServiceFlags1&(~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++]=pProtoInfo[i].dwCatalogEntryId; bFindRaw=TRUE; } } } //安装我们自定义的分层协议,获取一个dwLayeredCatalogID,即LSP入口ID; //任意将一个下层服务提供者的结构复制到LayeredProtocolInfo中,进行LSP //服务提供者结构的自定义; WSAPROTOCOL_INFOW LayeredProtocolInfo; memcpy(&LayeredProtocolInfo,&OriginalProtocolInfo[0],sizeof(WSAPROTOCOL_INFOW)); //构造我们自定义的LSP结构; wcscpy(LayeredProtocolInfo.szProtocol,wszLSPName); LayeredProtocolInfo.ProtocolChain.ChainLen=LAYERED_PROTOCOL; LayeredProtocolInfo.dwProviderFlags|=PFL_HIDDEN; //通过WSCInstallProvider()开始安装我们自定义的LSP; if(::WSCInstallProvider(&ProviderGuid,pwszPathName,&LayeredProtocolInfo,1,&nError)==SOCKET_ERROR) { return nError; } //重新枚举各服务提供者,获取刚才我们安装好的自定义的LSP的入口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]; for(i=0;i<nArrayCount;i++) { swprintf(wszChainName,L"%ws over %ws",wszLSPName,OriginalProtocolInfo[i].szProtocol); wcscpy(OriginalProtocolInfo[i].szProtocol,wszChainName); if(OriginalProtocolInfo[i].ProtocolChain.ChainLen==1) { OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1]=dwOrigCatalogId[i]; } else { for(int j=OriginalProtocolInfo[i].ProtocolChain.ChainLen;j>0;j--) { OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j]=OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j-1]; } } OriginalProtocolInfo[i].ProtocolChain.ChainLen++; OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0]=dwLayeredCatalogId; } //为协议链获取一个GUID,并通过OriginalProtocol数组来安装三个协议链; GUID ProviderChainGuid; if(::UuidCreate(&ProviderChainGuid)==RPC_S_OK) { if(::WSCInstallProvider(&ProviderChainGuid,pwszPathName,OriginalProtocolInfo,nArrayCount,&nError)==SOCKET_ERROR) { return nError; } } else return GetLastError(); //协议链安装完毕后,需要重新排序,将我们的协议链提到最前面; 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; } //添加其他的服务提供者入口ID; for(i=0;i<nProtocols;i++) { if((pProtoInfo[i].ProtocolChain.ChainLen<=1)||(pProtoInfo[i].ProtocolChain.ChainEntries[0]!=dwLayeredCatalogId)) dwIds[nIndex++]=pProtoInfo[i].dwCatalogEntryId; } //通过WSCWriteProviderOrder()重新按照dwIds的顺序排序; if((nError=::WSCWriteProviderOrder(dwIds,nIndex))!=ERROR_SUCCESS) { return nError; } FreeProvider(pProtoInfo); return nError; } //移除我们自定义的LSP及协议链; void RemoveProvider() { LPWSAPROTOCOL_INFOW pProtoInfo; int nProtocols; DWORD dwLayeredCatalogId; pProtoInfo=GetProvider(&nProtocols); int nError; //根据GUID来获得分层协议的入口ID; 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); } } //最后移除分层服务提供者LSP; ::WSCDeinstallProvider(&ProviderGuid, &nError); } } /////////////////////////////////////////////////////////////////////////////////////// int usage() { printf("\n*********************************************************\n" "* nfilter.exe,by miyagi&echo *\n" "* *\n" "* usage:nfilter.exe [-install] [-uninstall] [-query] *\n" "*********************************************************\n"); return 0; } int main(int argc,char* argv[]) { if(argc<2) { usage(); } else { if(strcmp(argv[1],"-install")==0) { if(InstallProvider(L"wskfilter.dll") == ERROR_SUCCESS) { printf(" Install successully!^_^ \n"); } else { printf(" Install failed!~o~ \n"); } } if(strcmp(argv[1],"-uninstall")==0) { RemoveProvider(); printf(" Uninstall successully!^_^ \n"); } if(strcmp(argv[1],"-query")==0) { query(); printf(" Query successully!^_^ \n"); } } return 1; }
将输出路径改为:
../Release/install.exe
在此过程中可能会出现external symbol _WSCWriteProviderOrder@8。然后解决方法呢就是、、<a target=_blank href="http://blog.csdn.net/u013675958/article/details/21302423">点击打开链接</a>
。。。。。
相关文章推荐
- 知识点——网络
- socket网络编程基础小记
- 入侵某邮网络例子
- HTTP长链接
- PRML5-神经网络(1)
- 巧用nc命令搭建http请求调试工具
- android菜鸟学习笔记24----与服务器端交互(一)使用HttpURLConnection和HttpClient请求服务端数据
- 云计算和大数据时代网络技术揭秘(一)云计算的兴起
- 神经网络识别车牌字符
- http://objccn.io/
- 解决 HttpURLConnection类中getContentLength()方法返回-1问题
- 深度学习--深度信念网络(Deep Belief Network)
- linux kernel 网络协议栈之xps特性详解
- HTTP长连接与短连接
- 浅谈HTTP中Get与Post的区别
- fancy2D 源码解析 1 TestCpp
- Android利用网络编程HttpClient批量上传(一个)
- Server.UrlEncode、HttpUtility.UrlDecode的区别
- HTTP 协议详解
- Android网络请求框架Volley的使用