Hello there.
I'm posting about my problem since I haven't found any thread about this topic :(
I am trying to make an 'outgoing packet listener' for this game, by detour-ing its SendPacket function. Obviously it only listens for packets being sent.
I want to avoid using MS Detours, so I'm using a detour function I found on the internet.
Needless to say I am injecting a dll into the client in order to do that.
The problem is the game crashes, most likely when jumping from my custom SendPacket function to the real SendPacket function (according to OllyDbg).
Here's the code (C++) for the dll I'm injecting into the client:
It compiles fine. I inject it into the client with a simple dll injector, and here's what happen:
1) A console gets attached to the client.
2) I move/sit/attack/whatever.. in game to trigger SendPacket.
3) SendPacket gets called, it jumps to my custom SendPacket (h_SendPacket in my code) which prints text on the console.
4) Crash.
I assume that it crashes when jumping back to the real SendPacket, maybe it screws up the registers?
This method used to work for me on other games, and I'm still a noob at Olly/ASM, so I'm kinda clueless for now :(
I'm posting about my problem since I haven't found any thread about this topic :(
I am trying to make an 'outgoing packet listener' for this game, by detour-ing its SendPacket function. Obviously it only listens for packets being sent.
I want to avoid using MS Detours, so I'm using a detour function I found on the internet.
Needless to say I am injecting a dll into the client in order to do that.
The problem is the game crashes, most likely when jumping from my custom SendPacket function to the real SendPacket function (according to OllyDbg).
Here's the code (C++) for the dll I'm injecting into the client:
Code:
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <cstdio>
#include <windows.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>
typedef int (__stdcall *pSendPacket) (void *Src, size_t Size);
unsigned int __stdcall mainThread(void* pArguments);
bool OpenConsole();
void SetConsoleTitle(wchar_t *title);
void *SetDetour(BYTE *source, const BYTE *destination, const unsigned int length);
pSendPacket o_SendPacket = NULL;
int _stdcall h_SendPacket(void *Src, size_t Size);
extern "C" __declspec(dllexport) BOOL APIENTRY DllMain(HANDLE hModule, DWORD lpReason, LPVOID lpReserved)
{
switch (lpReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
HANDLE hThread;
unsigned int threadId;
hThread = (HANDLE)_beginthreadex(NULL, 0x1000, &mainThread, (void *)hModule, 0, &threadId);
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
}
unsigned int __stdcall mainThread(void* pArguments)
{
OpenConsole();
SetConsoleTitle(L"Packet Listener");
DWORD addr = 0x63AA80; // sendpacket's address (old version of the game, I play on a private server, 1.4.4 I believe)
o_SendPacket = (pSendPacket)SetDetour((BYTE *)addr, (BYTE *)h_SendPacket, 7); // detour SendPacket, it should now jump to h_SendPacket
wprintf(L"SendPacket's address: %x\nh_SendPacket's address: %x\no_SendPacket's address: %x\n", (BYTE *)addr, h_SendPacket, o_SendPacket); // check the functions' addresses, to make it easier to debug
return S_OK; // exit current thread
}
bool OpenConsole()
{
FILE *out;
FILE *in;
FILE *err;
if (AllocConsole() == FALSE)
return false;
out = _fdopen(_open_osfhandle(PtrToUlong(GetStdHandle(STD_OUTPUT_HANDLE)), _O_TEXT), "w");
in = _fdopen(_open_osfhandle(PtrToUlong(GetStdHandle(STD_INPUT_HANDLE)), _O_TEXT), "r");
err = _fdopen(_open_osfhandle(PtrToUlong(GetStdHandle(STD_ERROR_HANDLE)), _O_TEXT), "w");
*stdout = *out;
*stdin = *in;
*stderr = *err;
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
return true;
}
void SetConsoleTitle(wchar_t *title)
{
SetConsoleTitleW(title);
}
void *SetDetour(BYTE *source, const BYTE *destination, const unsigned int length) // this wasn't written by myself
{
BYTE *jmp = (BYTE *)malloc(length + 5);
DWORD dwBack;
VirtualProtect(source, length, PAGE_EXECUTE_READWRITE, &dwBack);
memcpy(jmp, source, length);
jmp += length;
jmp[0] = 0xE9;
*(DWORD *)(jmp + 1) = (DWORD)(source + length - jmp) - 5;
source[0] = 0xE9;
*(DWORD*)(source + 1) = (DWORD)(destination - source) - 5;
for(int i = 5; i < length; i++)
{
source[i] = 0x90;
}
VirtualProtect(source, length, dwBack, &dwBack);
return jmp - length + 1;
}
int __stdcall h_SendPacket(void *Src, size_t Size)
{
wprintf(L"SendPacket triggered! opcode: %x (%d bytes long)\n", ((BYTE *)Src)[0], (int)Size); // check the packet's opcode, to make sure it works
return o_SendPacket(Src, Size);
}
1) A console gets attached to the client.
2) I move/sit/attack/whatever.. in game to trigger SendPacket.
3) SendPacket gets called, it jumps to my custom SendPacket (h_SendPacket in my code) which prints text on the console.
4) Crash.
I assume that it crashes when jumping back to the real SendPacket, maybe it screws up the registers?
This method used to work for me on other games, and I'm still a noob at Olly/ASM, so I'm kinda clueless for now :(