SPI黑客技术研究[4]

接下来,我们最后来看看怎么样实现一个服务提供者的最基本的实例,我们可以试图在这里对网络封包进行截取。

 

以下是基础服务提供者实例,对于分层服务提供者,麻烦!我懒得写了:

 

int WSPAPI WSPStartup(

WORD wVersion,

LPWSPDATA lpWSPData,

LPWSAPROTOCOL_INFOW lpProtocolInfo,

WSPUPCALLTABLE UpCallTable,

LPWSPPROC_TABLE lpProcTable)

{

 

int nTotalProtocols=0;

int nProviderPathLen=MAX_PATH;

TCHAR szLibraryPath[MAX_PATH]={ '/0' };

TCHAR szProviderPath[MAX_PATH]={ '/0' };;

LPWSAPROTOCOL_INFOW lpOrigProtocolInfo=NULL;

theApp.m_hLibOrigBase=NULL;

LPWSPSTARTUP WSPStartupFunc = NULL;

 

EnterCriticalSection(&theApp.m_CriticalSection);

if (!theApp.m_nEntityCount)

{

CFile f;

TCHAR szFileName[MAX_PATH]={ '/0' };

GetWindowsDirectory(szFileName,MAX_PATH);

sprintf(szFileName,"%s//%s",szFileName,OLD_BSP_CATALOG);

if(!f.Open(szFileName,CFile::modeRead)) return WSAEPROVIDERFAILEDINIT;

DWORD dwLen=f.GetLength();

DWORD dwSize=MAX_PATH+sizeof(WSAPROTOCOL_INFOW);

nTotalProtocols=dwLen/dwSize;

lpOrigProtocolInfo=new WSAPROTOCOL_INFOW[nTotalProtocols];

for(int i=0;i<nTotalProtocols;i++)

{

f.Seek(dwSize*i+MAX_PATH,0);

f.Read(&lpOrigProtocolInfo[i],sizeof(WSAPROTOCOL_INFOW));

if(lpProtocolInfo->ProviderId==lpOrigProtocolInfo->ProviderId)

{

f.Seek(dwSize*i,0);

f.Read(szProviderPath,MAX_PATH);

break;

}

}

f.Close();

delete[] lpOrigProtocolInfo; lpOrigProtocolInfo=NULL;

if(!ExpandEnvironmentStrings(szProviderPath,szLibraryPath,MAX_PATH)) return WSAEPROVIDERFAILEDINIT;

 

theApp.m_hLibOrigBase=LoadLibrary(szLibraryPath);

if(theApp.m_hLibOrigBase==NULL) return WSAEPROVIDERFAILEDINIT;

 

WSPStartupFunc=(LPWSPSTARTUP)GetProcAddress(theApp.m_hLibOrigBase,"WSPStartup";

if(WSPStartupFunc==NULL) return WSAEPROVIDERFAILEDINIT;

 

int nRet=(*WSPStartupFunc)(wVersion,lpWSPData,lpProtocolInfo,UpCallTable,lpProcTable);

if(nRet!=ERROR_SUCCESS) return nRet;

 

memmove(&theApp.m_NextProcTable, lpProcTable, sizeof(WSPPROC_TABLE));

 

lpProcTable->lpWSPAccept = WSPAccept;

lpProcTable->lpWSPAddressToString = WSPAddressToString;

lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;

lpProcTable->lpWSPBind = WSPBind;

lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;

lpProcTable->lpWSPCleanup = WSPCleanup;

lpProcTable->lpWSPCloseSocket = WSPCloseSocket;

lpProcTable->lpWSPConnect = WSPConnect;

lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;

lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;

lpProcTable->lpWSPEventSelect = WSPEventSelect;

lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;

lpProcTable->lpWSPGetPeerName = WSPGetPeerName;

lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;

lpProcTable->lpWSPGetSockName = WSPGetSockName;

lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;

lpProcTable->lpWSPIoctl = WSPIoctl;

lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;

lpProcTable->lpWSPListen = WSPListen;

lpProcTable->lpWSPRecv = WSPRecv;

lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;

lpProcTable->lpWSPRecvFrom = WSPRecvFrom;

lpProcTable->lpWSPSelect = WSPSelect;

lpProcTable->lpWSPSend = WSPSend;

lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;

lpProcTable->lpWSPSendTo = WSPSendTo;

lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;

lpProcTable->lpWSPShutdown = WSPShutdown;

lpProcTable->lpWSPSocket = WSPSocket;

lpProcTable->lpWSPStringToAddress = WSPStringToAddress;

 

theApp.m_lpWSPData = lpWSPData;

theApp.m_lpProcTable = lpProcTable;

}

else

{

lpWSPData = theApp.m_lpWSPData;

lpProcTable = theApp.m_lpProcTable;

}

theApp.m_nEntityCount++;

LeaveCriticalSection(&theApp.m_CriticalSection);

 

return 0;

}

 

int WSPAPI WSPCleanup (LPINT lpErrno)

{

int nRet=theApp.m_NextProcTable.lpWSPCleanup(lpErrno);

 

EnterCriticalSection(&theApp.m_CriticalSection);

theApp.m_nEntityCount--;

if (theApp.m_nEntityCount == 0)

{

FreeLibrary(theApp.m_hLibOrigBase);

theApp.m_hLibOrigBase = NULL;

}

LeaveCriticalSection(&theApp.m_CriticalSection);

 

return nRet;

}

 

对于不同的I/0操作模式,需要进行不同的处理

对于WSARecv,WSARecvFrom,WSASend,WSASendTo的重叠调用,保存重叠信息,重点是完成例程

// 客户程序如果用完成例程,那么将不能直接监视到收发的数据,为了解决这个问题

// 我们可以在服务提供者内提供我们自己的完成例程截获数据,在我们截获了数据之后,

// 再把控制权交还给客户机的完成例程。

//

// 首先,保存重叠操作参数信息的结构

typedef struct tagOVERLAPPED_RECORDER

{

DWORD                  dwType; // WSASend,WSASendTo,WSARecv,WSARecvFrom

// 用来标志监视的数据操作方式

SOCKET                 s,                                                 

LPWSABUF               lpBuffers,                                       

DWORD                  dwBufferCount,                                      

LPDWORD                lpNumberOfBytesSent,                              

DWORD                  dwFlags,                                            

const SOCKADDR_IN FAR  *lpFromOrTo,                         

int                    iFromOrTolen,                        

LPWSAOVERLAPPED        lpOverlapped,                             

LPWSAOVERLAPPED_COMPLETION_ROUTINE   lpCompletionRoutine,

LPWSATHREADID          lpThreadId,                            

LPINT                  lpErrno  

}

OVERLAPPED_RECORDER, *POVERLAPPED_RECORDER, *LPOVERLAPPED_RECORDER;

 

// 其次替换重叠操作的完成例程为自定义的例程

// 例程完成后,控制权交给客户机的完成例程,我们可以删除上面保存的重叠参数信息结构了

// 完成例程原型如下:

void CALLBACK CompletionRoutine (

IN    DWORD             dwError, 

IN    DWORD             cbTransferred, 

IN    LPWSAOVERLAPPED   lpOverlapped, 

IN    DWORD             dwFlags 

);

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值