我寫了一個數據包攔截器來從winsock的send/recv函數轉儲信息,並且據我所知,這兩個函數都位於ws2_32.dll中;掛鉤是通過將jmp寫入一個函數來完成的,該函數記錄我需要的信息,然後調用原始函數,掛鉤本身工作得很好。Winsock使用不同版本
真奇怪的是我開始注意到我無法記錄任何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的SEND中又有一個斷點;兩個斷點都被擊中。
這意味着該程序使用ws2_32.dll發送和wsock32.dll recv,這是否有任何意義?這種行爲在任何方面都是正常的嗎?
在不同模塊中編寫鉤子相當容易,但由於它們應該是不同的,所以我相信有些東西是錯誤的,而且我的電腦中的其他一些應用程序(如Firefox本身)也具有相同的行爲。
我添加此圖片來更好地解釋情況,看起來像程序鏈接到wsock32,並最終得到一些ws2_32的功能。
'send()'和'recv()'不是可用於發送/讀取數據的唯一函數。試着鉤住'WSASend()'和'WSARecv()'。如果套接字通信使用重疊I/O,則可能還需要鉤住其他函數,如'WriteFile()'和'ReadFile()',甚至GetOverlappedResult()和GetQueuedCompletionStatus()。 –
'wsock32.dll'用於Winsock 1.x,'ws2_32.dll'用於Winsock 2.x. 'wsock32.dll'只是一個將命令重定向到'ws2_32.dll'的thunk,以便與舊應用程序兼容。一切都應該最終通過'ws2_32.dll'。但是這並不一定保證'wsock32.dll'中的'recv()'映射到'ws2_32.dll'中的'recv()'。它實際上做的是'wsock32.dll'的私有實現。 –
@RemyLebeau但如果應用程序使用ws2_32的SEND發送信息,它不應該使用來自同一模塊的RECV來接收數據嗎? –