5.1 DLL的封包截获 内容来自论文无忧网 www.paper51.com BOOL WINAPI DllMain是DLL的入口函数,系统调用时的标准接口。做一些初始化工作。主要工作是得到调用这个程序的进程路径和名称并设置DLL调用次数的计数器。 http://www.paper51.com WSPStartup是Windows Sockets应用程序调用SPI的初始化函数。是服务提供者的标准入口函数。这里的工作是根据lpProtocolInfo找出已经被替换的服务提供者路径,然后加载,并利用被替换服务提供者的WSPStartup得到30个服务函数指针。需要先保存这些函数指针,然后将lpProcTable结构中的30个服务函数指针都设置成自己的。这样,相应的函数请求会首先经过我们自己的函数,然后用这些函数可以做适当的处理,再调用原来的,将请求转发,完成整个通信。 内容来自www.paper51.com int WSPAPI WSPStartup( http://www.paper51.com WORD wVersionRequested, 内容来自论文无忧网 www.paper51.com LPWSPDATA lpWSPData, paper51.com LPWSAPROTOCOL_INFOW lpProtocolInfo, http://www.paper51.com
WSPUPCALLTABLE upcallTable, http://www.paper51.com
LPWSPPROC_TABLE lpProcTable paper51.com ) http://www.paper51.com { 内容来自www.paper51.com ODS(_T("WSPStartup...")); copyright paper51.com if(!m_CheckAcl.m_bIsWin9x &&m_CheckAcl.CheckStartup() == XF_QUERY && !QueryAccess()) 内容来自www.paper51.com return SOCKET_ERROR; copyright paper51.com TCHAR sLibraryPath[512]; copyright paper51.com
LPWSPSTARTUP WSPStartupFunc = NULL; 内容来自论文无忧网 www.paper51.com HMODULE hLibraryHandle = NULL; 内容来自论文无忧网 www.paper51.com INT ErrorCode = 0; copyright paper51.com
if(!GetHookProvider(lpProtocolInfo,sLibraryPath)||(hLibraryHandle =LoadLibrary(sLibraryPath))==NULL||(WSPStartupFunc=(LPWSPSTARTUP)GetProcAddress(hLibraryHandle,"WSPStartup")) == NULL) http://www.paper51.com return WSAEPROVIDERFAILEDINIT; paper51.com
if((ErrorCode=WSPStartupFunc(wVersionRequested,lpWSPData,lpProtocolInfo,upcallTable, lpProcTable)) != ERROR_SUCCESS) http://www.paper51.com return ErrorCode; copyright paper51.com if( !lpProcTable->lpWSPAccept || http://www.paper51.com
!lpProcTable->lpWSPAddressToString || copyright paper51.com !lpProcTable->lpWSPAsyncSelect || 内容来自www.paper51.com !lpProcTable->lpWSPBind || 内容来自论文无忧网 www.paper51.com
!lpProcTable->lpWSPCancelBlockingCall || 内容来自www.paper51.com !lpProcTable->lpWSPCleanup || 内容来自www.paper51.com
!lpProcTable->lpWSPCloseSocket || copyright paper51.com
!lpProcTable->lpWSPConnect || http://www.paper51.com !lpProcTable->lpWSPDuplicateSocket || 内容来自论文无忧网 www.paper51.com !lpProcTable->lpWSPEnumNetworkEvents || copyright paper51.com !lpProcTable->lpWSPEventSelect || 内容来自论文无忧网 www.paper51.com !lpProcTable->lpWSPGetOverlappedResult|| 内容来自论文无忧网 www.paper51.com !lpProcTable->lpWSPGetPeerName || 内容来自www.paper51.com
!lpProcTable->lpWSPGetSockName || 内容来自论文无忧网 www.paper51.com
!lpProcTable->lpWSPGetSockOpt || 内容来自www.paper51.com !lpProcTable->lpWSPGetQOSByName || paper51.com !lpProcTable->lpWSPIoctl || http://www.paper51.com !lpProcTable->lpWSPJoinLeaf || copyright paper51.com !lpProcTable->lpWSPListen || http://www.paper51.com
!lpProcTable->lpWSPRecv || http://www.paper51.com !lpProcTable->lpWSPRecvDisconnect || paper51.com !lpProcTable->lpWSPRecvFrom || copyright paper51.com !lpProcTable->lpWSPSelect || http://www.paper51.com
!lpProcTable->lpWSPSend || http://www.paper51.com !lpProcTable->lpWSPSendDisconnect || 内容来自www.paper51.com !lpProcTable->lpWSPSendTo || copyright paper51.com !lpProcTable->lpWSPSetSockOpt || copyright paper51.com !lpProcTable->lpWSPShutdown || http://www.paper51.com !lpProcTable->lpWSPSocket || copyright paper51.com
!lpProcTable->lpWSPStringToAddress) paper51.com
return WSAEINVALIDPROCTABLE; 内容来自www.paper51.com EnterCriticalSection(&gCriticalSection); 内容来自www.paper51.com NextProcTable = *lpProcTable; paper51.com lpProcTable->lpWSPSocket =WSPSocket; 内容来自论文无忧网 www.paper51.com
lpProcTable->lpWSPCloseSocket =WSPCloseSocket; 内容来自论文无忧网 www.paper51.com lpProcTable->lpWSPConnect =WSPConnect; copyright paper51.com
lpProcTable->lpWSPAccept =WSPAccept; 内容来自www.paper51.com lpProcTable->lpWSPSend =WSPSend; paper51.com lpProcTable->lpWSPSendTo =WSPSendTo; 内容来自论文无忧网 www.paper51.com
lpProcTable->lpWSPRecv =WSPRecv; 内容来自www.paper51.com lpProcTable->lpWSPRecvFrom =WSPRecvFrom; paper51.com //以上是我们截获并要用自己定义的函数。 paper51.com
LeaveCriticalSection(&gCriticalSection); http://www.paper51.com return 0; http://www.paper51.com } 内容来自论文无忧网 www.paper51.com
XfIoControl是供EXE调用的。用来设置DLL的配置信息和得到DLL的反馈信息,这个函数为EXE提供接口,EXE通过这个函数来设置工作模式,或得到截获的网络封包信息。 内容来自www.paper51.com QueryAccess是在应用程序提交连网请求时,如果发现控管规则中没有关于这个应用程序的控管规则,并且工作模式为询问,则向拥护发出询问,是否让这个程序通行。 内容来自www.paper51.com GetHookProvider用来读取注册表得到系统的SPI的DLL路径和文件信息。这个信息是安装时自己写入的。根据pProtocolInfo信息取出自己保存的、已经被本程序替换的服务提供者路径。 paper51.com
GetRightEntryIdItem是供GetHookProvider()调用的扩展函数,用来得到保存系统服务提供者路径的注册表键名。及得到已经被本程序替换的服务提供者的dwCatalogEntryId。 内容来自www.paper51.com XfShutdown调用系统服务提供者函数WSPShutdown,关闭一个Socket连接。并设置相应的错误代码。 内容来自论文无忧网 www.paper51.com
截获的服务提供者函数: 内容来自论文无忧网 www.paper51.com 过滤WSPSocket。WSPSocket是用来创建Socket的函数,首先调用底层函数得到新创建的Socket,然后设置新建Socket的协议信息,并调用自定义函数CheckSocket为这个Socket建立Session,然后保存相应的信息。 内容来自论文无忧网 www.paper51.com 过滤WSPCloseSocket。转发之前首先调用自定义函数CheckCloseSocket删除相应的Session。 http://www.paper51.com 过滤WSPConnect。当一个Socket建立连接后调用这个函数,转发之前先调用访问控制函数CheckConnect,检查是否放行。如果不放行,返回错误;如果放行,调用底层WSPConnect函数进行转发。 http://www.paper51.com 过滤WSPAccept。用来接受一个连接请求。首先调用底层函数,然后对连接的合法性进行检查,如果不允许通过,关闭这个连接 内容来自论文无忧网 www.paper51.com
过滤WSPSend。这个函数用来发送面向连接的数据,先检查是否允许通过,然后进行转发。 内容来自论文无忧网 www.paper51.com 过滤WSPSendTo。这个函数用来发送面向无连接的数据,先检查是否允许通过,然后进行转发。 内容来自论文无忧网 www.paper51.com 过滤WSPRecv。这个函数用来接收面向连接的数据。首先判断是不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。 copyright paper51.com 过滤WSPRecvFrom。这个函数用来接收面向连接的数据。首先判断是不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。 内容来自www.paper51.com 5.2 DLL的访问控管 内容来自论文无忧网 www.paper51.com 编写一个CCheckAcl。它封装了一组对访问权限进行控制的函数。访问权限主要是由控管规则设置决定。另外还封装了一组网络封包操作函数。下面是一些主要函数及相应代码。 copyright paper51.com |