【1】工具介绍:

用到的工具:VS2015
语言:C/C++
需要系统提供的动态链接库:1、 sporder.dll    //很多系统不自带着个dll,导致编译时缺少dll无法编译. (发布时必须将此dll放到程序目录)
本人只提供:   WIN7 64位的sporder.dll :http://download.csdn.net/download/aaron133/10153240其他系统自行网上下载.

安装、移除LSP、编写分层提供者DLL、测试程序的源码:(申明:本人只在Win7 32/64位 和 Win10 64测试过)
http://download.csdn.net/download/aaron133/10152873
(除了文章中的源码之外,包含了测试程序的源码)

【2】编写LSP分层服务提供者需知的概念:

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

2、本章就是介绍安装SPI的分层协议提供者(LSP),即第三方系统网络组件。

3、当Windows程序想要使用网络时,必须加载SPI的基础提供者(TCP、UDP、原始)才能进行网络通讯。

4、安装LSP分层服务提供者就是写一个DLL,让网络程序先加载进去调用,然后再我们的DLL内,再调用基础服务提供者,进行网络通讯,所以在这过程中,我们可以对系统上所有使用特定协议的网络程序,在用户模式下进行Winsock API调用监控,HOOK拦截,甚至利用LSP注入DLL。

5、LSP一般是对网络进行更高级的通讯服务管理、过滤,黑客常用它来进行浏览器劫持、监控用户信息等等.

6、360所谓的修复LSP或CMD的netsh winsock reset命令,就是清除第三方的LSP提供者,并清除它的DLL,留下系统的基础服务提供者.

【3】不能拦截的Winsock API函数:

1、htonl,htons仅在ws2_32.dll中实现.
2、inet_addr,inet_ntoa,gethostname,WSACreateEvent,WSACloseEvent等等都不在SPI中.

3、如果程序直接使用传输驱动接口(TDI)进行TCP/IP发送数据包,那么拦截不了.

4、所以在用户模式下,使用LSP过滤网络封包是一个很好的选择.

【4】LSP分层服务提供者的编写:(DLL)

一、简述:

1、编写LSP提供者就是写一个DLL.

2、WSPStartup是LSP必须导出的函数.

3、加载下层提供者的DLL,并调用它的初始化WSPStartup是LSP必须做的事情.

4、拦截API函数就是将下层提供者(基础协议提供者)的函数地址记录下来,将我们自定义的函数地址替换上去,执行到如send时就会先调用我们的自定义函数,再由我们的自定义函数,考虑要不要调用真正的send.

二、开始编写LSP分层服务提供者的DLL:

【开始编写】

1、步骤 :创建Win32程序     -->     DLL开发

2、新建一个.def文件:

EXPORTS
WSPStartup      @2

【代码步骤分析】

1、网络程序加载LSP分层服务提供者的DLL,并调用了DLL里的WSPStartup初始化函数.

2、在LSP的WSPStartup函数中,加载它的下层服务提供者的DLL,并调用它的WSPStartup初始化函数.

3、对下层提供者的函数表地址进行修改,修改感兴趣的网络函数指向我们的自定义函数,进行拦截、监视Winsock API.

4、下面的例子中拦截了connect函数、sendto函数.

头文件:       //在讲解SPI篇的时候,用到的函数,用于遍历系统所有协议,包括分层协议

  1. #include <WinSock2.h>
  2. #include <WS2spi.h>
  3. #include <tchar.h>
  4. LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
  5. {//遍历所有协议
  6. int nError = 0;
  7. DWORD dwSize = 0;
  8. LPWSAPROTOCOL_INFOW pProtoInfo = NULL;
  9. if (WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)
  10. {
  11. if (nError != WSAENOBUFS)
  12. return NULL;
  13. }
  14. pProtoInfo = (LPWSAPROTOCOL_INFOW)new WSAPROTOCOL_INFOW[dwSize / sizeof(WSAPROTOCOL_INFOW)];
  15. if (!pProtoInfo)
  16. return NULL;
  17. ZeroMemory(pProtoInfo, dwSize);
  18. lpnTotalProtocols = WSAEnumProtocols(NULL, pProtoInfo, &dwSize);
  19. return pProtoInfo;
  20. }
  21. void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
  22. {
  23. delete[] pProtoInfo;
  24. }

源文件:

  1. WSPPROC_TABLE g_NextProcTable; //下层提供者的函数表 全局
  2. //LSP的初始化函数(唯一的导出函数)
  3. int WSPAPI WSPStartup(
  4. WORD wVersionRequested, //用户程序加载套接字库的版本号(in)
  5. LPWSPDATA lpWSPData, //用于取得Winsock服务的详细信息
  6. LPWSAPROTOCOL_INFO lpProtocolInfo, //指定想得到的协议的特征
  7. WSPUPCALLTABLE UpcallTable, //Ws2_32.dll向上调用转发的函数表
  8. LPWSPPROC_TABLE lpProTable //下层提供者的函数表(一般为基础协议,共30个服务函数)
  9. )
  10. { //如果协议位分层协议或基础协议,那么返回错误
  11. if (lpProtocolInfo->ProtocolChain.ChainLen <= 1)
  12. { //无法加载或初始化请求的服务提供程序
  13. return WSAEPROVIDERFAILEDINIT;
  14. }
  15. //找到下层协议的WSAPROTOCOL_INFOW结构体
  16. WSAPROTOCOL_INFOW NextProtocolInfo;
  17. int nTotalProtols;
  18. LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtols);
  19. //下层提供者的入口ID
  20. DWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries[1];
  21. //遍历所有协议
  22. int i = 0;
  23. for (; i < nTotalProtols; i++)
  24. {//找到下层提供者协议
  25. if (pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId)
  26. {
  27. memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));
  28. break;
  29. }
  30. }
  31. //如果没找到
  32. if (i >= nTotalProtols)
  33. return WSAEPROVIDERFAILEDINIT;
  34. //加载下层协议的Dll
  35. int nError = 0;
  36. TCHAR szBaseProviderDll[MAX_PATH];
  37. int nLen = MAX_PATH;
  38. //取得下层提供者的DLL路径(可能包含坏境变量)
  39. if(WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR)
  40. return WSAEPROVIDERFAILEDINIT;
  41. //坏境变量转换字符串
  42. if(!ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH))
  43. return WSAEPROVIDERFAILEDINIT;
  44. //加载dll
  45. HMODULE hModdule = LoadLibrary(szBaseProviderDll);
  46. if(hModdule == NULL)
  47. return WSAEPROVIDERFAILEDINIT;
  48. //取出下层提供者的WSPStartup函数
  49. LPWSPSTARTUP pfnWSPStartup = (LPWSPSTARTUP)GetProcAddress(hModdule, “WSPStartup”);
  50. if(NULL == pfnWSPStartup )
  51. return WSAEPROVIDERFAILEDINIT;
  52. LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo;
  53. if (NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL)//如果下层提供者是基础协议
  54. pInfo = &NextProtocolInfo; //赋给pInfo指针
  55. //调用下层提供者的初始化函数
  56. int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, lpProtocolInfo, UpcallTable, lpProTable);
  57. //初始化失败
  58. if (nRet != ERROR_SUCCESS)
  59. return nRet;
  60. //初始化完成后,复制下层提供者(基础协议)的整个函数表
  61. g_NextProcTable = lpProTable;
  62. //将基础协议的SendTo函数指针,指向我们的WSPSendTo函数,在我们的函数内,再确定要不要调用回基础协议的Sendto函数
  63. lpProTable->lpWSPSendTo = WSPSendTo;
  64. lpProTable->lpWSPConnect = WSPConnect;
  65. FreeProvider(pProtoInfo, nTotalProtols);
  66. return nRet;
  67. }

//下面对sendto、connect函数的8888端口进行拦截:

  1. int WSPAPI WSPConnect( //自定义的WSPConnect函数
  2. SOCKET s,
  3. const struct sockaddr FAR * name,
  4. int namelen,
  5. LPWSABUF lpCallerData,
  6. LPWSABUF lpCalleeData,
  7. LPQOS lpSQOS,
  8. LPQOS lpGQOS,
  9. LPINT lpErrno
  10. )
  11. {
  12. sockaddr_in info = (sockaddr_in)name;
  13. USHORT port = ntohs(info->sin_port);
  14. if (port == 8888) //如果是8888端口,那么拦截
  15. {
  16. int nError = 0;
  17. //因为整个dll已经加载进程序里,这里对我的控制台程序进行测试
  18. SetConsoleTitle(_T(“sorry,we shutdown you tcp protocol port<8888>!”));
  19. g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &nError);
  20. //设置错误信息
  21. lpErrno = WSAECONNABORTED;
  22. return SOCKET_ERROR;
  23. }
  24. //如果不是,调用下层提供者的函数表中的WSPConnect函数
  25. return g_NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);
  26. }
  27. int WSPAPI WSPSendTo //自定义的WSPSendTo函数
  28. (
  29. SOCKET s,
  30. LPWSABUF lpBuffers,
  31. DWORD dwBufferCount,
  32. LPDWORD lpNumberOfBytesSent,
  33. DWORD dwFlags,
  34. const struct sockaddr FAR * lpTo,
  35. int iTolen,
  36. LPWSAOVERLAPPED lpOverlapped,
  37. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  38. LPWSATHREADID lpThreadId,
  39. LPINT lpErrno
  40. )
  41. {
  42. sockaddr_in info = (sockaddr_in*)lpTo;
  43. USHORT port = ntohs(info->sin_port);
  44. if (port == 8888) //如果是8888端口,那么拦截
  45. {
  46. int nError = 0;
  47. SetConsoleTitle(_T(“sorry,we shutdown you udp protocol port<8888>!”));
  48. g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &nError);
  49. //设置错误信息
  50. lpErrno = WSAECONNABORTED;
  51. return SOCKET_ERROR;
  52. }
  53. //如果不是,调用下层提供者的函数表中的WSPSendTo函数
  54. return g_NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
  55. lpTo, iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
  56. }

【5】LSP的DLL编写完成后,编写安装与卸载LSP的程序:

一、简述:
1、安装、卸载LSP必须是管理员用户组的权限才能使用.
2、下面的例子中,我一共安装了1个分层协议(DLL),3个协议链用于抢在TCP、UDP、原始套接字提供者前执行)
3、在http://blog.csdn.net/aaron133/article/details/78005779篇中的
“网络程序是如何调用Winsock2 服务提供者进行网络通讯”
调用网络通讯的机制,所以要将新安装的协议链,排在遍历函数的最前面,网络程序先找到适合的协议,就会用那个协议,如果排在后面,就可能载入别的相同类型的协议的提供者,而不使用我们的分层提供者.
二、开始编写安装LSP程序:
【编写步骤分析】
一、遍历所有协议,将UDP、TCP、原始的Winsock目录入口(结构体)各复制一份出来.
二、随便找一个下层协议(基础服务提供者)Winsock目录入口结构体作为模板,用于安装LSP时作为它的Winsock目录入口(结构体).
1、必须修改协议名称(szProtocol成员).
2、dwServiceFlags1成员必须将XP1_IFS_HANDLES标志去掉.
3、提供者的类型:ProtocolChain成员ChainLen变量 = LAYERED_PROTOCOL(0) //0暗示为分层协议提供者    
不懂这个概念的先看我上一篇讲解SPI文章.//地址:http://blog.csdn.net/aaron133/article/details/78005779
4、表示方式:dwProviderFlags成员 = PFL_HIDDEN; //由提供者自己设置的Winsock目录入口.
5、安装分层协议提供者.
三、安装3个协议链(协议链,排在第一位的就是我们新安装的分层提供者)
1、为什么有3个协议链,因为它们各对应一个基础协议提供者,分别是TCP、UDP、原始,当网络程序使用TCP、UDP、原始,会先加载我们的分层服务提供者LSP的DLL。
四、重新排序Winsock目录
1、因为新安装的提供者,都会排在最后,这样如果前面有网络程序适合的提供者时,就会直接载入它的DLL,而不载入我们LSP的DLL.
头文件:
  1. #include <WS2spi.h>
  2. #include <winsock2.h>
  3. #include <process.h>
  4. #include <ws2tcpip.h>
  5. #include <mstcpip.h>
  6. #include <Windows.h>
  7. #include <iostream>
  8. #include <tchar.h>
  9. using namespace std;
  10. #pragma warning(disable:4996)
  11. #pragma comment(lib,“Sporder.lib”)
  12. #pragma comment(lib, “Ws2_32.lib”)
  13. #include <sporder.h>
  14. //安装LSP
  15. class installLSP
  16. {
  17. public:
  18. installLSP()
  19. {
  20. WSADATA wsa;
  21. WSAStartup(MAKEWORD(2, 2), &wsa);
  22. CoCreateGuid(&this->Layered_guid);
  23. CoCreateGuid(&this->AgreementChain_guid);
  24. }
  25. ~installLSP()
  26. {
  27. WSACleanup();
  28. }
  29. public:
  30. //安装LSP,并安装3个协议链
  31. BOOL InstallProvider(WCHAR wszDllPath) //参数:LSP的DLL的地址
  32. {
  33. WCHAR wszLSPName[] = _T(“AaronLSP”);
  34. LPWSAPROTOCOL_INFOW pProtoInfo = NULL;
  35. int nProtocols = 0; //分层协议 取出来的模板
  36. WSAPROTOCOL_INFOW OriginalProtocolInfo[3]; //数组成员为TCP、UDP、原始的目录入口信息
  37. DWORD dwOrigCatalogId[3]; //记录入口ID号
  38. int nArrayCount = 0; //数组个数索引
  39. DWORD dwLayeredCatalogId; //分层协议的入口ID号
  40. int nError;
  41. pProtoInfo = GetProvider(&nProtocols);
  42. if (nProtocols < 1 || pProtoInfo == NULL)
  43. return FALSE;
  44. BOOL bFindUdp = FALSE;
  45. BOOL bFindTcp = FALSE;
  46. BOOL bFindRaw = FALSE;
  47. for (int i = 0; i < nProtocols; i++)
  48. { //查找地址族为AF_INET的协议
  49. if (pProtoInfo[i].iAddressFamily == AF_INET)
  50. {
  51. if (!bFindUdp && pProtoInfo[i].iProtocol == IPPROTO_UDP)
  52. {
  53. memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));
  54. //去除XP1_IFS_HANDLES标志,防止提供者返回的句柄是真正的操作系统句柄
  55. OriginalProtocolInfo[nArrayCount].dwServiceFlags1 &= (~XP1_IFS_HANDLES);
  56. //记录目录入口ID
  57. dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;
  58. bFindUdp = TRUE;
  59. }
  60. if (!bFindTcp && pProtoInfo[i].iProtocol == IPPROTO_TCP)
  61. {
  62. memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));
  63. //去除XP1_IFS_HANDLES标志,防止提供者返回的句柄是真正的操作系统句柄
  64. OriginalProtocolInfo[nArrayCount].dwServiceFlags1 &= (~XP1_IFS_HANDLES);
  65. //记录目录入口ID
  66. dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;
  67. bFindTcp = TRUE;
  68. }
  69. if (!bFindRaw && pProtoInfo[i].iProtocol == IPPROTO_IP)
  70. {
  71. memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW));
  72. //去除XP1_IFS_HANDLES标志,防止提供者返回的句柄是真正的操作系统句柄
  73. OriginalProtocolInfo[nArrayCount].dwServiceFlags1 &= (~XP1_IFS_HANDLES);
  74. //记录目录入口ID
  75. dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId;
  76. bFindRaw = TRUE;
  77. }
  78. }
  79. }
  80. if (nArrayCount == 0)
  81. {
  82. FreeProvider(pProtoInfo);
  83. return FALSE;
  84. }
  85. //安装LSP分层协议
  86. WSAPROTOCOL_INFOW LayeredProtocolInfo;
  87. memcpy(&LayeredProtocolInfo, &OriginalProtocolInfo[0], sizeof(WSAPROTOCOL_INFOW));
  88. //修改协议名称的字符串
  89. wcscpy(LayeredProtocolInfo.szProtocol, wszLSPName);
  90. //表示分层协议
  91. LayeredProtocolInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL;//0
  92. //表示方式为由提供者自己设置
  93. LayeredProtocolInfo.dwProviderFlags = PFL_HIDDEN;
  94. //安装分层协议
  95. if (SOCKET_ERROR == WSCInstallProvider(&Layered_guid, wszDllPath, &LayeredProtocolInfo, 1, &nError))
  96. {
  97. FreeProvider(pProtoInfo);
  98. return FALSE;
  99. }
  100. FreeProvider(pProtoInfo);
  101. //重新遍历协议,获取分层协议的目录ID号
  102. pProtoInfo = GetProvider(&nProtocols);
  103. if (nProtocols < 1 || pProtoInfo == NULL)
  104. return FALSE;
  105. for (int i = 0; i < nProtocols; i++)//一般安装新入口后,会排在最低部
  106. {
  107. if (memcmp(&pProtoInfo[i].ProviderId, &Layered_guid, sizeof(GUID)) == 0)
  108. {
  109. //取出分层协议的目录入口ID
  110. dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
  111. break;
  112. }
  113. }
  114. //安装协议链 256
  115. WCHAR wszChainName[WSAPROTOCOL_LEN + 1];//新分层协议的名称 over 取出来的入口模板的名称
  116. for (int i = 0; i < nArrayCount; i++)
  117. {
  118. swprintf(wszChainName, _T("%s over %s"), wszLSPName, OriginalProtocolInfo[i].szProtocol);
  119. wcscpy(OriginalProtocolInfo[i].szProtocol, wszChainName); //将这个模板的名称改成新名称↑
  120. if (OriginalProtocolInfo[i].ProtocolChain.ChainLen == 1)//这是基础协议的模板
  121. { //修改基础协议模板的协议链, 在协议链[1]写入真正UDP[基础协议]的入口ID
  122. OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1] = dwOrigCatalogId[i];
  123. }
  124. else
  125. {//如果大于1,相当于是个协议链,表示:将协议链中的入口ID,全部向后退一格,留出[0]
  126. for (int j = OriginalProtocolInfo[i].ProtocolChain.ChainLen; j > 0; j–)
  127. OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j] = OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j - 1];
  128. }
  129. //让新分层协议排在基础协议的前面(如果为协议链排就排在开头了)
  130. OriginalProtocolInfo[i].ProtocolChain.ChainLen++;
  131. OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0] = dwLayeredCatalogId;
  132. }
  133. //一次安装3个协议链
  134. if (SOCKET_ERROR == WSCInstallProvider(&AgreementChain_guid, wszDllPath, OriginalProtocolInfo, nArrayCount, &nError))
  135. {
  136. FreeProvider(pProtoInfo);
  137. return FALSE;
  138. }
  139. //第三步:将所有3种协议进行重新排序,以让系统先调用我们的协议(让协议链排第一,协议链中[0]是新分层协议,[1]基础UDP协议)
  140. //重新遍历所有协议
  141. FreeProvider(pProtoInfo);
  142. pProtoInfo = GetProvider(&nProtocols);
  143. if (nProtocols < 1 || pProtoInfo == NULL)
  144. return FALSE;
  145. DWORD dwIds[20];
  146. int nIndex = 0;
  147. //添加我们的协议链
  148. for (int i = 0; i < nProtocols; i++)
  149. {//如果是我们新创建的协议链
  150. if (pProtoInfo[i].ProtocolChain.ChainLen > 1 && pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId)
  151. dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;//将3个协议链排在前3
  152. }
  153. //添加其他协议
  154. for (int i = 0; i < nProtocols; i++)
  155. {//如果是基础协议,分层协议(不包括我们的协议链,但包括我们的分层协议)
  156. if (pProtoInfo[i].ProtocolChain.ChainLen <= 1 || pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId)
  157. dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
  158. }
  159. //重新排序Winsock目录
  160. if (WSCWriteProviderOrder(dwIds, nIndex) != ERROR_SUCCESS)
  161. return FALSE;
  162. FreeProvider(pProtoInfo);
  163. return TRUE;
  164. }
  165. //卸载LSP
  166. void RemoveProvider()
  167. {
  168. LPWSAPROTOCOL_INFOW pProtoInfo = NULL;
  169. int nProtocols = 0;
  170. DWORD dwLayeredCatalogId = 0; //分层协议提供者的入口ID号
  171. //遍历出所有协议
  172. pProtoInfo = GetProvider(&nProtocols);
  173. if (nProtocols < 1 || pProtoInfo == NULL)
  174. return;
  175. int nError = 0;
  176. int i = 0;
  177. for (i = 0; i < nProtocols; i++)
  178. { //查找分层协议提供者
  179. if (memcmp(&Layered_guid, &pProtoInfo[i].ProviderId, sizeof(GUID)) == 0)
  180. {
  181. dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
  182. break;
  183. }
  184. }
  185. if (i < nProtocols)
  186. {
  187. for (i = 0; i < nProtocols; i++)
  188. {//查找协议链(这个协议链的[0]为分层协议提供者)
  189. if (pProtoInfo[i].ProtocolChain.ChainLen > 1 && pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId)
  190. {//先卸载协议链
  191. WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);
  192. break;
  193. }
  194. }
  195. WSCDeinstallProvider(&Layered_guid, &nError);
  196. }
  197. }
  198. private:
  199. //这两个函数是遍历所有协议函数,在编写DLL时,已经把源代码放出来了,这里就不放出来了.
  200. LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols);
  201. void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo);
  202. private:
  203. GUID Layered_guid; //分层协议GUID
  204. GUID AgreementChain_guid; //协议链GUID
  205. };
源文件:
  1. #include “Hello.h”
  2. #define PATH _T(“C:\Users\Administrator\Desktop\实例\网络实验\安装LSP服务提供程序\LSPDll\Debug\LSPDll.dll”)
  3. int main(int argc,char** argv)
  4. {
  5. system(“color 4e”);
  6. SetConsoleTitle(_T(“安装LSP提供者程序实验”));
  7. ProtocolTraversestheExperiment2 s;
  8. printf(“安装LSP前的所有协议:\r\n”);
  9. s.ShowAllProtocol();
  10. installLSP LSP;
  11. LSP.InstallProvider(PATH);
  12. printf(“安装LSP后的所有协议:\r\n”);
  13. s.ShowAllProtocol();
  14. getchar();
  15. LSP.RemoveProvider();
  16. printf(“清除LSP完成\r\n”);
  17. getchar();
  18. return 0;
  19. }

【测试】

1、安装了一个LSP分层服务提供者(相当于HOOK了TCP、UDP、原始套接字),三个协议链
2、当有程序使用8888端口进行TCP连接或8888端口使用UDP发送数据时,就会拦截禁止:
附加说明:
1、Sporder.dll在编写LSP程序时,32位放在WOWSys64文件夹、64位放在system32文件夹.
2、发布时必须携带着Sporder.dll在程序目录存放.
3、编写64位LSP程序的程序时,不要包含#pragma comment(lib,“Sporder.lib”)否则程序出错!

网络编程之编写LSP进行Winsock API监控拦截或LSP注入相关推荐

  1. 《Unix网络编程卷1-套接字联网API》第一个例子编译 不通过问题解决

    <Unix网络编程卷1-套接字联网API>是本好书. 但是第一个例子不是很好编译. 需要如下步骤: 本人机器CentOS 5.4 1.下载源码 unpv13e解压到任意目录 然后按其rea ...

  2. 【网络编程】之二、socket API学习

    套接字API函数: 1.socket函数:The socket function creates a socket that is bound to a specific transport serv ...

  3. 《UNIX网络编程:套接字联网API》啃书笔记(第8UDP套接字编程、11章地址转换)

    基本UDP套接字编程 下图为UDP客户/服务器程序的函数调用: 注意客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指定目的地的地址作为参数.类似的,服务器不接受来自客 ...

  4. 基于Winsock API的VC网络编程实战

    基于Winsock API的VC网络编程实战 随着计算机信息技术的飞速发展,互联网与人类社会的工作.生活越来越紧密相关,它已经成为人类获取.交流信息的重要途径和手段.所以当前对于开发人员来说,网络编程 ...

  5. WinSock网络编程实用宝典(一)

    一.TCP/IP 体系结构与特点    1.TCP/IP体系结构   TCP/IP协议实际上就是在物理网上的一组完整的网络协议.其中TCP是提供传输层服务,而IP则是提供网络层服务.TCP/IP包括以 ...

  6. Windows下的网络编程Winsock

    文章目录 前言 1.服务器下的Winsock 1.1.构建编程环境: 1.2.WSAData结构体 1.3.WSAStartup初始化Winsock 1.4.WSACleanup释放Winsock 1 ...

  7. Winsock网络编程头文件及库文件的设置

    Winsock是Windows下网络编程的规范.使用Winsock可以实现基于TCP或UDP的通信. 1 Winsock版本 Winsock主要包含两个版本,即Winsock1和Winsock2.Wi ...

  8. windows多线程和网络编程

    第 10 章  多线程与网络编程初步  教学提示:Windows 是一个支持多任务的操作系统.当在一个程序中需要启动另外一 个程序时,需要用到多进程的编程方式.如果一个进程中有一些相似的任务需要同时推 ...

  9. python怎么编程输入坐标_python编程之API入门: (一)使用百度地图API查地理坐标...

    在网络编程中,我们会和API打交道.那么,什么是API?如何使用API呢?本文分享了一下我对API的理解以及百度地图API的使用. API是"Application Programming ...

最新文章

  1. 交叉验证分析每一折(fold of Kfold)验证数据的评估指标并绘制综合ROC曲线
  2. android 实现全屏代码
  3. 何恺明CVPR演讲:深入理解ResNet和视觉识别的表示学习(41 PPT)
  4. jsp mysql 换行_jsp 操作 mysql 数据库
  5. 中国象棋程序的设计与实现(四)-- 一次“流产”的写书计划
  6. VTK:Utilities之LUTUtilities
  7. 什么是数据的完整性约束
  8. mysql备份表恢复数据库_mysql备份恢复数据库据/表
  9. c++: size_type与 size_t一些概念
  10. 牛客寒假算法基础训练营5
  11. Cygwin ssh
  12. IE中getElementById的Bug
  13. 盖世无双之国产数据库风云榜-2022年02月
  14. 卡巴斯基2010激活码
  15. 企业需要关注的零信任 24 问
  16. 解决Postman报错Could not send request
  17. 互联网巨头的2B市场变革
  18. 【搞笑】新闻联播熏陶下的小学生作文
  19. Win10取消文件默认打开方式
  20. 计算机utp,UTP网线

热门文章

  1. 鸟人的Android揭秘(3)——Android 编译环境搭建
  2. byte数组转blob类型_Jfinal 存byte[] 到mysql数据库中blob类型
  3. 5、Squid代理服务
  4. html a text decoration,你未必知道的CSS小知识:text-decoration属性变成了属性简写
  5. 微信公众号怎么做地推活动?效果极佳又安全!
  6. 博客园有一段时间登不上
  7. 工作站和台式机的区别是什么
  8. 参考资料来自 懒兔子 的公众号
  9. Unity 0.Interactive Tutorials
  10. 为什么有些人赚钱那么容易,有些人却赚不到钱?