如何触发WSAOVERLAPPED事件? (C ++)

时间:2011-08-19 02:29:43

标签: c++ winsock

注意:我遇到麻烦的特殊情况是lpCompletionRoutine为null且lpOverlapped不为。

我正在尝试编写数据包嗅探器。我正在挂钩WSARecv并用我自己的代码替换它。如果lpOverlapped不为null,我创建自己的LPWSAOVERLAPPED变量并调用真正的WSARecv。我接收并记录数据包就好了,但问题是,我正在嗅探的客户端似乎在等待触发它的WSOAVERLAPPED事件。

所以问题是,如何触发初始的lpOverlapped?我尝试过像WSASetEvent这样的东西。我尝试过内联asm并做这样的事情:

__asm{
  push InFlags
  push lpOverlapped
  push BytesTransferred
  push Error
  call lpOverlapped
}

这些都没有奏效。我认为应该有一个简单的方法来触发wsaoverlapped,所以游戏知道i / o操作已经完成,但我只是不知道如何。

感谢任何和所有帮助。

谢谢!

编辑:

我尝试通过执行以下操作来发送代码,但是我收到了ERROR_INVALID_HANDLE错误。

WSAOVERLAPPED overlapped = *lpOverlapped;
HANDLE hEvent = overlapped.hEvent;
if(!SetEvent(hEvent)){
    int error = GetLastError();
    Write(error);
}

准备活动需要做些什么特别的事情吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

没有特殊的方法来触发它。

您需要记住原始的LPOVERLAPPED和完成例程参数,并通过完成例程发出您自己的调用。在完成例程中,当您收到数据包时,检查原始参数:如果有完成例程,请调用它;否则,LPOVERLAPPED中有hEvent - 发出信号。

答案 1 :(得分:1)

与Eugene Homyakov达成协议,只增加一点。实际上,操作系统可以通过3种方式通知流程重叠的I / O完成。

  • 设置hEvent结构的OVERLAPPED成员指定的事件
  • 调用完成例程(在WSAxxxx的调用中指定)。
  • 向完成端口发送完成。

关于完成例程 - 当I / O完成时,您应该注意它是预定到调用者线程的APC队列。只有当线程调用可警告的等待过程(例如SleepExWaitForMultipleObjectsEx)时,它实际上才会被称为

如果套接字/文件句柄与之关联,操作系统会将完成发布到完成端口。有关详细信息,请参阅CreateIoCompletionPortPostQueuedCompletionStatus

答案 2 :(得分:0)

您不应该直接挂钩Winsock API。使用分层服务提供程序框架。这是一个例子:http://www.netresec.com/?page=Blog&month=2011-01&post=Proxocket---A-Winsock-Proxy-Sniffer