Форум администраторов игровых серверов

Форум администраторов игровых серверов (https://forum.zone-game.info/TT.php)
-   Программирование / Programming (https://forum.zone-game.info/forumdisplay.php?f=98)
-   -   C++ перехват пакетов (https://forum.zone-game.info/showthread.php?t=41105)

Zubastic 25.07.2016 14:10

C++ перехват пакетов
 
Собственно хочу сделать еще одну реинкарнацию пакетхака. На этот раз в виде длл, но возникла большая проблема:
// dllmain.cpp: определяет точку входа для приложения DLL.
#include <Windows.h>
 
__declspec(dllexport) void dllmain() {}
 
class UNetworkHandler {};
 
#pragma pack(push, 1)
struct NetworkPacket
{
    unsigned char id, _padding1, exid, _padding2;
    unsigned short size, _padding3;
    unsigned char* data;
};
struct ClientPacket
{
    unsigned char id, _padding1, exid, _padding2;
    unsigned short size, _padding3;
    unsigned char* data;
};
#pragma pack(pop)
 
int(__fastcall *UNetworkHandler_AddNetworkQueue)(UNetworkHandler*, int, NetworkPacket*);
typedef void(__cdecl *UNetworkHandler_OutgoingPacket)(unsigned int This, char *Format, ...);
UNetworkHandler_OutgoingPacket true_UNetworkHandler_OutgoingPacket;
 
void ParseClientPacket(ClientPacket* packet)
{
 
}
 
void ParseServerPacket(NetworkPacket* packet)
{
 
}
 
//Клиентские пакеты
int __cdecl UNetworkHandler_OutgoingPacket_hook(unsigned int This, char *Format, ...)
{
    true_UNetworkHandler_OutgoingPacket(This, Format, ...);
    return 0;
}
 
//Серверные пакеты
int __fastcall UNetworkHandler_IncommingPacket_hook(UNetworkHandler* This, int /*edx*/, NetworkPacket* packet)
{
    // Полезная нагрузка перехвата
    char buf[1024];
    wsprintfA(buf, "Server Packet id=0x%x, size=0x%x", packet->id, packet->size);
    OutputDebugStringA(buf);
    ParseServerPacket(packet);
    //-----------------------------------------
    return (*UNetworkHandler_AddNetworkQueue)(This, 0/*чтоугодно*/, packet);
}
 
DWORD WINAPI InitThread(LPVOID)
{
    HMODULE hEngine = LoadLibraryA("Engine.dll");
    (FARPROC&)UNetworkHandler_AddNetworkQueue = GetProcAddress(hEngine, "?AddNetworkQueue@UNetworkHandler@@UAEHPAUNetworkPacket@@@Z");
    void** UNetworkHandler_vftable = (void**)GetProcAddress(hEngine, "??_7UNetworkHandler@@6BUObject@@@");
    void** addr = (void**)(UNetworkHandler_vftable - 0x7); //0x1C for 4 byte
    (FARPROC&)true_UNetworkHandler_OutgoingPacket = FARPROC(addr);
    *addr = (void*)UNetworkHandler_OutgoingPacket_hook;
    void** UNetworkHandler_vftableCheck = UNetworkHandler_vftable;
    while (*UNetworkHandler_vftableCheck != (void*)UNetworkHandler_AddNetworkQueue) ++UNetworkHandler_vftableCheck;
    *UNetworkHandler_vftableCheck = (void*)UNetworkHandler_IncommingPacket_hook;
    return 0;
}
 
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID)
{
    if (DLL_PROCESS_ATTACH != ul_reason_for_call)
        return 1;
    DisableThreadLibraryCalls(hModule);
 
    CreateThread(0, 0, &InitThread, 0, 0, 0);
    return 1;
}
Code: C++
Собственно почему в одном случае все работает, а в другом ошибка?)

Awiion 25.07.2016 20:28

Re: C++ перехват пакетов
 
Zubastic,
Почему вы так не используете? :)

Код:

BOOL InitThread(void)
{
        return 0;
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD hReason, LPVOID hReserved)
{
        DisableThreadLibraryCalls(hModule);
        if (hReason == DLL_PROCESS_ATTACH)
        {
                CreateThread(0, 0, (LPTHREAD_START_ROUTINE)InitThread, 0, 0, 0);
        }
        return TRUE;
}


Zubastic 25.07.2016 21:08

Re: C++ перехват пакетов
 
Мопед был найден на просторах интернета, да и для меня большой разницы не было как это реализовать.
Вопрос вот в этом:
int __cdecl UNetworkHandler_OutgoingPacket_hook(unsigned int This, char *Format, ...)
{
    true_UNetworkHandler_OutgoingPacket(This, Format, ...);
    return 0;
}
Code: C++
Тут эта байда отваливается, хотя я просто хочу пробросить функцию (ну и модифицировать чутка).

flopix 25.07.2016 21:44

Re: C++ перехват пакетов
 
Какие хроники?

UNetworkHandler_AddNetworkQueue вызывается без ошибок?

Возможно адрес true_UNetworkHandler_OutgoingPacket рассчитан неправильно.

n3k0nation 25.07.2016 21:57

Re: C++ перехват пакетов
 
В true_* функциях пролог есть?

Zubastic 25.07.2016 22:03

Re: C++ перехват пакетов
 
Цитата:

Сообщение от n3k0nation (Сообщение 415661)
В true_* функциях пролог есть?

Шо це такое?
Чета вон вверху есть.

Добавлено через 5 минут
Цитата:

Сообщение от flopix (Сообщение 415658)
Какие хроники?

UNetworkHandler_AddNetworkQueue вызывается без ошибок?

Возможно адрес true_UNetworkHandler_OutgoingPacket рассчитан неправильно.

ХФ 273

n3k0nation 25.07.2016 22:13

Re: C++ перехват пакетов
 
Цитата:

Сообщение от Zubastic (Сообщение 415662)
Шо це такое?
Чета вон вверху есть.

Добавлено через 5 минут

ХФ 273

like:
Код:

push ebp
mov ebp, esp
;далее твой джамп на функцию со смещением на 5 байт

И да. Корректно ли заменяются 5 байт на jmp near? Ибо пролога у функции может и не быть, что делает кучу гемороя, типа, написания дизассемблера длин и замена с помощью него + нопы, плюс учет стека, состояния регистров, бла-бла-бла

Zubastic 25.07.2016 23:02

Re: C++ перехват пакетов
 
Цитата:

Сообщение от n3k0nation (Сообщение 415665)
like:
Код:

push ebp
mov ebp, esp
;далее твой джамп на функцию со смещением на 5 байт

И да. Корректно ли заменяются 5 байт на jmp near? Ибо пролога у функции может и не быть, что делает кучу гемороя, типа, написания дизассемблера длин и замена с помощью него + нопы, плюс учет стека, состояния регистров, бла-бла-бла

Я же заменяю ссылку в vtable на метод. Зачем мне делать пролог?
Я понимаю если бы я экстил функцию в методе, тогда это имело смысл, а так какой смысл? Нет, конечно можно и так сделать, но это дополнительный геморрой, как ты описал.

flopix 25.07.2016 23:09

Re: C++ перехват пакетов
 
Попробуйте добавить поиск адреса таким способом и сравнить полученные адреса.
Это рабочий вариант как раз для HF

PHP код:

unsigned int GetSendPacketAddress(void)
{
    
HMODULE hEngine LoadLibraryA("engine.dll");

    
unsigned int startVMT = (unsigned intGetProcAddress(hEngine"??_7UNetworkHandler@@6BUObject@@@");
    
//sprintf_s(outSt, "startVMT: %u\n", startVMT);
    //PrintOnConsole(outSt);

    
unsigned int AddNetworkQueue = (unsigned intGetProcAddress(hEngine"?AddNetworkQueue@UNetworkHandler@@UAEHPAUNetworkPacket@@@Z");
    
unsigned int currVMT startVMT;

    if (
AddNetworkQueue == 0)
    {
        
PrintOnConsole("GetSendPacketAddress: AddNetworkQueue == 0\n");
        return 
0;
    }

    while (
true)
    {
        if (*(
unsigned int*) currVMT == AddNetworkQueue)
        {
            return *(
unsigned int*) (currVMT 0xA4);
        }

        
currVMT++;
        if (
currVMT startVMT 10000)
        {
            
PrintOnConsole("GetSendPacketAddress: currVMT - startVMT > 10000\n");
            return 
0;
        }
    }

    
PrintOnConsole("GetSendPacketAddress: not find\n");
    return 
0;



Zubastic 25.07.2016 23:34

Re: C++ перехват пакетов
 
Хорошо, попробую.
Но у меня адрес находится верно в любом случае.


Текущее время: 01:00. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot