Вопрос Помогите с установкой хука

Начинающий
Статус
Оффлайн
Регистрация
8 Ноя 2023
Сообщения
4
Реакции[?]
0
Поинты[?]
0
В общем я хочу перехватить аргументы функции SendMessage() из ISteamGameCoordinator, но не получается поставить хук
вот код:
C++:
DWORD GetModuleBaseAddr(DWORD PID, const TCHAR* szModuleName) {
    DWORD dwModuleBaseAddr = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID);

    if (hSnapshot != INVALID_HANDLE_VALUE) {
        MODULEENTRY32 ModuleEntry32;
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);

        if (Module32First(hSnapshot, &ModuleEntry32)) {
            do {
                if (strcmp(ModuleEntry32.szModule, szModuleName) == 0) {
                    dwModuleBaseAddr = (DWORD_PTR)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while(Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }

    return dwModuleBaseAddr;
}

inline void HookFunc(void* func, void* detour, void* original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, (LPVOID*)original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);
    
    if (HookCreateStatus != MH_OK | HookEnableStatus != MH_OK) {
        printf("hook error\n");
    }
};

inline void __fastcall HKSendMessage(void* _this, uint32_t unMsgType, const void* pubData, uint32_t cubData) {
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
}


DWORD WINAPI runBot(LPVOID lpParam) {
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    DWORD PID = GetCurrentProcessId();
    DWORD ClientBaseAddr = GetModuleBaseAddr(PID, "client.dll");
    uintptr_t** vtable = (uintptr_t**)((DWORD)ClientBaseAddr + 0x18);
    uintptr_t* pSendMessage = vtable[0];

    printf("PID:\t\t%d\n", PID);
    printf("ClientBaseAddr:\t%X\n", ClientBaseAddr);

    MH_STATUS HookInitializeStatus = MH_Initialize();
    if (HookInitializeStatus == MH_OK) {
        HookFunc(&HKSendMessage, pSendMessage, NULL);
    }
    
    return 1;
}
подозреваю что я как то не так получаю адрес функции
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
774
Реакции[?]
330
Поинты[?]
62K
В общем я хочу перехватить аргументы функции SendMessage() из ISteamGameCoordinator, но не получается поставить хук
вот код:
C++:
DWORD GetModuleBaseAddr(DWORD PID, const TCHAR* szModuleName) {
    DWORD dwModuleBaseAddr = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID);

    if (hSnapshot != INVALID_HANDLE_VALUE) {
        MODULEENTRY32 ModuleEntry32;
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);

        if (Module32First(hSnapshot, &ModuleEntry32)) {
            do {
                if (strcmp(ModuleEntry32.szModule, szModuleName) == 0) {
                    dwModuleBaseAddr = (DWORD_PTR)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while(Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }

    return dwModuleBaseAddr;
}

inline void HookFunc(void* func, void* detour, void* original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, (LPVOID*)original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);
   
    if (HookCreateStatus != MH_OK | HookEnableStatus != MH_OK) {
        printf("hook error\n");
    }
};

inline void __fastcall HKSendMessage(void* _this, uint32_t unMsgType, const void* pubData, uint32_t cubData) {
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
}


DWORD WINAPI runBot(LPVOID lpParam) {
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    DWORD PID = GetCurrentProcessId();
    DWORD ClientBaseAddr = GetModuleBaseAddr(PID, "client.dll");
    uintptr_t** vtable = (uintptr_t**)((DWORD)ClientBaseAddr + 0x18);
    uintptr_t* pSendMessage = vtable[0];

    printf("PID:\t\t%d\n", PID);
    printf("ClientBaseAddr:\t%X\n", ClientBaseAddr);

    MH_STATUS HookInitializeStatus = MH_Initialize();
    if (HookInitializeStatus == MH_OK) {
        HookFunc(&HKSendMessage, pSendMessage, NULL);
    }
   
    return 1;
}
подозреваю что я как то не так получаю адрес функции
1) твой GetModuleBaseAddr это функция для экстерналов. нахуя она тебе нужна если у тебя интернал?(если у тебя не интернал то какого хуя ты пишешь vtable[0] и как ты собрался хукать). юзай GetModuleHandleA она интернал
2) адрес модуля это не DWORD это uintptr_t(т.е. либо uint32 либо uint64 в зависимости от платформы под которую компилишь)
3) ну так логай значения проверяй адекватные они или нет. что значит "подозреваю что я как то не так получаю адрес функции". взял реальный адрес(в дебагере или еще в чём-нибудь), сравнил с тем что у тебя получилось - оно либо совпало, либо ты чето не так делаешь.
4) можно узнать что это за вуду магия ClientBaseAddr + 0x18? ты знаешь что на RVA 0x18 лежит? там лежит IMAGE_DOS_HEADER::e_lfarlc(File address of relocation table). это совсем не то что тебе нужно.
 
Начинающий
Статус
Оффлайн
Регистрация
8 Ноя 2023
Сообщения
4
Реакции[?]
0
Поинты[?]
0
1) твой GetModuleBaseAddr это функция для экстерналов. нахуя она тебе нужна если у тебя интернал?(если у тебя не интернал то какого хуя ты пишешь vtable[0] и как ты собрался хукать). юзай GetModuleHandleA она интернал
2) адрес модуля это не DWORD это uintptr_t(т.е. либо uint32 либо uint64 в зависимости от платформы под которую компилишь)
3) ну так логай значения проверяй адекватные они или нет. что значит "подозреваю что я как то не так получаю адрес функции". взял реальный адрес(в дебагере или еще в чём-нибудь), сравнил с тем что у тебя получилось - оно либо совпало, либо ты чето не так делаешь.
4) можно узнать что это за вуду магия ClientBaseAddr + 0x18? ты знаешь что на RVA 0x18 лежит? там лежит IMAGE_DOS_HEADER::e_lfarlc(File address of relocation table). это совсем не то что тебе нужно.
где и как адреса брать?
насчет вуду магии это я дурачок неправильно понял) вот

код подправил вроде, но не работает подскажи где я еблан))

Код:
#include "pch.h"
#include <Psapi.h>
#define ui unsigned long long

enum EGCResults
{
    k_EGCResultOK = 0,
    k_EGCResultNoMessage = 1,
    k_EGCResultBufferTooSmall = 2,
    k_EGCResultNotLoggedOn = 3,
    k_EGCResultInvalidMessage = 4,
};

class ISteamGameCoordinator
{
public:
    virtual EGCResults SendMessage(uint32_t unMsgType, const void* pubData, uint32_t cubData) = 0;
    virtual bool IsMessageAvailable(uint32_t* pcubMsgSize) = 0;
    virtual EGCResults RetrieveMessage(uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize) = 0;
};

inline void HookFunc(void* func, void* detour, void* original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, (LPVOID*)original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);
    
    if (HookCreateStatus != MH_OK) {
        printf("hook error1\n");
    }
    if (HookEnableStatus != MH_OK) {
        printf("hook error2\n");
    }
};

void hkSendMessage(ISteamGameCoordinator* thisptr, uint32_t unMsgType, const void* pubData, uint32_t cubData) {
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
    MessageBox(NULL, "called SendMessage", "My Message", MB_ICONINFORMATION);
}

typedef void* (*oCreateInterface)(const char*, int);
oCreateInterface pCreateInterface;
ui CreateInterface(const char* szModule, const char* szInterface) {
    pCreateInterface = (oCreateInterface)GetProcAddress(GetModuleHandleA(szModule), "CreateInterface");
    return (ui)pCreateInterface(szInterface, 0);
}

DWORD WINAPI runBot(LPVOID lpParam) {
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    uintptr_t ClientBaseAddr = reinterpret_cast<uintptr_t>(GetModuleHandle("client.dll"));
    ui mDOTA_CLIENT_GCCLIENT = CreateInterface("client.dll", "DOTA_CLIENT_GCCLIENT");

    uintptr_t** vtable = (uintptr_t**)((ISteamGameCoordinator*)(mDOTA_CLIENT_GCCLIENT + 0x18));
    uintptr_t* pSendMessage = vtable[0];

    printf("ClientBaseAddr:\t\t%X\n", ClientBaseAddr);
    printf("mDOTA_CLIENT_GCCLIENT:\t%X\n", mDOTA_CLIENT_GCCLIENT);
    printf("vtable:\t\t\t%X\n", vtable);
    printf("pSendMessage:\t\t%X\n", pSendMessage);

    
    MH_STATUS HookEnableStatus = MH_Initialize();
    HookFunc(&hkSendMessage, pSendMessage, NULL);

    return 1;
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  reason, LPVOID lpReserved){
    switch (reason) {
        case DLL_PROCESS_ATTACH: {
            MessageBox(NULL ,"my Message", "My Message", MB_ICONINFORMATION);
            auto thread = CreateThread(NULL, 0, &runBot, NULL, 0, NULL);
            CloseHandle(thread);
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
774
Реакции[?]
330
Поинты[?]
62K
где и как адреса брать?
насчет вуду магии это я дурачок неправильно понял) вот

код подправил вроде, но не работает подскажи где я еблан))

Код:
#include "pch.h"
#include <Psapi.h>
#define ui unsigned long long

enum EGCResults
{
    k_EGCResultOK = 0,
    k_EGCResultNoMessage = 1,
    k_EGCResultBufferTooSmall = 2,
    k_EGCResultNotLoggedOn = 3,
    k_EGCResultInvalidMessage = 4,
};

class ISteamGameCoordinator
{
public:
    virtual EGCResults SendMessage(uint32_t unMsgType, const void* pubData, uint32_t cubData) = 0;
    virtual bool IsMessageAvailable(uint32_t* pcubMsgSize) = 0;
    virtual EGCResults RetrieveMessage(uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize) = 0;
};

inline void HookFunc(void* func, void* detour, void* original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, (LPVOID*)original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);
   
    if (HookCreateStatus != MH_OK) {
        printf("hook error1\n");
    }
    if (HookEnableStatus != MH_OK) {
        printf("hook error2\n");
    }
};

void hkSendMessage(ISteamGameCoordinator* thisptr, uint32_t unMsgType, const void* pubData, uint32_t cubData) {
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
    MessageBox(NULL, "called SendMessage", "My Message", MB_ICONINFORMATION);
}

typedef void* (*oCreateInterface)(const char*, int);
oCreateInterface pCreateInterface;
ui CreateInterface(const char* szModule, const char* szInterface) {
    pCreateInterface = (oCreateInterface)GetProcAddress(GetModuleHandleA(szModule), "CreateInterface");
    return (ui)pCreateInterface(szInterface, 0);
}

DWORD WINAPI runBot(LPVOID lpParam) {
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    uintptr_t ClientBaseAddr = reinterpret_cast<uintptr_t>(GetModuleHandle("client.dll"));
    ui mDOTA_CLIENT_GCCLIENT = CreateInterface("client.dll", "DOTA_CLIENT_GCCLIENT");

    uintptr_t** vtable = (uintptr_t**)((ISteamGameCoordinator*)(mDOTA_CLIENT_GCCLIENT + 0x18));
    uintptr_t* pSendMessage = vtable[0];

    printf("ClientBaseAddr:\t\t%X\n", ClientBaseAddr);
    printf("mDOTA_CLIENT_GCCLIENT:\t%X\n", mDOTA_CLIENT_GCCLIENT);
    printf("vtable:\t\t\t%X\n", vtable);
    printf("pSendMessage:\t\t%X\n", pSendMessage);

   
    MH_STATUS HookEnableStatus = MH_Initialize();
    HookFunc(&hkSendMessage, pSendMessage, NULL);

    return 1;
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  reason, LPVOID lpReserved){
    switch (reason) {
        case DLL_PROCESS_ATTACH: {
            MessageBox(NULL ,"my Message", "My Message", MB_ICONINFORMATION);
            auto thread = CreateThread(NULL, 0, &runBot, NULL, 0, NULL);
            CloseHandle(thread);
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
1) твой принт хуита %X это инт32. лучше %p
2) ты зачемто пытаешься хукнуть сам свою функцию чтобы она вызывала оригинальную :)) местами поменяй аргументы при вызове HookFunc.
3) ты не так считываешь гс и его втейблу
4) и я надеюсь ты понимаешь что такой хук легко детектится?
кароче както так условно
C++:
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
#include <stdio.h>

#include "minhook/MinHook.h"

enum EGCResults
{
    k_EGCResultOK = 0,
    k_EGCResultNoMessage = 1,
    k_EGCResultBufferTooSmall = 2,
    k_EGCResultNotLoggedOn = 3,
    k_EGCResultInvalidMessage = 4,
};

class ISteamGameCoordinator
{
public:
#pragma push_macro("SendMessage")
#undef SendMessage
    virtual EGCResults SendMessage(std::uint32_t unMsgType, const void* pubData, std::uint32_t cubData) = 0;
#pragma pop_macro("SendMessage")

    virtual bool IsMessageAvailable(std::uint32_t* pcubMsgSize) = 0;
    virtual EGCResults RetrieveMessage(std::uint32_t* punMsgType, void* pubDest, std::uint32_t cubDest, std::uint32_t* pcubMsgSize) = 0;
};

inline void HookFunc(void* func, void* detour, void** original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);

    if (HookCreateStatus != MH_OK) {
        printf("hook error1\n");
    }
    if (HookEnableStatus != MH_OK) {
        printf("hook error2\n");
    }
    printf("hello world\n");
};

EGCResults(*oSendMessage)(ISteamGameCoordinator*, std::uint32_t, const void*, std::uint32_t) = nullptr;
EGCResults hkSendMessage(ISteamGameCoordinator* thisptr, std::uint32_t unMsgType, const void* pubData, std::uint32_t cubData)
{
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
    MessageBoxA(NULL, "called SendMessage", "My Message", MB_ICONINFORMATION);
    return oSendMessage(thisptr, unMsgType, pubData, cubData);
}

typedef void* (*oCreateInterface)(const char*, int);
oCreateInterface pCreateInterface;
void* CreateInterface(const char* szModule, const char* szInterface) {
    pCreateInterface = (oCreateInterface)GetProcAddress(GetModuleHandleA(szModule), "CreateInterface");
    return pCreateInterface(szInterface, 0);
}

DWORD WINAPI runBot(LPVOID lpParam)
{
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    auto mDOTA_CLIENT_GCCLIENT = (char*)CreateInterface("client.dll", "DOTA_CLIENT_GCCLIENT");

    ISteamGameCoordinator* gc = *(ISteamGameCoordinator**)(mDOTA_CLIENT_GCCLIENT + 0x18);
    if (gc)
    {
        void** vtable = *(void***)(gc);
        void* pSendMessage = vtable[0];

        printf("mDOTA_CLIENT_GCCLIENT: 0x%p\n", mDOTA_CLIENT_GCCLIENT);
        printf("gc: 0x%p\n", gc);
        printf("vtable: 0x%p\n", vtable);
        printf("pSendMessage: 0x%p\n", pSendMessage);
        MH_STATUS HookEnableStatus = MH_Initialize();
        if (HookEnableStatus != MH_OK) {
            printf("hook init error\n");
        }
        else
            HookFunc(pSendMessage, hkSendMessage, (void**)&oSendMessage);
    }
    else
        printf("blah blah blah steam not initialized\n");

    return 1;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  reason, LPVOID lpReserved) {
    switch (reason) {
    case DLL_PROCESS_ATTACH: {
        MessageBoxA(NULL, "my Message", "My Message", MB_ICONINFORMATION);
        auto thread = CreateThread(NULL, 0, &runBot, NULL, 0, NULL);
        CloseHandle(thread);
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
 
Начинающий
Статус
Оффлайн
Регистрация
8 Ноя 2023
Сообщения
4
Реакции[?]
0
Поинты[?]
0
1) твой принт хуита %X это инт32. лучше %p
2) ты зачемто пытаешься хукнуть сам свою функцию чтобы она вызывала оригинальную :)) местами поменяй аргументы при вызове HookFunc.
3) ты не так считываешь гс и его втейблу
4) и я надеюсь ты понимаешь что такой хук легко детектится?
кароче както так условно
C++:
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
#include <stdio.h>

#include "minhook/MinHook.h"

enum EGCResults
{
    k_EGCResultOK = 0,
    k_EGCResultNoMessage = 1,
    k_EGCResultBufferTooSmall = 2,
    k_EGCResultNotLoggedOn = 3,
    k_EGCResultInvalidMessage = 4,
};

class ISteamGameCoordinator
{
public:
#pragma push_macro("SendMessage")
#undef SendMessage
    virtual EGCResults SendMessage(std::uint32_t unMsgType, const void* pubData, std::uint32_t cubData) = 0;
#pragma pop_macro("SendMessage")

    virtual bool IsMessageAvailable(std::uint32_t* pcubMsgSize) = 0;
    virtual EGCResults RetrieveMessage(std::uint32_t* punMsgType, void* pubDest, std::uint32_t cubDest, std::uint32_t* pcubMsgSize) = 0;
};

inline void HookFunc(void* func, void* detour, void** original) {
    MH_STATUS HookCreateStatus = MH_CreateHook(func, detour, original);
    MH_STATUS HookEnableStatus = MH_EnableHook(func);

    if (HookCreateStatus != MH_OK) {
        printf("hook error1\n");
    }
    if (HookEnableStatus != MH_OK) {
        printf("hook error2\n");
    }
    printf("hello world\n");
};

EGCResults(*oSendMessage)(ISteamGameCoordinator*, std::uint32_t, const void*, std::uint32_t) = nullptr;
EGCResults hkSendMessage(ISteamGameCoordinator* thisptr, std::uint32_t unMsgType, const void* pubData, std::uint32_t cubData)
{
    printf("called SendMessage\n");
    printf("unMsgType: %d\n", unMsgType);
    MessageBoxA(NULL, "called SendMessage", "My Message", MB_ICONINFORMATION);
    return oSendMessage(thisptr, unMsgType, pubData, cubData);
}

typedef void* (*oCreateInterface)(const char*, int);
oCreateInterface pCreateInterface;
void* CreateInterface(const char* szModule, const char* szInterface) {
    pCreateInterface = (oCreateInterface)GetProcAddress(GetModuleHandleA(szModule), "CreateInterface");
    return pCreateInterface(szInterface, 0);
}

DWORD WINAPI runBot(LPVOID lpParam)
{
    if (AllocConsole())
    {
        FILE* file{};
        freopen_s(&file, "CONOUT$", "w+", stdout);
    }

    auto mDOTA_CLIENT_GCCLIENT = (char*)CreateInterface("client.dll", "DOTA_CLIENT_GCCLIENT");

    ISteamGameCoordinator* gc = *(ISteamGameCoordinator**)(mDOTA_CLIENT_GCCLIENT + 0x18);
    if (gc)
    {
        void** vtable = *(void***)(gc);
        void* pSendMessage = vtable[0];

        printf("mDOTA_CLIENT_GCCLIENT: 0x%p\n", mDOTA_CLIENT_GCCLIENT);
        printf("gc: 0x%p\n", gc);
        printf("vtable: 0x%p\n", vtable);
        printf("pSendMessage: 0x%p\n", pSendMessage);
        MH_STATUS HookEnableStatus = MH_Initialize();
        if (HookEnableStatus != MH_OK) {
            printf("hook init error\n");
        }
        else
            HookFunc(pSendMessage, hkSendMessage, (void**)&oSendMessage);
    }
    else
        printf("blah blah blah steam not initialized\n");

    return 1;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  reason, LPVOID lpReserved) {
    switch (reason) {
    case DLL_PROCESS_ATTACH: {
        MessageBoxA(NULL, "my Message", "My Message", MB_ICONINFORMATION);
        auto thread = CreateThread(NULL, 0, &runBot, NULL, 0, NULL);
        CloseHandle(thread);
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

благодарю за помощь!!
хук моей конечно это кринж)) а то что детектится не страшно, мне буквально айдишки у пары сообщений узнать надо
 
Сверху Снизу