我编写了一个数据包拦截器来从winsock转发send / recv函数的信息,据我所知,这两个函数都位于ws2_32.dll;通过将jmp写入记录我需要的信息的函数来完成钩子,然后调用原始函数,钩子本身就可以正常工作。
真正奇怪的部分是我开始注意到我无法记录任何RECV电话,而SEND电话被拦截就好了。
写钩子的函数如下:
procedure Setup;
var
lModuleHandle : dword;
lPlaceHolder : dword;
begin
lModuleHandle := LoadLibrary(MODULE_NAME);
OriginalSend := Dword(GetProcAddress(lModuleHandle, FUNCTION_SEND));
OriginalRecv := Dword(GetProcAddress(lModuleHandle, FUNCTION_RECV));
VirtualProtect(Ptr(OriginalSend), 5, PAGE_EXECUTE_READWRITE, lPlaceHolder);
VirtualProtect(Ptr(OriginalRecv), 5, PAGE_EXECUTE_READWRITE, lPlaceHolder);
PByte(OriginalRecv)^ := $E9;
PDword(OriginalRecv + 1)^ := Dword(@Hook_Recv) - OriginalRecv - 5;
PByte(OriginalSend)^ := $E9;
PDword(OriginalSend + 1)^ := Dword(@Hook_Send) - OriginalSend - 5;
Inc(OriginalSend, 5);
Inc(OriginalRecv, 5);
end;
我正在使用的程序(被拦截的程序)使用winsock 2并且经过一些调试我注意到我加载了wsock32.dll并决定在其RECV上设置断点而我在ws2_32中有另一个断点.dll的发送;两个断点都被击中了。
这意味着程序正在使用ws2_32.dll发送和wsock32.dll到recv,这有什么意义吗?这种行为是否正常?
在不同的模块中编写钩子相当容易,但由于它们应该是不同的,它让我相信有些东西是错的,而且,我的计算机中的其他一些应用程序(比如firefox本身)也有同样的行为。 / p>
我添加此图片以更好地解释这种情况,看起来该程序链接到wsock32并最终得到了一些ws2_32的功能。
答案 0 :(得分:2)
wsock32.dll
适用于Winsock 1.x,ws2_32.dll
适用于Winsock 2.x.大多数应用都会链接到ws2_32.dll
,但旧版应用(以及配置错误的应用)仍可能会链接到wsock32.dll
。在现代系统上,wsock32.dll
在内部将的大多数功能重定向到ws2_32.dll
或mswsock.dll
。
您的目标应用正在关联wsock32.dll
。您正在ws2_32.dll
中挂钩函数。
在内部,wsock32.send()
直接映射到ws2_32.send()
,这就是您的send()
挂钩有效的原因。但是,wsock32.recv()
不会映射到ws2_32.recv()
,这就是您的recv()
挂钩不起作用的原因。 wsock32.recv()
实际上会调用ws2_32.WSARecv()
。
在WinSock 2.x中,标准BSD套接字函数仍然可用(send()
,recv()
等),但也有可用的Winsock特定扩展函数({{1} },WSASend()
等,Winsock 2.x套接字也可以支持重叠I / O和I / O完成端口。因此,如果您真的想在任何给定的应用程序中挂钩所有可能的数据交换途径,您可能必须挂钩BSD函数,Winsock扩展函数和I / O函数。但是,如果您只是针对某个特定应用,则只需挂钩它实际调用的函数(在这种情况下为WSARecv()
和send()
)。