2017-12-27 30 views
0

同じホスト上のプロセス間のUDPパケットが断続的に消滅する場合のトラブルシューティングのために、winsock2呼び出しを傍受しようとしています。彼らが消えてしまうと20秒くらい消えてしまうので、実行中のプロセスを中止するのに十分です。winsock recvfrom関数をインターセプトすると無効なアドレスエラーが発生する

私は単純なプリントを行うことができるので、DLLインジェクションを動作させることができ、2回のwinsockコールが正しく傍受されますが、アドレス情報を処理できるようにする必要があります何人に...

残念ながら、私が注入しようとしている上流のプロセスは明らかにrecvfromを呼び出しています(WSA ...ではなく、これは古いPOSIXコードです)。 "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; 
} 
+0

* UDP *パケットは消滅します。つまり、送信元によって送信されていますが、送信先には到着しません。これは* UDP *の* PoV *からOKです。 'recvfrom'を微調整している場合(注意:この関数は完全にうまくいきます。' WSARecvFrom'はその上のラッパーであるという感覚を持っています)、宛先側でもやっています。あなたが新しいものを見つけることができる可能性は低いです。また、あなたは 'Myrecvfrom'をどのように呼びますか?どの引数( 'from'と' fromLen'のためにまだ0)? – CristiFati

+0

エラー** 10014 **の完全な説明は "**呼び出しでポインター引数を使用しようとする際に無効なポインターアドレスを検出しました。**"これはプロセスメモリーマッピングの問題に起因するメモリー違反に関連しているようですwinsockコードよりも注入されたコードで。 –

+0

@christifati - 私はこのDLLを注入し、winsock2のrecvfromを無効にしています。そして、私の目的は、最終的にprocess1によって送信されたパケットが2を処理しないことを示すことです(またはその逆)。理論的には@Frankie_Cの –

答えて

0

問題の原因は、返信のACTUALサイズが「struct sockaddr」のサイズを超えていることです。実際にはSOCKADDR_IN6構造体が戻ってきました。 28バイトのsockaddr構造体の代わりに200バイトの任意のバッファを使用し、データを取り込むことができました。

このプロセスでは、受け取ったデータを取り込んだ後に処理する代わりに、そのデータを「覗く」ように変換しました。ソースコードを持つPCで更新プログラムのインストールが完了したら、投稿します。

家からの仕事はかなり隔離されていて、とにかく私のオフィスのwinsockに住んでいる人はいません。コメントに「チャット」するのは本当に役に立ちました。

関連する問題