、、、首先我不是原創、、、、、
轉載別人的然後自己學習,網上有很多資料。大家可以先看《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>
。。。。。