您的位置:首页 > 理论基础 > 计算机网络

基于SPI的LSP网络封包截获

2015-07-13 22:02 691 查看
、、、首先我不是原创、、、、、

转载别人的然后自己学习,网上有很多资料。大家可以先看《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>
。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: