我試圖攔截的Winsock2呼籲解決在同一臺主機上的進程之間的UDP數據包間歇性消失的情況。當它們「消失」時,它們會消失20秒,這足以中止正在運行的過程。攔截winsock的recvfrom函數提供了無效地址錯誤
我設法讓DLL注入工作,並正確截獲了2個winsock調用(我希望),因爲我可以做一個簡單的打印,但我需要能夠處理地址信息,以便我可以跟蹤誰發送什麼對誰...
不幸的是,我注入的上游過程顯然是調用recvfrom(是的,不是WSA ...等價物,這是舊的移植POSIX代碼)與NULL的「從」和「fromlen」參數。如果我在所有的接收作品中都不擺弄他們。如果我執行以下操作,則會收到「無效地址」錯誤(Winsock錯誤10014)。
的我在做一些愚蠢的事嗎?不是說我會感到驚訝....是的,用所需的調試重建目標應用程序會更容易,但由於數據中心遷移,構建環境下降,我需要彈藥來說「這不是應用。」
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "mhook.h"
#include <winsock2.h>
// typedefs for function pointers...
typedef int(WINAPI *rcvfrom_ptr) (
SOCKET s,
char *buf,
int len,
int flags,
struct sockaddr *from,
int *fromlen
);
typedef int(WINAPI *sendto_ptr) (
_In_ SOCKET s,
_In_ const char *buf,
_In_ int len,
_In_ int flags,
_In_ const struct sockaddr *to,
_In_ int tolen
);
// Function pointers for original calls.
rcvfrom_ptr orig_rcvfrom;
sendto_ptr orig_sendto;
//
// Helper functions.
//
typedef union sockaddrs {
struct sockaddr from;
struct sockaddr_in in_from;
// Need to verify Ipv6 support. may need to remigrate back to VS 2015
//struct sockaddr_in6 in6_from;
} tsockaddrs;
char *printaddr(char *buff,const int buffsz, const tsockaddrs *addr)
{
...
}
// Shim functions.
//
// Still working on getting them to actually work and do what I need.
// But I may as well develop the skeleton
int WINAPI Myrecvfrom(SOCKET s,
char *buf,
int len,
int flags,
struct sockaddr *from,
int *fromlen
)
{
int result;
struct sockaddr *all_froms;
char addrbuff[100] = "";
int newfromlen = sizeof(struct sockaddr);
all_froms = (struct sockaddr *)malloc(sizeof(struct sockaddr));
memset((void *)all_froms,0,sizeof(struct sockaddr));
printf("Receiving Packet!\n");
if (from == NULL) {
printf("\tFrom addr == null, using internal structures\n");
result = (orig_rcvfrom)(s, buf, len, flags, all_froms, &newfromlen);
} else {
printf("\tFrom addr != null, using passed structures\n");
result = (orig_rcvfrom)(s, buf, len, flags, from, fromlen);
memcpy_s((void*)&all_froms,sizeof(all_froms),(void *)from,*fromlen);
if (fromlen != NULL) {
newfromlen=*fromlen;
} else {
newfromlen=sizeof(struct sockaddr);
}
}
if (result >0) {printf("received %d bytes\n",result);}
else if (result == SOCKET_ERROR) {printf("Socket Error %d occurred!\n",WSAGetLastError());}
if (newfromlen >0) {
if (printaddr(addrbuff,sizeof(addrbuff),(tsockaddrs *)all_froms)!=NULL) {
printf("received %d bytes from on port %d from host %s\n",result,((tsockaddrs *)(all_froms))->in_from.sin_port,addrbuff);
}
if (from != NULL) {
memcpy_s((void*)from,sizeof(struct sockaddr),(void*)&all_froms,newfromlen);
}
else
{
}
if (fromlen != NULL) *fromlen=newfromlen;
}
else {
printf("received %d bytes from unknown port and host\n",result);
}
if (all_froms != NULL) {free(all_froms);}
return result;
}
int WINAPI Mysendto(SOCKET s,
const char *buf,
int len,
int flags,
const struct sockaddr *to,
int tolen
)
{
printf("Sending packet!\n");
return orig_sendto(s, buf, len, flags, to, tolen);
}
BOOL AttachHooks(void)
{
BOOL sethooks;
orig_rcvfrom = (rcvfrom_ptr)GetProcAddress(GetModuleHandle(L"ws2_32"), "recvfrom");
sethooks = Mhook_SetHook((PVOID*)&orig_rcvfrom, Myrecvfrom);
if (sethooks) {
orig_sendto = (sendto_ptr)GetProcAddress(GetModuleHandle(L"ws2_32"), "sendto");
sethooks &= Mhook_SetHook((PVOID*)&orig_sendto, Mysendto);
}
return sethooks;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf_s("This is an attached DLL!\n");
AttachHooks();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
的* UDP數據包*消失:這意味着他們正在被源發送的,但他們從來沒有到達目的地。這從* UDP *的* PoV *可以確定。如果你正在調整'recvfrom'(注意:這個函數非常好,我覺得'WSARecvFrom'只是它的一個包裝器),你也在目標端做這件事,如果包沒有達到它的可能性很低,你可以找到新的。另外:你怎麼稱呼'Myrecvfrom'?什麼參數(對於'from'和'fromLen'仍然是0)? – CristiFati
錯誤的完整描述** ** 10014就是「**該系統在試圖在調用中使用指針參數檢測到無效的指針地址。**」這似乎更關係到內存衝突,由於進程的內存映射問題與注入的代碼比winsock代碼。 –
@christifati - 我正在注入這個DLL並覆蓋winsock2 recvfrom。我的目標是最終顯示process1發送的數據包永遠不會處理2(反之亦然)。 –