C++ hook wsarecv and wsasend

01/20/2012 21:11 vitalka#1
Hey guys i dont know why my source doesnt work. Whats the mistake?


Code:
#include "stdio.h"
#include "winsock2.h"
#include "windows.h"
#include <iostream>
#include <commctrl.h>
#include <time.h>

using namespace std;

#pragma comment(lib, "ws2_32.lib")

typedef int (WINAPI* t_WSARecv)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
typedef int (WINAPI* t_WSASend)(SOCKET,LPWSABUF,DWORD,LPDWORD,DWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE );

t_WSASend o_WSASend;
t_WSARecv o_WSARecv;


void *DetourFunction(BYTE *src, const BYTE *dst, const int len) // credits to gamedeception
{
	BYTE *jmp = (BYTE*)malloc(len+5);
	DWORD dwback;
	VirtualProtect(src, len, PAGE_READWRITE, &dwback);
	memcpy(jmp, src, len); jmp += len;
	jmp[0] = 0xE9;
	*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
	src[0] = 0xE9;
	*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
	VirtualProtect(src, len, dwback, &dwback);
	return (jmp-len);
}


int WINAPI hook_WSARecv(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
	MessageBox(HWND_DESKTOP,L"Blabla",L"Titel",MB_OK);
	return o_WSARecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpOverlapped,lpCompletionRoutine);
}

int WINAPI hook_WSASend(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
	MessageBox(HWND_DESKTOP,L"Blabla",L"Titel",MB_OK);
	return o_WSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD Ergebnis, LPVOID lpReserved)
{
    UNREFERENCED_PARAMETER(lpReserved);
  switch(Ergebnis)
  {
  case DLL_PROCESS_ATTACH:

        DisableThreadLibraryCalls(hModule);

		o_WSASend  = (t_WSASend)DetourFunction((PBYTE)GetProcAddress(GetModuleHandle(L"ws2_32.dll"), "WSASend"), (PBYTE)hook_WSASend,5);
        o_WSARecv  = (t_WSARecv)DetourFunction((PBYTE)GetProcAddress(GetModuleHandle(L"ws2_32.dll"), "WSARecv"), (PBYTE)hook_WSARecv,5);
          
		break;
  }
    return true;
}
01/21/2012 22:47 pushedx#2
You don't really want to hook WSASend/WSARecv in Silkroad. Silkroad uses [Only registered and activated users can see links. Click Here To Register...], which means the data you actually send and receive will most likely be processed later, rather than at the time of the API call.

To properly process the API results, you'd have to also hook and process [Only registered and activated users can see links. Click Here To Register...] and possibly [Only registered and activated users can see links. Click Here To Register...], keeping track of the lpOverlapped parameter so you know which event is a read/write/something else.

You should really just detour connect and detour to a proxy, either external or internal (via an injected dll) so you don't have to mess with this stuff. That's been the way to go about things since 2006, so no sense in not doing it.

If you still want to hook raw send/recv functions, you need to be hooking client code and not the WSASend/WSARecv API calls. Otherwise, between threading issues, non-networking code using the same mechanics, you will have a hard time getting something that will always give the correct results.
01/22/2012 11:37 vitalka#3
Its not really for Silkroad i dont want to code anymore for Silkroad, but in this section are some people who have much knowledge.
So the hook works for now, but the send funktion working only time per hook so after one send i get a windows error, but why?

Code:
// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib")

using namespace std;

typedef int ( WINAPI *realConnect )(SOCKET s, const struct sockaddr* name, int namelen );
typedef int (WINAPI* realRecv)(SOCKET socket, const char* buffer, int length, int flags);
typedef int (WINAPI* realSend)(SOCKET socket, const char* buffer, int length, int flags);

realSend o_send;
realRecv o_recv;
realConnect o_connect;

SOCKET Bot;
SOCKADDR_IN addr;


int WINAPI my_connect( SOCKET s, const struct sockaddr* name, int namelen)
{
	WORD port = ntohs((*(WORD*)name->sa_data));
	sockaddr_in *sockaddr = (sockaddr_in*)name;
	sockaddr->sin_port = htons(16000);
	if ( port != 80 )
	{
	sockaddr->sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	}
	return o_connect(s,name,namelen);
}

int WINAPI my_send(SOCKET socket, const char* buffer, int length, int flags) 
{
	send(Bot, buffer, length, flags);
	return o_send(socket, buffer, length, flags);
}

int WINAPI my_recv(SOCKET socket, const char* buffer, int length, int flags) 
{
	send(Bot, buffer, length, flags);
	return o_recv(socket, buffer, length, flags);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		//Socketpart
		WSADATA wsa;
		WSAStartup(MAKEWORD(2,2), &wsa);

		Bot=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
		memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten 
        addr.sin_family=AF_INET;
        addr.sin_port=htons(16000);
        addr.sin_addr.s_addr=inet_addr("127.0.0.1");

		short status;
		status=connect(Bot,(SOCKADDR*)(&addr),sizeof(addr));
		if (status==SOCKET_ERROR)
		{
			MessageBox(NULL, TEXT("Bot dont exists"), TEXT("Error"), MB_OK);
			exit(0);
		}
		/////////////////////////////////////////////////////
		HMODULE hWS32 = LoadLibraryA( "ws2_32.dll" );
		FARPROC pConnect = GetProcAddress(hWS32,"connect");
		FARPROC pSend = GetProcAddress(hWS32,"send");
		FARPROC pRecv = GetProcAddress(hWS32,"recv");
		//DetourCreate((LPVOID)pConnect,my_connect,5);
		//__asm mov [ o_connect ], eax;
		DetourCreate((LPVOID)pSend,my_send,5);
		__asm mov [ o_send ], eax;
		DetourCreate((LPVOID)pRecv,my_recv,5);
		__asm mov [ o_recv ], eax;
		break;
	}
	return true;
}
01/23/2012 08:13 lesderid#4
Quote:
Originally Posted by vitalka View Post
Its not really for Silkroad i dont want to code anymore for Silkroad, but in this section are some people who have much knowledge.
So the hook works for now, but the send funktion working only time per hook so after one send i get a windows error, but why?

Code:
//...
Use this:
Code:
int WINAPI my_send(SOCKET socket, const char* buffer, int length, int flags) 
{
	o_send(Bot, buffer, length, flags);
	return o_send(socket, buffer, length, flags);
}

int WINAPI my_recv(SOCKET socket, const char* buffer, int length, int flags) 
{
	o_send(Bot, buffer, length, flags); //And shouldn't this be o_recv?
	return o_recv(socket, buffer, length, flags);
}