0

我正在使用 C++ 和 detours 处理挂钩 winsock2 函数的 dll。我的目标是修改进出原始可执行文件的 TCP 流量。在某些时候,我需要停止某些数据包传递(以便原始可执行文件根本不知道该数据包,但仍保持连接)。

使用 WSASend 挂钩,很清楚(您只是不调用原始 WSASend 并返回 0)。但我不知道如何使用 WSAOVERLAPPED 结构在 WSARecv 钩子中制作它。

我希望下面的代码演示了我想要什么:

__declspec(dllexport) int WINAPI WSARecv_hook(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
    // Recieve real data
    int ret = WSARecv_real(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);

    // Loop over lpBuffers and analyze it
    for(int i=0; i < dwBufferCount; i++)
    {
        // analyze it
        if(packet_should_be_blocked(lpBuffers[i].buf, lpBuffers[i].len))
        {
            // Do or return what?
        } else {
            // Otherwise, just process as usual
        }
    }
    return ret;
}

我如何假装什么​​也没发生,也没有收到任何数据包(比如假的 WSA_IO_PENDING)?有什么想法/想法吗?

PS 据我所知,可执行文件不使用完成例程(lpCompletionRoutine 始终为 NULL),仅使用重叠结构。

4

2 回答 2

3

主要障碍是重叠操作意味着在调用函数以挂起状态退出后在后台执行。如果调用者要求WSARecv()执行重叠读取,则它期望数据到达后台,并且您将无法直接验证钩子内的数据,因为它尚未收到。您将不得不使用自己的私有WSAOVERLAPPED来执行自己的重叠读取,使用线程或完成回调来检测读取何时完成,以便您可以分析数据。如果数据是可接受的,则将其复制到调用者的缓冲区并通知调用者的WSAOVERLAPPED. 否则,发布另一个读取并等待该数据到达,根据需要重复,直到您最终收到一些您想要提供给调用者的数据。

于 2014-08-06T23:20:18.517 回答
-1

修改 TCP 流量的一种更简单的方法是仅挂钩connect函数系列,并使应用程序连接到您控制下的透明代理,该代理执行实际的流修改。

虽然应用程序可以在流中写入自己的端口号,以便远程端与数据包源地址进行比较,但这在实践中不是问题,因为

  1. 这也会破坏在住宅互联网连接中非常常见的 NAT-PAT 网关
  2. 您可以重写内容并发送代理的地址,因此检查通过

事实上,FTP 代理必须重写此命令,因为它们会产生从属连接以进行文件传输。但是大多数现代应用程序都被编写为与 PAT 兼容。

于 2014-08-07T00:29:13.097 回答