當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]【1】工具介紹:用到的工具:VS2015 語(yǔ)言:C/C++ 需要系統(tǒng)提供的動(dòng)態(tài)鏈接庫(kù):1、?sporder.dll????//很多系統(tǒng)不自帶著個(gè)dll,導(dǎo)致編譯時(shí)缺少dll無(wú)法編譯.?(發(fā)布時(shí)必須將此

【1】工具介紹:


用到的工具:VS2015
語(yǔ)言:C/C++
需要系統(tǒng)提供的動(dòng)態(tài)鏈接庫(kù):1、?sporder.dll????//很多系統(tǒng)不自帶著個(gè)dll,導(dǎo)致編譯時(shí)缺少dll無(wú)法編譯.?(發(fā)布時(shí)必須將此dll放到程序目錄)
本人只提供:???WIN7?64位的sporder.dll?:http://download.csdn.net/download/aaron133/10153240
???????????????其他系統(tǒng)自行網(wǎng)上下載.

安裝、移除LSP、編寫分層提供者DLL、測(cè)試程序的源碼:(申明:本人只在Win7?32/64位?和?Win10?64測(cè)試過(guò))
http://download.csdn.net/download/aaron133/10152873?
(除了文章中的源碼之外,包含了測(cè)試程序的源碼)


【2】編寫LSP分層服務(wù)提供者需知的概念:


1、先看我寫的SPI接口的概念:http://blog.csdn.net/aaron133/article/details/78005779

2、本章就是介紹安裝SPI的分層協(xié)議提供者(LSP),即第三方系統(tǒng)網(wǎng)絡(luò)組件。

3、當(dāng)Windows程序想要使用網(wǎng)絡(luò)時(shí),必須加載SPI的基礎(chǔ)提供者(TCP、UDP、原始)才能進(jìn)行網(wǎng)絡(luò)通訊。

4、安裝LSP分層服務(wù)提供者就是寫一個(gè)DLL,讓網(wǎng)絡(luò)程序先加載進(jìn)去調(diào)用,然后再我們的DLL內(nèi),再調(diào)用基礎(chǔ)服務(wù)提供者,進(jìn)行網(wǎng)絡(luò)通訊,所以在這過(guò)程中,我們可以對(duì)系統(tǒng)上所有使用特定協(xié)議的網(wǎng)絡(luò)程序,在用戶模式下進(jìn)行Winsock API調(diào)用監(jiān)控,HOOK攔截,甚至利用LSP注入DLL。

5、LSP一般是對(duì)網(wǎng)絡(luò)進(jìn)行更高級(jí)的通訊服務(wù)管理、過(guò)濾,黑客常用它來(lái)進(jìn)行瀏覽器劫持、監(jiān)控用戶信息等等.

6、360所謂的修復(fù)LSP或CMD的netsh winsock reset命令,就是清除第三方的LSP提供者,并清除它的DLL,留下系統(tǒng)的基礎(chǔ)服務(wù)提供者.


【3】不能攔截的Winsock API函數(shù):


1、htonl,htons僅在ws2_32.dll中實(shí)現(xiàn).
2、inet_addr,inet_ntoa,gethostname,WSACreateEvent,WSACloseEvent等等都不在SPI中.

3、如果程序直接使用傳輸驅(qū)動(dòng)接口(TDI)進(jìn)行TCP/IP發(fā)送數(shù)據(jù)包,那么攔截不了.

4、所以在用戶模式下,使用LSP過(guò)濾網(wǎng)絡(luò)封包是一個(gè)很好的選擇.

【4】LSP分層服務(wù)提供者的編寫:(DLL)


一、簡(jiǎn)述:

1、編寫LSP提供者就是寫一個(gè)DLL.

2、WSPStartup是LSP必須導(dǎo)出的函數(shù).

3、加載下層提供者的DLL,并調(diào)用它的初始化WSPStartup是LSP必須做的事情.

4、攔截API函數(shù)就是將下層提供者(基礎(chǔ)協(xié)議提供者)的函數(shù)地址記錄下來(lái),將我們自定義的函數(shù)地址替換上去,執(zhí)行到如send時(shí)就會(huì)先調(diào)用我們的自定義函數(shù),再由我們的自定義函數(shù),考慮要不要調(diào)用真正的send.


二、開始編寫LSP分層服務(wù)提供者的DLL:


【開始編寫】

1、步驟 :創(chuàng)建Win32程序 ? ? --> ? ? DLL開發(fā)

2、新建一個(gè).def文件:

EXPORTS
WSPStartup ? ? ?@2


【代碼步驟分析】

1、網(wǎng)絡(luò)程序加載LSP分層服務(wù)提供者的DLL,并調(diào)用了DLL里的WSPStartup初始化函數(shù).

2、在LSP的WSPStartup函數(shù)中,加載它的下層服務(wù)提供者的DLL,并調(diào)用它的WSPStartup初始化函數(shù).

3、對(duì)下層提供者的函數(shù)表地址進(jìn)行修改,修改感興趣的網(wǎng)絡(luò)函數(shù)指向我們的自定義函數(shù),進(jìn)行攔截、監(jiān)視Winsock API.

4、下面的例子中攔截了connect函數(shù)、sendto函數(shù).


頭文件: ? ? ??//在講解SPI篇的時(shí)候,用到的函數(shù),用于遍歷系統(tǒng)所有協(xié)議,包括分層協(xié)議

#include#include#includeLPWSAPROTOCOL_INFOW?GetProvider(LPINT?lpnTotalProtocols)
{//遍歷所有協(xié)議
int?nError?=?0;
DWORD?dwSize?=?0;
LPWSAPROTOCOL_INFOW?pProtoInfo?=?NULL;
if?(WSCEnumProtocols(NULL,?pProtoInfo,?&dwSize,?&nError)?==?SOCKET_ERROR)
{
if?(nError?!=?WSAENOBUFS)
return?NULL;
}
pProtoInfo?=?(LPWSAPROTOCOL_INFOW)new?WSAPROTOCOL_INFOW[dwSize?/?sizeof(WSAPROTOCOL_INFOW)];
if?(!pProtoInfo)
return?NULL;
ZeroMemory(pProtoInfo,?dwSize);
*lpnTotalProtocols?=?WSAEnumProtocols(NULL,?pProtoInfo,?&dwSize);
return?pProtoInfo;
}
void?FreeProvider(LPWSAPROTOCOL_INFOW?pProtoInfo)
{
delete[]?pProtoInfo;
}

源文件:

WSPPROC_TABLE?g_NextProcTable;??//下層提供者的函數(shù)表????????全局
//LSP的初始化函數(shù)(唯一的導(dǎo)出函數(shù))
int?WSPAPI?WSPStartup(
WORD?wVersionRequested,??????????????????????????//用戶程序加載套接字庫(kù)的版本號(hào)(in)
LPWSPDATA?lpWSPData,???????????????????????????????//用于取得Winsock服務(wù)的詳細(xì)信息
LPWSAPROTOCOL_INFO?lpProtocolInfo,???//指定想得到的協(xié)議的特征
WSPUPCALLTABLE?UpcallTable,?????????????????//Ws2_32.dll向上調(diào)用轉(zhuǎn)發(fā)的函數(shù)表
LPWSPPROC_TABLE?lpProTable?????????????????//下層提供者的函數(shù)表(一般為基礎(chǔ)協(xié)議,共30個(gè)服務(wù)函數(shù))
)
{???//如果協(xié)議位分層協(xié)議或基礎(chǔ)協(xié)議,那么返回錯(cuò)誤
if?(lpProtocolInfo->ProtocolChain.ChainLen?ProtocolChain.ChainEntries[1];
//遍歷所有協(xié)議
int?i?=?0;
for?(;?i?<?nTotalProtols;?i++)
{//找到下層提供者協(xié)議
if?(pProtoInfo[i].dwCatalogEntryId?==?dwBaseEntryId)
{
memcpy(&NextProtocolInfo,?&pProtoInfo[i],?sizeof(WSAPROTOCOL_INFOW));
break;
}
}
//如果沒(méi)找到
if?(i?>=?nTotalProtols)
return?WSAEPROVIDERFAILEDINIT;
//加載下層協(xié)議的Dll
int?nError?=?0;
TCHAR?szBaseProviderDll[MAX_PATH];
int?nLen?=?MAX_PATH;
//取得下層提供者的DLL路徑(可能包含壞境變量)
if(WSCGetProviderPath(&NextProtocolInfo.ProviderId,?szBaseProviderDll,?&nLen,?&nError)?==?SOCKET_ERROR)
return?WSAEPROVIDERFAILEDINIT;
//壞境變量轉(zhuǎn)換字符串
if(!ExpandEnvironmentStrings(szBaseProviderDll,?szBaseProviderDll,?MAX_PATH))
return?WSAEPROVIDERFAILEDINIT;
//加載dll
HMODULE?hModdule?=?LoadLibrary(szBaseProviderDll);
if(hModdule?==?NULL)
return?WSAEPROVIDERFAILEDINIT;
//取出下層提供者的WSPStartup函數(shù)
LPWSPSTARTUP?pfnWSPStartup?=?(LPWSPSTARTUP)GetProcAddress(hModdule,?"WSPStartup");
if(NULL?==?pfnWSPStartup?)
return?WSAEPROVIDERFAILEDINIT;
LPWSAPROTOCOL_INFOW?pInfo?=?lpProtocolInfo;
if?(NextProtocolInfo.ProtocolChain.ChainLen?==?BASE_PROTOCOL)//如果下層提供者是基礎(chǔ)協(xié)議
pInfo?=?&NextProtocolInfo;???????????????????????????????//賦給pInfo指針
//調(diào)用下層提供者的初始化函數(shù)
int?nRet?=?pfnWSPStartup(wVersionRequested,?lpWSPData,?lpProtocolInfo,?UpcallTable,?lpProTable);
//初始化失敗
if?(nRet?!=?ERROR_SUCCESS)
return?nRet;

//初始化完成后,復(fù)制下層提供者(基礎(chǔ)協(xié)議)的整個(gè)函數(shù)表
g_NextProcTable?=?*lpProTable;
//將基礎(chǔ)協(xié)議的SendTo函數(shù)指針,指向我們的WSPSendTo函數(shù),在我們的函數(shù)內(nèi),再確定要不要調(diào)用回基礎(chǔ)協(xié)議的Sendto函數(shù)
lpProTable->lpWSPSendTo?=?WSPSendTo;?
lpProTable->lpWSPConnect?=?WSPConnect;
FreeProvider(pProtoInfo,?nTotalProtols);
return?nRet;
}

//下面對(duì)sendto、connect函數(shù)的8888端口進(jìn)行攔截:

int?WSPAPI?WSPConnect(???????//自定義的WSPConnect函數(shù)
SOCKET?s,
const?struct?sockaddr?FAR?*?name,
int?namelen,
LPWSABUF?lpCallerData,
LPWSABUF?lpCalleeData,
LPQOS?lpSQOS,
LPQOS?lpGQOS,
LPINT?lpErrno
)
{
sockaddr_in*?info?=?(sockaddr_in*)name;
USHORT?port?=?ntohs(info->sin_port);
if?(port?==?8888)???//如果是8888端口,那么攔截
{
int?nError?=?0;
???????????????//因?yàn)檎麄€(gè)dll已經(jīng)加載進(jìn)程序里,這里對(duì)我的控制臺(tái)程序進(jìn)行測(cè)試
SetConsoleTitle(_T("sorry,we?shutdown?you?tcp?protocol?port!"));?
g_NextProcTable.lpWSPShutdown(s,?SD_BOTH,?&nError);
//設(shè)置錯(cuò)誤信息
*lpErrno?=?WSAECONNABORTED;???
return?SOCKET_ERROR;?
}
???????//如果不是,調(diào)用下層提供者的函數(shù)表中的WSPConnect函數(shù)
return?g_NextProcTable.lpWSPConnect(s,?name,?namelen,?lpCallerData,?lpCalleeData,?lpSQOS,?lpGQOS,?lpErrno);
}
int?WSPAPI?WSPSendTo?????????//自定義的WSPSendTo函數(shù)
(
SOCKET?s,
LPWSABUF?lpBuffers,
DWORD?dwBufferCount,
LPDWORD?lpNumberOfBytesSent,
DWORD?dwFlags,
const?struct?sockaddr?FAR?*?lpTo,
int?iTolen,
LPWSAOVERLAPPED?lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE?lpCompletionRoutine,
LPWSATHREADID?lpThreadId,
LPINT?lpErrno
)
{
sockaddr_in*?info?=?(sockaddr_in*)lpTo;
USHORT?port?=?ntohs(info->sin_port);
if?(port?==?8888)????//如果是8888端口,那么攔截
{
int?nError?=?0;
SetConsoleTitle(_T("sorry,we?shutdown?you?udp?protocol?port!"));
g_NextProcTable.lpWSPShutdown(s,?SD_BOTH,?&nError);
//設(shè)置錯(cuò)誤信息
*lpErrno?=?WSAECONNABORTED;
return?SOCKET_ERROR;
}
????????//如果不是,調(diào)用下層提供者的函數(shù)表中的WSPSendTo函數(shù)
return?g_NextProcTable.lpWSPSendTo(s,?lpBuffers,?dwBufferCount,?lpNumberOfBytesSent,?dwFlags,
lpTo,?iTolen,?lpOverlapped,?lpCompletionRoutine,?lpThreadId,?lpErrno);
}

【5】LSP的DLL編寫完成后,編寫安裝與卸載LSP的程序:


一、簡(jiǎn)述:1、安裝、卸載LSP必須是管理員用戶組的權(quán)限才能使用.2、下面的例子中,我一共安裝了1個(gè)分層協(xié)議(DLL),3個(gè)協(xié)議鏈(用于搶在TCP、UDP、原始套接字提供者前執(zhí)行)3、在http://blog.csdn.net/aaron133/article/details/78005779篇中的? ? ?“網(wǎng)絡(luò)程序是如何調(diào)用Winsock2 服務(wù)提供者進(jìn)行網(wǎng)絡(luò)通訊”? ? 調(diào)用網(wǎng)絡(luò)通訊的機(jī)制,所以要將新安裝的協(xié)議鏈,排在遍歷函數(shù)的最前面,網(wǎng)絡(luò)程序先找到適合的協(xié)議,就會(huì)用那個(gè)協(xié)議,如果排在后面,就可能載入別的相同類型的協(xié)議的提供者,而不使用我們的分層提供者.
二、開始編寫安裝LSP程序:
【編寫步驟分析】一、遍歷所有協(xié)議,將UDP、TCP、原始的Winsock目錄入口(結(jié)構(gòu)體)各復(fù)制一份出來(lái).二、隨便找一個(gè)下層協(xié)議(基礎(chǔ)服務(wù)提供者)的Winsock目錄入口結(jié)構(gòu)體作為模板,用于安裝LSP時(shí)作為它的Winsock目錄入口(結(jié)構(gòu)體).1、必須修改協(xié)議名稱(szProtocol成員).2、dwServiceFlags1成員必須將XP1_IFS_HANDLES標(biāo)志去掉.
3、提供者的類型:ProtocolChain成員ChainLen變量 = LAYERED_PROTOCOL(0) //0暗示為分層協(xié)議提供者 ? ?不懂這個(gè)概念的先看我上一篇講解SPI文章.//地址:http://blog.csdn.net/aaron133/article/details/78005779
4、表示方式:dwProviderFlags成員 = PFL_HIDDEN; //由提供者自己設(shè)置的Winsock目錄入口.5、安裝分層協(xié)議提供者.
三、安裝3個(gè)協(xié)議鏈(協(xié)議鏈,排在第一位的就是我們新安裝的分層提供者)1、為什么有3個(gè)協(xié)議鏈,因?yàn)樗鼈兏鲗?duì)應(yīng)一個(gè)基礎(chǔ)協(xié)議提供者,分別是TCP、UDP、原始,當(dāng)網(wǎng)絡(luò)程序使用TCP、UDP、原始,會(huì)先加載我們的分層服務(wù)提供者LSP的DLL。
四、重新排序Winsock目錄1、因?yàn)樾掳惭b的提供者,都會(huì)排在最后,這樣如果前面有網(wǎng)絡(luò)程序適合的提供者時(shí),就會(huì)直接載入它的DLL,而不載入我們LSP的DLL.頭文件:

#include#include#include#include#include#include#include#includeusing?namespace?std;
#pragma?warning(disable:4996)
#pragma?comment(lib,"Sporder.lib")
#pragma?comment(lib,?"Ws2_32.lib")
#include//安裝LSP
class?installLSP
{
public:
installLSP()
{
WSADATA?wsa;
WSAStartup(MAKEWORD(2,?2),?&wsa);
CoCreateGuid(&this->Layered_guid);
CoCreateGuid(&this->AgreementChain_guid);
}
~installLSP()
{
WSACleanup();
}
public:
//安裝LSP,并安裝3個(gè)協(xié)議鏈
BOOL?InstallProvider(WCHAR*?wszDllPath)??//參數(shù):LSP的DLL的地址
{
WCHAR?wszLSPName[]?=?_T("AaronLSP");
LPWSAPROTOCOL_INFOW?pProtoInfo?=?NULL;
int?nProtocols?=?0;?//分層協(xié)議?????取出來(lái)的模板
WSAPROTOCOL_INFOW?OriginalProtocolInfo[3];?//數(shù)組成員為TCP、UDP、原始的目錄入口信息
DWORD?dwOrigCatalogId[3];?//記錄入口ID號(hào)
int?nArrayCount?=?0;??????//數(shù)組個(gè)數(shù)索引
DWORD?dwLayeredCatalogId;?//分層協(xié)議的入口ID號(hào)
int?nError;
pProtoInfo?=?GetProvider(&nProtocols);
if?(nProtocols?<?1?||?pProtoInfo?==?NULL)
return?FALSE;
BOOL?bFindUdp?=?FALSE;
BOOL?bFindTcp?=?FALSE;
BOOL?bFindRaw?=?FALSE;
for?(int?i?=?0;?i?<?nProtocols;?i++)
{???//查找地址族為AF_INET的協(xié)議
if?(pProtoInfo[i].iAddressFamily?==?AF_INET)
{
if?(!bFindUdp?&&?pProtoInfo[i].iProtocol?==?IPPROTO_UDP)
{
memcpy(&OriginalProtocolInfo[nArrayCount],?&pProtoInfo[i],?sizeof(WSAPROTOCOL_INFOW));
//去除XP1_IFS_HANDLES標(biāo)志,防止提供者返回的句柄是真正的操作系統(tǒng)句柄
OriginalProtocolInfo[nArrayCount].dwServiceFlags1?&=?(~XP1_IFS_HANDLES);
//記錄目錄入口ID
dwOrigCatalogId[nArrayCount++]?=?pProtoInfo[i].dwCatalogEntryId;?
bFindUdp?=?TRUE;
}
if?(!bFindTcp?&&?pProtoInfo[i].iProtocol?==?IPPROTO_TCP)
{
memcpy(&OriginalProtocolInfo[nArrayCount],?&pProtoInfo[i],?sizeof(WSAPROTOCOL_INFOW));
//去除XP1_IFS_HANDLES標(biāo)志,防止提供者返回的句柄是真正的操作系統(tǒng)句柄
OriginalProtocolInfo[nArrayCount].dwServiceFlags1?&=?(~XP1_IFS_HANDLES);
//記錄目錄入口ID
dwOrigCatalogId[nArrayCount++]?=?pProtoInfo[i].dwCatalogEntryId;
bFindTcp?=?TRUE;
}
if?(!bFindRaw?&&?pProtoInfo[i].iProtocol?==?IPPROTO_IP)
{
memcpy(&OriginalProtocolInfo[nArrayCount],?&pProtoInfo[i],?sizeof(WSAPROTOCOL_INFOW));
//去除XP1_IFS_HANDLES標(biāo)志,防止提供者返回的句柄是真正的操作系統(tǒng)句柄
OriginalProtocolInfo[nArrayCount].dwServiceFlags1?&=?(~XP1_IFS_HANDLES);
//記錄目錄入口ID
dwOrigCatalogId[nArrayCount++]?=?pProtoInfo[i].dwCatalogEntryId;
bFindRaw?=?TRUE;
}
}
}
if?(nArrayCount?==?0)
{
FreeProvider(pProtoInfo);
return?FALSE;
}
//安裝LSP分層協(xié)議
WSAPROTOCOL_INFOW?LayeredProtocolInfo;


memcpy(&LayeredProtocolInfo,?&OriginalProtocolInfo[0],?sizeof(WSAPROTOCOL_INFOW));
//修改協(xié)議名稱的字符串
wcscpy(LayeredProtocolInfo.szProtocol,?wszLSPName);
//表示分層協(xié)議
LayeredProtocolInfo.ProtocolChain.ChainLen?=?LAYERED_PROTOCOL;//0
//表示方式為由提供者自己設(shè)置
LayeredProtocolInfo.dwProviderFlags?=?PFL_HIDDEN;
//安裝分層協(xié)議
if?(SOCKET_ERROR?==?WSCInstallProvider(&Layered_guid,?wszDllPath,?&LayeredProtocolInfo,?1,?&nError))
{
FreeProvider(pProtoInfo);
return?FALSE;
}
FreeProvider(pProtoInfo);
//重新遍歷協(xié)議,獲取分層協(xié)議的目錄ID號(hào)
pProtoInfo?=?GetProvider(&nProtocols);
if?(nProtocols?<?1?||?pProtoInfo?==?NULL)
return?FALSE;
for?(int?i?=?0;?i?<?nProtocols;?i++)//一般安裝新入口后,會(huì)排在最低部
{
if?(memcmp(&pProtoInfo[i].ProviderId,?&Layered_guid,?sizeof(GUID))?==?0)
{
//取出分層協(xié)議的目錄入口ID
dwLayeredCatalogId?=?pProtoInfo[i].dwCatalogEntryId;
break;
}
}
//安裝協(xié)議鏈?????????????????256
WCHAR?wszChainName[WSAPROTOCOL_LEN?+?1];//新分層協(xié)議的名稱??over???取出來(lái)的入口模板的名稱
for?(int?i?=?0;?i?<?nArrayCount;?i++)
{
swprintf(wszChainName,?_T("%s?over?%s"),?wszLSPName,?OriginalProtocolInfo[i].szProtocol);
wcscpy(OriginalProtocolInfo[i].szProtocol,?wszChainName);??//將這個(gè)模板的名稱改成新名稱↑
if?(OriginalProtocolInfo[i].ProtocolChain.ChainLen?==?1)//這是基礎(chǔ)協(xié)議的模板
{???//修改基礎(chǔ)協(xié)議模板的協(xié)議鏈,?在協(xié)議鏈[1]寫入真正UDP[基礎(chǔ)協(xié)議]的入口ID
OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1]?=?dwOrigCatalogId[i];
}
else
{//如果大于1,相當(dāng)于是個(gè)協(xié)議鏈,表示:將協(xié)議鏈中的入口ID,全部向后退一格,留出[0]
for?(int?j?=?OriginalProtocolInfo[i].ProtocolChain.ChainLen;?j?>?0;?j--)
OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j]?=?OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j?-?1];
}
//讓新分層協(xié)議排在基礎(chǔ)協(xié)議的前面(如果為協(xié)議鏈排就排在開頭了)
OriginalProtocolInfo[i].ProtocolChain.ChainLen++;
OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0]?=?dwLayeredCatalogId;
}
//一次安裝3個(gè)協(xié)議鏈
if?(SOCKET_ERROR?==?WSCInstallProvider(&AgreementChain_guid,?wszDllPath,?OriginalProtocolInfo,?nArrayCount,?&nError))
{
FreeProvider(pProtoInfo);
return?FALSE;
}
//第三步:將所有3種協(xié)議進(jìn)行重新排序,以讓系統(tǒng)先調(diào)用我們的協(xié)議(讓協(xié)議鏈排第一,協(xié)議鏈中[0]是新分層協(xié)議,[1]基礎(chǔ)UDP協(xié)議)
//重新遍歷所有協(xié)議
FreeProvider(pProtoInfo);
pProtoInfo?=?GetProvider(&nProtocols);
if?(nProtocols?<?1?||?pProtoInfo?==?NULL)
return?FALSE;
DWORD?dwIds[20];
int?nIndex?=?0;
//添加我們的協(xié)議鏈
for?(int?i?=?0;?i?<?nProtocols;?i++)
{//如果是我們新創(chuàng)建的協(xié)議鏈
if?(pProtoInfo[i].ProtocolChain.ChainLen?>?1?&&?pProtoInfo[i].ProtocolChain.ChainEntries[0]?==?dwLayeredCatalogId)
dwIds[nIndex++]?=?pProtoInfo[i].dwCatalogEntryId;//將3個(gè)協(xié)議鏈排在前3
}
//添加其他協(xié)議
for?(int?i?=?0;?i?<?nProtocols;?i++)
{//如果是基礎(chǔ)協(xié)議,分層協(xié)議(不包括我們的協(xié)議鏈,但包括我們的分層協(xié)議)
if?(pProtoInfo[i].ProtocolChain.ChainLen?<=?1?||?pProtoInfo[i].ProtocolChain.ChainEntries[0]?!=?dwLayeredCatalogId)
dwIds[nIndex++]?=?pProtoInfo[i].dwCatalogEntryId;
}
//重新排序Winsock目錄
if?(WSCWriteProviderOrder(dwIds,?nIndex)?!=?ERROR_SUCCESS)
return?FALSE;
FreeProvider(pProtoInfo);
return?TRUE;
}
????????//卸載LSP
void?RemoveProvider()
{
LPWSAPROTOCOL_INFOW?pProtoInfo?=?NULL;
int?nProtocols?=?0;
DWORD?dwLayeredCatalogId?=?0;?//分層協(xié)議提供者的入口ID號(hào)
?//遍歷出所有協(xié)議
pProtoInfo?=?GetProvider(&nProtocols);
if?(nProtocols?<?1?||?pProtoInfo?==?NULL)
return;
int?nError?=?0;
int?i?=?0;
for?(i?=?0;?i?<?nProtocols;?i++)
{?//查找分層協(xié)議提供者
if?(memcmp(&Layered_guid,?&pProtoInfo[i].ProviderId,?sizeof(GUID))?==?0)
{
dwLayeredCatalogId?=?pProtoInfo[i].dwCatalogEntryId;
break;
}
}
if?(i?<?nProtocols)
{
for?(i?=?0;?i?<?nProtocols;?i++)
{//查找協(xié)議鏈(這個(gè)協(xié)議鏈的[0]為分層協(xié)議提供者)
if?(pProtoInfo[i].ProtocolChain.ChainLen?>?1?&&?pProtoInfo[i].ProtocolChain.ChainEntries[0]?==?dwLayeredCatalogId)
{//先卸載協(xié)議鏈
WSCDeinstallProvider(&pProtoInfo[i].ProviderId,?&nError);
break;
}
}
WSCDeinstallProvider(&Layered_guid,?&nError);
}
}
private:
???????//這兩個(gè)函數(shù)是遍歷所有協(xié)議函數(shù),在編寫DLL時(shí),已經(jīng)把源代碼放出來(lái)了,這里就不放出來(lái)了.
???????LPWSAPROTOCOL_INFOW?GetProvider(LPINT?lpnTotalProtocols);
???????void?FreeProvider(LPWSAPROTOCOL_INFOW?pProtoInfo);?
private:
GUID?Layered_guid;????????//分層協(xié)議GUID
GUID?AgreementChain_guid;?//協(xié)議鏈GUID
};

源文件:

#include?"Hello.h"
#define?PATH?_T("C:\Users\Administrator\Desktop\實(shí)例\網(wǎng)絡(luò)實(shí)驗(yàn)\安裝LSP服務(wù)提供程序\LSPDll\Debug\LSPDll.dll")
int?main(int?argc,char**?argv)
{
system("color?4e");
SetConsoleTitle(_T("安裝LSP提供者程序?qū)嶒?yàn)"));
ProtocolTraversestheExperiment2?s;
printf("安裝LSP前的所有協(xié)議:rn");
s.ShowAllProtocol();
installLSP?LSP;
LSP.InstallProvider(PATH);
printf("安裝LSP后的所有協(xié)議:rn");
s.ShowAllProtocol();
getchar();
LSP.RemoveProvider();
printf("清除LSP完成rn");
getchar();
return?0;
}


【測(cè)試】1、安裝了一個(gè)LSP分層服務(wù)提供者(相當(dāng)于HOOK了TCP、UDP、原始套接字),三個(gè)協(xié)議鏈


2、當(dāng)有程序使用8888端口進(jìn)行TCP連接或8888端口使用UDP發(fā)送數(shù)據(jù)時(shí),就會(huì)攔截禁止:
附加說(shuō)明:1、Sporder.dll在編寫LSP程序時(shí),32位放在WOWSys64文件夾、64位放在system32文件夾.2、發(fā)布時(shí)必須攜帶著Sporder.dll在程序目錄存放.3、編寫64位LSP程序的程序時(shí),不要包含#pragma comment(lib,"Sporder.lib")否則程序出錯(cuò)!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉