Разбираюсь с перехватом функций клиента и возникла непонятная ситуация: некоторые функции хукаются нормально, а некоторые вызывают криты в клиенте без видимых на то причин.
Вот пример кода:
PHP код:
#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 (__stdcall *t_Func)(void* param1/*, int param2*/);
t_Func Original_Func = NULL;
DWORD WINAPI Intercept_Func(void* param1/*, int param2*/) {
// Сохранение контекста класса перехваченного метода.
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");
/* DWORD UGameEngine::OnSocialAction(User* user, int id) */
//Original_Func = (t_Func)GetProcAddress(hEngine, "?OnSocialAction@UGameEngine@@UAEHPAUUser@@H@Z"); // Работает
/* DWORD UNetworkHandler::AddNetworkQueue(NetworkPacket* networkPacket) */
Original_Func = (t_Func)GetProcAddress(hEngine, "?AddNetworkQueue@UNetworkHandler@@UAEHPAUNetworkPacket@@@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(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) {
if(ul_reason_for_call == DLL_PROCESS_ATTACH ) {
// MessageBox(0, L"Injected", L"", MB_OK);
InterceptFunctions();
}
return TRUE;
}
Перехват OnSocialAction (как и многих других функций) работает вполне успешно, а вот AddNetworkQueue перехватить не получается. В чем может быть дело?
P.S. Крит возникает в момент вызова оригинальной функции из функции-перехватчика, т.е сразу после MessageBox(0, L"Hooked", L"", MB_OK);