Нашёл тут на форуме пример на с++, но клиент вылетает с критом после месседж бокса, никак не получается заставить работать.
Код:
#include "stdafx.h"
#include <Windows.h>
#pragma pack(push, 1)
struct jmp_struct {
BYTE instruction;
DWORD argument;
};
#pragma pack(pop)
BYTE old[5];
DWORD written = 0;
jmp_struct jump;
typedef DWORD(__fastcall *t_Func)(void* param1)
t_Func Original_Func = NULL;
INT __fastcall Intercept_Func(void* param1)
{
// Сохранение контекста класса перехваченного метода.
DWORD this_ptr = NULL;
__asm mov this_ptr, ecx;
// Восстанавливаем 5 первых байт функции.
WriteProcessMemory(GetCurrentProcess(), (void*)Original_Func, (void*)&old, 5, &written);
MessageBox(0, L"Hooked", L"", MB_OK);
// Восстановление в регистр ecx контекста класса перехваченного метода.
__asm mov ecx, this_ptr;
DWORD originalResult = Original_Func(param1/*, param2*/);
// Снова заменяем 5 байт функции на команду перехода на нашу функцию
WriteProcessMemory(GetCurrentProcess(), (void*)Original_Func, (void*)&jump, 5, &written);
return originalResult;
}
void InterceptFunctions() {
HMODULE hEngine = GetModuleHandleA("engine.dll");
Original_Func = (t_Func)GetProcAddress(hEngine, "?RequestBypassToServer@UNetworkHandler@@UAEHAAVL2ParamStack@@@Z");
if (Original_Func == 0) {
MessageBox(NULL, L"Can't get address", L"Error!", MB_OK);
return;
}
jump.instruction = 0xE9;
jump.argument = (DWORD)&Intercept_Func - ((DWORD)Original_Func + 5); // Смещение для jmp = <адрес назначения> - (<адрес jmp> + sizeof(BYTE) + sizeof(int))
ReadProcessMemory(GetCurrentProcess(), (void*)Original_Func, (void*)&old, 5, &written);
WriteProcessMemory(GetCurrentProcess(), (void*)Original_Func, (void*)&jump, sizeof(jmp_struct), &written);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: InterceptFunctions();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}