【发布时间】:2014-08-06 22:34:29
【问题描述】:
我正在使用 C++ 和绕道来开发挂钩 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)?有什么想法/想法吗?
附:据我所知,可执行文件不使用完成例程(lpCompletionRoutine 始终为 NULL),仅使用重叠结构。
【问题讨论】:
-
嗯。我以为我写了一条评论,询问当您“丢弃”数据包时您希望应用程序实际做什么?相信这是超时,还是网络出现故障?
-
不,我只是想让它继续等待其他数据包,就像什么都没发生一样。
-
请注意,
packet_should_be_blocked不能工作,因为 TCP 不是面向消息的。您必须缓冲数据,直到有足够的数据进行分析,然后可能仅删除您在单个调用中收到的部分数据。这也适用于阻止接收呼叫。 -
@BenVoigt 我熟悉我正在修改的协议(每个数据包/消息的前两个字节定义数据包/消息类型,每个数据包类型都有固定长度),所以这根本不是问题。还是谢谢你。
-
@splattru:这是一个问题,因为您假设标头和有效负载在单个缓冲区中一起到达。这种假设对于 TCP 来说是错误的。
标签: c++ sockets detours overlapped-io