2016-01-06 164 views
1

我寫了一個數據包攔截器來從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的功能。

An image to explain better the situation

+0

'send()'和'recv()'不是可用於發送/讀取數據的唯一函數。試着鉤住'WSASend()'和'WSARecv()'。如果套接字通信使用重疊I/O,則可能還需要鉤住其他函數,如'WriteFile()'和'ReadFile()',甚至GetOverlappedResult()和GetQueuedCompletionStatus()。 –

+0

'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'的私有實現。 –

+0

@RemyLebeau但如果應用程序使用ws2_32的SEND發送信息,它不應該使用來自同一模塊的RECV來接收數據嗎? –

回答

2

wsock32.dll是的Winsock 1.x中,ws2_32.dll如果Winsock的2.x的大多數應用鏈接到ws2_32.dll,但傳統應用(和錯誤配置的應用)可能仍然鏈接到wsock32.dll。在現代系統上,wsock32.dll在其內部重定向大多數其功能爲ws2_32.dllmswsock.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的具體可用的擴展功能,以及(WSASend()WSARecv(),等),和Winsock 2。 x套接字也可以支持重疊I/O和I/O完成端口。因此,如果您真的想要在任何給定的應用程序中掛接所有可能的數據交換途徑,您可能需要掛鉤BSD功能,Winsock擴展功能和I/O功能。但是,如果你只是針對一個特定的應用程序,你只需要鉤住它實際調用的函數(在這種情況下,它是send()WSARecv())。