gpt4 book ai didi

c - 拦截winsock recvfrom函数给出无效地址错误

转载 作者:行者123 更新时间:2023-11-30 16:37:19 28 4
gpt4 key购买 nike

我正在尝试拦截winsock2调用来解决同一主机上进程之间的UDP数据包间歇性消失的情况。当它们“消失”时,它们会消失大约 20 秒,这足以中止正在运行的进程。

我设法让 DLL 注入(inject)工作,并且正确拦截了 2 个 winsock 调用(我希望),因为我可以进行简单的打印,但我需要能够处理地址信息,以便我可以跟踪谁发送了什么给谁...

不幸的是,我注入(inject)的上游进程显然正在调用recvfrom(是的,不是WSA...等效,这是旧的移植的POSIX代码),“from”和“fromlen”参数为NULL。如果我不摆弄它们所有的接收工作。如果执行以下操作,我会收到“无效地址”错误(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;
}

最佳答案

问题的原因是回复的实际大小超过了“struct sockaddr”的大小。它实际上是一个 SOCKADDR_IN6 结构回来了。使用 200 字节的任意缓冲区而不是 28 字节的 sockaddr 结构,我能够提取数据。

在此过程中,我最终转换为“查看”接收到的数据,而不是在拉入数据后对其进行处理。当带有源代码的电脑完成安装更新时,我将发布它。

在家工作相当孤立,而且我办公室里也没有人住在winsock里。在评论中“聊天”确实很有帮助。

关于c - 拦截winsock recvfrom函数给出无效地址错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47997534/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com