我正在使用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)?任何想法/想法?
P.S。据我所知,可执行文件不使用完成例程(lpCompletionRoutine始终为NULL),只有重叠结构。
答案 0 :(得分:3)
主要障碍是重复操作意味着在调用函数退出并处于挂起状态后在后台执行。如果调用者要求WSARecv()
执行重叠读取,则期望数据到达后台,并且您将无法直接验证挂钩内部的数据,因为尚未收到该数据。您必须使用自己的私有WSAOVERLAPPED
来执行您自己的重叠读取,使用线程或完成回调来检测读取何时完成,以便您可以分析数据。如果数据可以接受,请将其复制到呼叫者的缓冲区中并发出呼叫者的WSAOVERLAPPED
信号。否则,发布另一个读取并等待该数据到达,根据需要重复,直到您最终收到一些您想要给调用者的数据。
答案 1 :(得分:-1)
更简单的修改TCP流量的方法是仅挂钩connect
系列函数,并使应用程序连接到您控制下的透明代理,以执行实际的流修改。
虽然应用程序可以在远程端的流中编写自己的端口号来与数据包源地址进行比较,但实际上这不是一个问题,因为
实际上,FTP代理必须执行此命令重写,因为它们会为文件传输生成从属连接。但大多数现代应用程序都是与PAT兼容的。