(winsock functions btw)
- hooking send() works fine for my internet browser
- hooking recv() works fine for my internet browser
- hooking send() works fine for conquer online
- hooking recv() ??? only 1/2 working for conquer online. When i hook recieve for conquer online, the packets recieved always seem to have size zero and the data is empty... however when i try to comment out call to the original recv() inside my recv() conquer stops working (for checking conquer uses that function). So what i think is going on is conquer is doing some trick with winsock to make the result of a recv() get stored somewhere else.
Any ideas what is up w/ the conquer recv() ?
Thanks in advance , and my code listings are below.
DLL that gets injected...
PHP Code:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <windows.h>
#include "types.h"
#include "detours/patcher.h"
/*
int WSARecv(
__in SOCKET s,
__inout LPWSABUF lpBuffers,
__in DWORD dwBufferCount,
__out LPDWORD lpNumberOfBytesRecvd,
__inout LPDWORD lpFlags,
__in LPWSAOVERLAPPED lpOverlapped,
__in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
*/
using namespace std;
typedef int (WINAPI *SendFunc)(SOCKET, const char*, int, int);
typedef int (WINAPI *RecvFunc)(SOCKET, char*, int, int);
typedef int (WINAPI *WSARecvFunc)(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
SendFunc pSend = NULL;
RecvFunc pRecv = NULL;
WSARecvFunc pWSARecv = NULL;
int WINAPI our_send(SOCKET s, const char* buf, int len, int flags);
int WINAPI our_recv(SOCKET s, char* buf, int len, int flags);
int WINAPI our_wsa_recv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
HMODULE hWinsock = GetModuleHandle("ws2_32.dll");
CPatch patchForSend((SendFunc)GetProcAddress(hWinsock, "send"), our_send, pSend);
CPatch patchForRecv((RecvFunc)GetProcAddress(hWinsock, "recv"), our_recv, pRecv);
CPatch patchForWSARecv((WSARecvFunc)GetProcAddress(hWinsock, "WSARecv"), our_wsa_recv, pWSARecv);
fstream sendPipe;
fstream recvPipe;
SOCKET lastSocket = INVALID_SOCKET;
int WINAPI our_send(SOCKET s, const char* buf, int len, int flags)
{
DWORD tmp;
lastSocket = s;
sendPipe.write(buf, len);
sendPipe.flush();
/*
char buf2[len];
sendPipe.read(buf2, len);
pSend(s, buf2, sendPipe.gcount(), flags);
*/
//return len;
return pSend(s, buf, len, flags);
}
int WINAPI our_recv(SOCKET s, char* buf, int len, int flags)
{
DWORD tmp;
lastSocket = s;
len = pRecv(s, buf, len, flags);
if (len == 0) { return 0; }
recvPipe.write(buf, len);
recvPipe.flush();
//recvPipe.read(buf, len);
return len;
}
int WINAPI our_wsa_recv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
int x = pWSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
for (int i = 0; i < dwBufferCount; ++i) {
recvPipe.write(lpBuffers[i].buf, lpBuffers[i].len);
recvPipe.flush();
}
return x;
}
DWORD WINAPI transmitter(void*);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
// attach to process
DisableThreadLibraryCalls((HMODULE)hinstDLL);
WaitNamedPipe("\\\\.\\pipe\\ConquerSendPipe", NMPWAIT_WAIT_FOREVER);
sendPipe.open("\\\\.\\pipe\\ConquerSendPipe");
if (!sendPipe) {
MessageBox(NULL, "Failed to connect send pipe.", "Error", MB_OK);
return FALSE;
}
WaitNamedPipe("\\\\.\\pipe\\ConquerRecvPipe", NMPWAIT_WAIT_FOREVER);
recvPipe.open("\\\\.\\pipe\\ConquerRecvPipe");
if (!recvPipe) {
MessageBox(NULL, "Failed to connect recv pipe.", "Error", MB_OK);
return FALSE;
}
//CreateThread(NULL, 0, transmitter, 0, 0, NULL);
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}
DWORD WINAPI transmitter(void*)
{
char buf[4096];
DWORD len;
while (1) {
sendPipe.read(buf, 4095);
len = sendPipe.gcount();
if (len == 0) {
MessageBox(NULL, "Connection to send pipe lost.", "Error", MB_OK);
return 1;
}
buf[len+1] = 0;
if (strcmp(buf, "exit") == 0) { break; }
pSend(lastSocket, buf, len, 0);
}
return 0;
}
PHP Code:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <windows.h>
#include <conio.h>
#include "types.h"
#include "tools.h"
using namespace std;
static void output_packet(char packet[], int len)
{
for (int i = 0; i < len; ++i) {
cout << hex << setw(2) << right << setfill('0') << (int)(unsigned char)packet[i] << " ";
}
}
DWORD WINAPI server_to_client(void*);
DWORD WINAPI client_to_server(void*);
HANDLE hSendPipe = INVALID_HANDLE_VALUE;
HANDLE hRecvPipe = INVALID_HANDLE_VALUE;
int main(int argc, char* argv[])
{
if (argc != 2) {
cout << "Usage: packetlogger <ProcessID>" << endl;
return 1;
}
istringstream is(argv[1]);
uint32 processId;
is >> processId;
// create a named pipe for communicating with the remote process
string sendPipeName, recvPipeName;
{
ostringstream os;
os << "\\\\.\\pipe\\ConquerSendPipe";// << processId;
sendPipeName = os.str();
os.str("");
os << "\\\\.\\pipe\\ConquerRecvPipe";// << processId;
recvPipeName = os.str();
}
cout << "send pipe name: " << sendPipeName << endl;
cout << "recv pipe name: " << recvPipeName << endl;
cout << "Creating & connecting send pipe... ";
hSendPipe = CreateNamedPipe(sendPipeName.c_str(), PIPE_ACCESS_DUPLEX /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1 /*PIPE_UNLIMITED_INSTANCES*/, 4096, 4096, 0, NULL);
if (hSendPipe == INVALID_HANDLE_VALUE) {
cout << "failed to create send pipe." << endl;
return 1;
}
if (!ConnectNamedPipe(hSendPipe, NULL)) {
cout << "failed to connect client to send pipe." << endl;
return 1;
}
cout << "done." << endl;
cout << "Creating & connecting recv pipe... ";
hRecvPipe = CreateNamedPipe(recvPipeName.c_str(), PIPE_ACCESS_DUPLEX /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1 /*PIPE_UNLIMITED_INSTANCES*/, 4096, 4096, 0, NULL);
if (hRecvPipe == INVALID_HANDLE_VALUE) {
cout << "failed to create recv pipe." << endl;
return 1;
}
if (!ConnectNamedPipe(hRecvPipe, NULL)) {
cout << "failed to connect client to send pipe." << endl;
return 1;
}
cout << "done." << endl;
cout << "ready for data." << endl;
HANDLE thread1 = CreateThread(NULL, 0, server_to_client, 0, 0, NULL);
HANDLE thread2 = CreateThread(NULL, 0, client_to_server, 0, 0, NULL);
while (WaitForSingleObject(thread1, 1000) != WAIT_OBJECT_0) {}
while (WaitForSingleObject(thread2, 1000) != WAIT_OBJECT_0) {}
DisconnectNamedPipe(hSendPipe);
DisconnectNamedPipe(hRecvPipe);
CloseHandle(hSendPipe);
CloseHandle(hRecvPipe);
return 0;
}
DWORD WINAPI server_to_client(void*)
{
char buf[4096];
DWORD len, tmp;
while (1) {
if (!ReadFile(hRecvPipe, buf, 4096, &len, NULL)) { break; }
cout << "Server --> Client" << endl;
output_packet(buf, len);
cout << endl;
//WriteFile(hRecvPipe, buf, len, &tmp, NULL);
}
return 0;
}
DWORD WINAPI client_to_server(void*)
{
char buf[4096];
DWORD len, tmp;
while (1) {
if (!ReadFile(hSendPipe, buf, 4096, &len, NULL)) { break; }
cout << "Client --> Server" << endl;
output_packet(buf, len);
cout << endl;
//WriteFile(hSendPipe, buf, len, &tmp, NULL);
}
return 0;
}