Winsock2 SPI网络封包截获技术

转载 2011年01月13日 21:23:00
众所周知,网络封包的截获技术分为几种,例如,过滤驱动程序,NDIS中间驱动程序以及Winsock2 SPI截取技术等等。其中要数Winsock2使用最为广泛,下面就向大家介绍下winsock2封包截获技术——它的很大一个特点,就是Winsock2在Winsock1.1的基础上引入了SPI技术!

 

Winsock2之关键函数
Winsock2的函数多是以WSP开头的,他们都是在WS2_32.DLL中实现的,而我们熟悉的Winsock 扩展API是以WSA开头的,因为Winsock的API在SPI函数都有相互对应,你甚至可以把这些函数当作是API函数来使用。

技术实现之关键
程序和其他钩子函数功能类似,并且将以动态链接库(DLL)文件实现,Winsock 钩子,用来截获 Winsock 调用从而拦截TCP/IP封包,并做相应处理。实现DLL的安装需要修改注册表,而不是替换系统的DLL函数,这和过去的一些资料是不同的,这种方法通用性比较高!
为了实际演示,我特别做了一个类似的程序,如果大家有一定基础,相信看了下面的文章后,反外挂也就不是问题了。程序基本流程:
1、 系统调用本dll,启动WSPStartup函数;
2、 WSPStartup将把30个相关函数设置成我们的函数,实现函数接挂;
3、 在各个函数中实现我们想要的功能,这部分读者可以随心所欲了!
下面我来介绍几个主要核心函数:
WSPStartup:WSPStartup是Windows Sockets应用程序调用SPI的初始化函数,我们称之为服务提供者的标准入口函数,主要是转换lpProcTable结构的30个指针设置成自己的,这样,相应的函数请求会首先经过我们自己的函数,然后我们自己的函数可以作适当的处理,最后再将数据流(封包)转给原来的服务提供者函数:
int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
WSPUPCALLTABLE upcallTable,

LPWSPPROC_TABLE lpProcTable
)
{
OutputDebugString(_T(" WSPStartup..."));
TCHAR LibraryPath[512];
LPWSPSTARTUP WSPStartupFunc = NULL;
HMODULE hLibraryHandle = NULL;
INT Error = 0;
//LoadLibrary GetProcAddress我就不多说了,所有DLL文件都少不了的。LoadLibrary动态调用自定义函数GetDLL提供的路径中的dll文件,GetProcAddress用于从载入的模块(sLibraryPath)中取得WSPStartup的函数地址。
if (!GetDLL(lpProtocolInfo, LibraryPath)
|| (hLibraryHandle = LoadLibrary(LibraryPath)) == NULL
|| (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(
hLibraryHandle, "WSPStartup")) == NULL
)
return WSAEPROVIDERFAILEDINIT;

PrintProtocolInfo(lpProtocolInfo, sLibraryPath);
//得到
if ((Error = WSPStartupFunc(wVersionRequested, lpWSPData
, lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
return ErrorCode;

EnterCriticalSection(&gCriticalSection);
//将30个服务函数指针加入到NextProcTable变量中保存。只要将这些函数指针赋值为自己函数的地址,那么当有调用这个函数时将首先调用自己的函数进行处理。然后自己的函数完成工作后,再去调用底层的30个函数完成中转工作。
NextProcTable = *lpProcTable;
lpProcTable->lpWSPSocket = WSPSocket;
lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
lpProcTable->lpWSPConnect = WSPConnect;
lpProcTable->lpWSPAccept = WSPAccept;
lpProcTable->lpWSPSend = WSPSend;
lpProcTable->lpWSPSendTo = WSPSendTo;
lpProcTable->lpWSPRecv = WSPRecv;
lpProcTable->lpWSPRecvFrom = WSPRecvFrom;

lpProcTable->lpWSPAddressToString = WSPAddressToString;
lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
lpProcTable->lpWSPBind = WSPBind;
lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
lpProcTable->lpWSPCleanup = WSPCleanup;
lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
lpProcTable->lpWSPEventSelect = WSPEventSelect;
lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
lpProcTable->lpWSPGetSockName = WSPGetSockName;
lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
lpProcTable->lpWSPIoctl = WSPIoctl;
lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
lpProcTable->lpWSPListen = WSPListen;
lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
lpProcTable->lpWSPSelect = WSPSelect;
lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
lpProcTable->lpWSPShutdown = WSPShutdown;
lpProcTable->lpWSPStringToAddress = WSPStringToAddress;

LeaveCriticalSection(&gCriticalSection);

return 0;
}
以下是几个Winsock 2 服务提供者的几个基本函数原型,作为例子:
WSPSocket是Winsock2SPI的服务函数之一,用来创建Socket连接并将创建的Socket连接加入Socket组。
SOCKET WSPSocket(
int af,
int type,
int protocol,//协议类型
LPWSAPROTOCOL_INFOW lpProtocolInfo,
GROUP g,
DWORD dwFlags,
LPINT lpErrno
)
面向连接的数据发送并调用PrintSocket来输出封包信息。
int WSPAPI WSPSend(
SOCKET s,//Socket
LPWSABUF lpBuffers,//缓冲区地址
DWORD dwBufferCount,//缓冲区数
LPDWORD lpNumberOfBytesSent,//发送字节数
DWORD dwFlags,//标志
LPWSAOVERLAPPED lpOverlapped,//重叠
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,//重叠处理设置
LPWSATHREADID lpThreadId,//进程ID
LPINT lpErrno//错误编号
)
同样是面向非连接的数据发送并调用PrintSocket来输出封包信息。
int WSPSendTo(
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
)
}
面向连接的数据接收,主要功能是在接收数据之前,对封包信息进行了解:
int WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,//数据缓冲区地址
DWORD dwBufferCount,//缓冲区数目
LPDWORD lpNumberOfBytesRecvd,//接收的字节数
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,//重叠设置
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
同样是面向非连接的数据接收,主要功能是在接收数据之前,对封包信息进行了解,函数如下:
int SPRecvFrom (
SOCKET s,
LPWSABUF lpBuffers,//缓冲区地址
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,//接受字节数
LPDWORD lpFlags,
struct sockaddr FAR * lpFrom,
LPINT lpFromlen,
LPWSAOVERLAPPED lpOverlapped,//重叠
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
其他还有:WSPCloseSocket;WSPConnect;WSPAccept;WSPSend;WSPSendTo;WSPRecv;WSPRecvFrom等一系列函数,大家可以查找有关手册。其实用法和winsock API类似。

运行调试
在加入普通模块后,运用dbgview.exe进行调试(网上有下载)安装后,联网测试,我们就可以看到效果了,SPI其实就是一种接口,当我们把自己写好的程序安装到系统后,所有的Winsock请求会发送到这个程序并由他进行转发等调用……一切ok!

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

利用SPI编写类似sockscap的代理工具

转自:http://blog.csdn.net/ze_tsin/article/details/6376831 SPI的出现其实就是微软为了方便程序员对网络API的各种HOOK,从而省去一些...

利用WinSock2 SPI进行网络内容访问控制

防火墙可以实施和执行网络访问策略,但是,传统的防火墙技术集中于如何防范外部网络对内部网络的入侵和攻击上,而对于如何控制内部用户对外部网络的访问问题研究不够深入,相关的控制技术也不多。据权威资料显示,全...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

利用WinSock2 SPI进行网络内容访问控制

防火墙可以实施和执行网络访问策略,但是,传统的防火墙技术集中于如何防范外部网络对内部网络的入侵和攻击上,而对于如何控制内部用户对外部网络的访问问题研究不够深入,相关的控制技术也不多。据权威资料显示,全...

利用SPI编写类似sockscap的代理工具

最近帮一个朋友实现sockscap的socks V5代理功能,sockscap貌似是通过API HOOK实现,一开始我便尝试这种方式,遇到各种麻烦的问题,还是用SPI的LSP来试试吧。SPI的出现其实...
  • ze_tsin
  • ze_tsin
  • 2011年04月30日 20:58
  • 5528

基于SPI的LSP网络封包截获

、、、首先我不是原创、、、、、 转载别人的然后自己学习,网上有很多资料。大家可以先看《windows防火墙与网络封包截获》然后再看“基于SPI 的网络封包截获”。应该就差不多了 我会在地址下方给出...

Windows防火墙与网络封包截获技术2

  • 2008年07月24日 19:17
  • 7.63MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: Winsock2 SPI网络封包截获技术
举报原因:
原因补充:

(最多只允许输入30个字)