网络验证的破解-用SPI修改网络封包

很多外挂和其他一些应用程序,更新频繁,如果每次都是:下载最新版本-脱壳-修改, 将非常麻烦。通过嗅探网卡数据,分析出网络验证算法,就可以自己写服务器模拟了。整个破解环节中,最重要的就是要把外挂发送到服务器的验证数据转发到我们 自己写的服务器上,这个可以通过NDIS驱动,TDI驱动或者更上层的SPI来实现。下面是我用SPI来实现的例子
一、自己写服务器响应外挂验证请求
   很简单,只要把发送目标就是IP地址改过来就可以了(需要在 WSPConnect 中处理)
int WSPAPI WSPConnect(  
       SOCKET          s,  
       const struct    sockaddr FAR * name,  
       int             namelen,  
       LPWSABUF        lpCallerData,  
       LPWSABUF        lpCalleeData,  
       LPQOS           lpSQOS,  
       LPQOS           lpGQOS,  
       LPINT           lpErrno  
       )  
{  
 int ret;
 SOCKADDR_IN mysock;
 CString strTemp;
 memcpy(&mysock,name,sizeof(sockaddr));
 strTemp.Format("before IP:%u.%u.%u.%u"  
        , mysock.sin_addr.S_un.S_un_b.s_b1
        , mysock.sin_addr.S_un.S_un_b.s_b2
        , mysock.sin_addr.S_un.S_un_b.s_b3
        , mysock.sin_addr.S_un.S_un_b.s_b4
  );
 //  ret = strTemp.Find("174.139.101.",0);    // DNF犀利外挂的请求地址,有很多,比较前三段即可
 if (ret != -1)
 {
  // 修改成自己服务器所在IP
  mysock.sin_addr.S_un.S_un_b.s_b1 = 192;
  mysock.sin_addr.S_un.S_un_b.s_b2 = 168;
  mysock.sin_addr.S_un.S_un_b.s_b3 = 1;
  mysock.sin_addr.S_un.S_un_b.s_b4 = 229;
 }
 ret =  NextProcTable.lpWSPConnect(s, (sockaddr *)&mysock, namelen, lpCallerData  
        , lpCalleeData, lpSQOS, lpGQOS, lpErrno);
 return ret;
}
 
二、修改发送数据
int WSPAPI WSPSend(  
 SOCKET          s,  
 LPWSABUF        lpBuffers,  
 DWORD           dwBufferCount,  
 LPDWORD         lpNumberOfBytesSent,  
 DWORD           dwFlags,  
 LPWSAOVERLAPPED lpOverlapped,  
 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
 LPWSATHREADID   lpThreadId,  
 LPINT           lpErrno  
)  
{
    int ret;
 CString strTemp;
 SOCKADDR_IN  remote_addr;   
 int remote_addr_len = sizeof(remote_addr);   
 getpeername(s, (SOCKADDR*)&remote_addr, &remote_addr_len);
 strTemp.Format("SEND IP:%u.%u.%u.%u"
  , remote_addr.sin_addr.S_un.S_un_b.s_b1  
        , remote_addr.sin_addr.S_un.S_un_b.s_b2  
        , remote_addr.sin_addr.S_un.S_un_b.s_b3  
        , remote_addr.sin_addr.S_un.S_un_b.s_b4
  );
 ret = strTemp.Find("192.168.1.229",0);    // DNF犀利
 if (ret != -1)
 {
    //  在这里处理数据,修改lpBuffers->buf 处内容
 }
    ret =  NextProcTable.lpWSPSend(s, lpBuffers, dwBufferCount  
        , lpNumberOfBytesSent, dwFlags, lpOverlapped  
        , lpCompletionRoutine, lpThreadId, lpErrno);
 return ret;
}
 
最后在 WSPStartup 中挂钩
int WSPAPI WSPStartup(
 WORD    wVersionRequested,
 LPWSPDATA   lpWSPData,
 LPWSAPROTOCOL_INFOW lpProtocolInfo,
 WSPUPCALLTABLE  upcallTable,
 LPWSPPROC_TABLE  lpProcTable
)
{
 TCHAR    sLibraryPath[512];
    LPWSPSTARTUP        WSPStartupFunc      = NULL;
 HMODULE    hLibraryHandle  = NULL;
    INT                 ErrorCode           = 0;
 if (!GetHookProvider(lpProtocolInfo, sLibraryPath)
  || (hLibraryHandle = LoadLibrary(sLibraryPath)) == NULL
  || (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(
        hLibraryHandle, "WSPStartup")) == NULL
  )
  return WSAEPROVIDERFAILEDINIT;
 if ((ErrorCode = WSPStartupFunc(wVersionRequested, lpWSPData
  , lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
  return ErrorCode;
 
 NextProcTable = *lpProcTable;
// 挂钩
 lpProcTable->lpWSPConnect = WSPConnect;
 lpProcTable->lpWSPSend = WSPSend;
 return 0;
}
原文地址:https://www.cnblogs.com/niuniu502/p/2024901.html