2012-04-08 9 views
3

Winsock 2.0 recv機能を使用するアプリケーションがあり、Redox Packet Editorなどの出力をキャッチして、そのバージョンが2.0であることを確認できます。Winsock recv Detoursとのフック

私は機能フックするために、このコードがあります:sendについては

#define _CRT_SECURE_NO_DEPRECATE 
#ifndef WIN32_LEAN_AND_MEAN 
#define WIN32_LEAN_AND_MEAN 
#endif 

#include <windows.h> 
#include <WinSock2.h> 
#include <detours.h> 
#include <stdio.h> 
#pragma comment(lib, "ws2_32.lib") 


FILE *pSendLogFile; 
FILE *pRecvLogFile; 

int (WINAPI *pSend)(SOCKET s, const char* buf, int len, int flags) = send; 
int WINAPI MySend(SOCKET s, const char* buf, int len, int flags); 
int (WINAPI *pRecv)(SOCKET s, char *buf, int len, int flags) = recv; 
int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags); 


INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) 
{ 
    switch(Reason) 
    { 
     case DLL_PROCESS_ATTACH: 
      DisableThreadLibraryCalls(hDLL); 

      DetourTransactionBegin(); 
      DetourUpdateThread(GetCurrentThread()); 
      DetourAttach(&(PVOID&)pSend, MySend); 
      if(DetourTransactionCommit() == NO_ERROR) 
       MessageBox(0,"send() detoured successfully","asd",MB_OK); 

      DetourTransactionBegin(); 
      DetourUpdateThread(GetCurrentThread()); 
      DetourAttach(&(PVOID&)pRecv, MyRecv); 
      if(DetourTransactionCommit() == NO_ERROR) 
       MessageBox(0,"recv() detoured successfully","asd",MB_OK); 
      break; 

    case DLL_PROCESS_DETACH: 
    case DLL_THREAD_ATTACH: 
    case DLL_THREAD_DETACH: 
     break; 
    } 
    return TRUE; 
} 


int WINAPI MySend(SOCKET s, const char* buf, int len, int flags) 
{ 
    MessageBox(0,"sent","sent",MB_OK); 
    return pSend(s, buf, len, flags); 
} 

int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags) 
{ 
    MessageBox(0,"recvd","recvd",MB_OK); 
    return pRecv(s, buf, len, flags); 
} 

を、すべてが完璧に動作しますが、私はrecvのための任意の出力を得ることはありません。私は1.1バージョンのWinsockを使って別のアプリケーションで試してみましたが、うまくいきました。 WSARecv、WSARecvExには何の不便もなくフックしようとしました。

WinAPIOverride32でアプリをチェックしたところ、それは明らかにrecv機能を使用していると表示され、successfulyがその使用状況を記録します。 Winsock Packet Editorもデータをよく読み取っています。

アイデア?

+1

私の助言:代わりにLSP(層別サービスプロバイダ)を書いてください。LSPサンプルの1つを変更すると、フックアプローチよりもさらに多くの情報が得られます。 TDIのドライバーや友人に代わるユーザーモードとして想像してみてください。 – 0xC0000022L

+0

このLSPの記事またはサンプルコードはありますか?それほど複雑ではないことを願っています。 – methyl

+0

もちろん、これは大部分の場合でも有効です:https://www.microsoft.com/msj/0599/layeredservice/layeredservice.aspxもちろん:http://msdn.microsoft.com/en-us/ライブラリ/ windows/desktop/bb513664(v = vs.85).aspx – 0xC0000022L

答えて

3

正しいdllに接続してもよろしいですか?私は、実際にどのDLLがプログラムによって使用されているかを確認します:WSOCK32.dllまたはws2_32.dll。

編集:

typedef int (WINAPI *SendPtr)(SOCKET s, const char* buf, int len, int flags); 
HMODULE hLib = LoadLibrary("wsock32.dll"); 
SendPtr pSend = (SendPtr)GetProcAddress(hLib, "send"); 

をし、その値(のrecvについても同じこと)でpSendを使用します。

たぶん、このような何かを試してみてください。最後にFreeLibraryを呼び出すことを忘れないでください。 dllがすでにロードされていることが確かな場合は、GetModuleHandle("wsock32.dll")を使用する方がよいでしょう。この場合、FreeLibraryを呼び出す必要はないからです。

+0

はい、私はそれをチェックし、どんな結果もせずに、挿入されたDLLのヘッダとlibをwinsock32に変更しようとしました。 – methyl

+0

EasyHookでは 'ws2_32.dll'の代わりに' [Dllimport] 'を' wsock32.dll'に設定しなければならないので、良いトレースだと思います。迂回路でそれを行う方法? – methyl

+0

あなたはそうですが、Ivarpoissはまず正確な解を得たので、賞金は彼のものです。手伝ってくれてありがとう! – methyl

1

あなたは問題が空の(あるいは初期化されていないバッファ)を書き込むしようとしているから茎:

int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags) 
{ 
    fopen_s(&pRecvLogFile, "C:\\RecvLog.txt", "a+"); 
    fprintf(pRecvLogFile, "%s\n", buf); 
    fclose(pRecvLogFile); 
    return pRecv(s, buf, len, flags); //you need to call recv first 
} 

代わりにこのような何か:二次的な問題として

int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags) 
{ 
    int read = pRecv(s, buf, len, flags); 
    if(read <= 0) 
    { 
     //read error/connection closed 
     return read; 
    } 

    fopen_s(&pRecvLogFile, "C:\\RecvLog.txt", "a+"); 
    fwrite(buf,sizeof(char),read,pRecvLogFile); 
    fclose(pRecvLogFile); 
    return read; 
} 

を、あなたがあるように見えます送信または受信されたデータが純粋に文字列ベースであると仮定した場合、一般的にパケットにはfprintfの出力が途中でゼロバイトになる可能性があるので、代わりにfwriteを使用して送信/受信サイズを渡す必要がありますバイナリモードでファイルを開くmplies)。

+0

メッセージの表示とデータがダンプされている、それが問題ではないと思うし、動作し、同じように見えるし、MyRecvの最初の呼び出しとしてMessageBoxによってデバッグしようとしました。 – methyl

+0

@methyl:しかし、 'send'は同じではありません。データを送って、' recv'で受け取る必要があります。*最初に受け取る必要があります。 'recv '。これをデバッガtbhで実行することをお勧めします。 – Necrolis

+0

しかし、問題は機能が迂回していないということです。ログは作成されません。 – methyl

1

GetProcAddressを使用してアドレスを取得する必要があります。

のような何か:

int (WINAPI *pRecv)(SOCKET s, char *buf, int len, int flags) = GetProcAddress(GetModuleHandle("ws2_32.dll"), "recv");

コンパイラは、DLLをロードしたものとあなたの「RECV」から野生のルートのすべての種類を思い付くことができます。したがって、これらの2つのアドレスは異なる場合があります。その場合にテストするには、あなたのdllからrecvを使ってください。

また、ReadFile/WriteFileに目を向けることもできます。

また、フッキングが信頼できないと予想します。たとえば、ターゲットは自由にフックを外してより多くのことを行うことができます。

+0

私のソリューションをコピーするためのDownvote。 – newgre

関連する問題