Вопрос Нужна помощь с CreateMove Hook

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
19 Мар 2021
Сообщения
5
Реакции
0
Не знаю что не так я делаю, но не он не прыгает. Будьте добры, подскажите что я не так делаю..


сурс:
Expand Collapse Copy
#include "pch.h"
 
#include <cstdint>
#include <vector>
#include <cstring>
#include <MinHook.h>
#include <iostream>
#include <atomic>
#include <cstdio>
 
#include "../includes/offsets.hpp"
#include "../includes/client_dll.hpp"
 
 
#include <Windows.h>
 
 
namespace test_input {
 
 
static uintptr_t ccsgoInputPtr = 0;
 
 
using CreateMoveFn = void(__fastcall*)(void* rcx, int edx, char r8, void* r9, void* a5, void* a6, void* a7, const char* a8);
static CreateMoveFn g_originalCreateMove = nullptr;
 
 
struct CUserCmd {
    int32_t     command_number;     
    int32_t     tick_count;         
    float       viewangles[3];     
    float       aimdirection[3];   
    float       forwardmove;       
    float       sidemove;           
    float       upmove;             
    int64_t     buttons;           
    uint8_t     impulse;           
    uint8_t     pad_35[3];         
    int32_t     weaponselect;       
    int32_t     weaponsubtype;     
    int32_t     random_seed;       
    int16_t     mousedx;           
    int16_t     mousedy;           
    uint8_t     hasbeenpredicted;   
    uint8_t     pad_49[0x78 - 0x49]; 
};
 
enum ECommandButtons : std::uint64_t {
    IN_ATTACK = 1ull << 0,
    IN_JUMP   = 1ull << 1,
    IN_DUCK   = 1ull << 2,
    IN_FORWARD= 1ull << 3,
    IN_BACK   = 1ull << 4,
    IN_USE    = 1ull << 5,
};
 
 
static const char* kCreateMovePattern = "48 8B C4 4C 89 40 ? 48 89 48 ? 55 53 41 57";
 
 
static const char* kCCSGOInputPattern = "48 8B 0D ? ? ? ? 48 8B 01 FF 50 ? 8B DF";
 
 
template<class T>
T absolute_to(uintptr_t value, ptrdiff_t rel_offset = 0x1, ptrdiff_t abs_offset = 0x0) noexcept {
    const auto jmp = value + rel_offset;
    const auto target = *reinterpret_cast<int32_t*>(jmp);
    if (target)
        return reinterpret_cast<T>(jmp + abs_offset + sizeof(int32_t) + target);
        
    return T();
}
 
 
static std::uint8_t* PatternScan(const char* module_name, const char* signature) noexcept {
    const HMODULE module_handle = GetModuleHandleA(module_name);
    if (!module_handle) return nullptr;
 
    auto pattern_to_byte = [](const char* pattern) {
        std::vector<int> bytes;
        const char* end = pattern + std::strlen(pattern);
        for (const char* current = pattern; current < end; ++current) {
            if (*current == ' ') continue;
            if (*current == '?') {
                ++current;
                if (current < end && *current == '?') ++current;
                bytes.push_back(-1);
            } else {
                bytes.push_back(std::strtoul(current, const_cast<char**>(&current), 16));
            }
        }
        return bytes;
    };
 
    const auto dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(module_handle);
    const auto nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<std::uint8_t*>(module_handle) + dos_header->e_lfanew);
    const size_t size_of_image = nt_headers->OptionalHeader.SizeOfImage;
    const auto pattern_bytes = pattern_to_byte(signature);
    auto scan_bytes = reinterpret_cast<std::uint8_t*>(module_handle);
 
    const size_t s = pattern_bytes.size();
    const int* d = pattern_bytes.data();
 
    for (size_t i = 0; i + s <= size_of_image; ++i) {
        bool found = true;
        for (size_t j = 0; j < s; ++j) {
            if (d[j] != -1 && scan_bytes[i + j] != d[j]) { found = false; break; }
        }
        if (found) return &scan_bytes[i];
    }
    return nullptr;
}
 
 
static uintptr_t GetVTable(void* object, int index) {
    if (!object) return 0;
    
    uintptr_t* vtablePtr = reinterpret_cast<uintptr_t*>(object);
    uintptr_t vtable = *vtablePtr;
    
    return reinterpret_cast<uintptr_t*>(vtable)[index];
}
 
 
static bool IsReadablePtr(const void* p) {
    if (!p) return false;
    MEMORY_BASIC_INFORMATION mbi{};
    if (!VirtualQuery(p, &mbi, sizeof(mbi))) return false;
    return (mbi.State == MEM_COMMIT) && (mbi.Protect != PAGE_NOACCESS);
}
 
 
static uintptr_t GetLocalPawn() {
    
    uintptr_t entitySystem = *reinterpret_cast<uintptr_t*>(GetModuleHandleA("client.dll") + cs2_dumper::offsets::client_dll::dwEntityList);
    if (!entitySystem) return 0;
    
    
    uintptr_t localController = *reinterpret_cast<uintptr_t*>(entitySystem + 0x8 * (1));
    if (!localController) return 0;
    
    return *reinterpret_cast<uintptr_t*>(localController + cs2_dumper::schemas::client_dll::CBasePlayerController::m_hPawn);
}
 
 
static bool IsOnGround(uintptr_t pawn) {
    if (!pawn) return false;
    int flags = *reinterpret_cast<int*>(pawn + cs2_dumper::schemas::client_dll::C_BaseEntity::m_fFlags);
    return (flags & 1) != 0;
}
 
 
static void* GetInputSystemInterface() {
    HMODULE client = GetModuleHandleA("client.dll");
    if (!client) return nullptr;
    
    
    auto createInterface = reinterpret_cast<void* (*)(const char*, int*)>(
        GetProcAddress(client, "CreateInterface"));
    
    if (!createInterface) return nullptr;
    
    
    int returnCode = 0;
    void* inputSystem = createInterface("InputSystemVersion001", &returnCode);
    
    if (inputSystem) {
        std::cout << "[test_input] Input System interface found at 0x" << std::hex
                  << reinterpret_cast<uintptr_t>(inputSystem) << std::dec << std::endl;
    } else {
        std::cout << "[test_input] Failed to get Input System interface, return code: " << returnCode << std::endl;
    }
    
    return inputSystem;
}
 
 
static void* GetInputSystemViaVTable() {
    HMODULE client = GetModuleHandleA("client.dll");
    if (!client) return nullptr;
    
    
    std::uint8_t* inputPattern = PatternScan("client.dll", "48 8B 0D ? ? ? ? 4C 8B C6 8B 10 E8");
    if (!inputPattern) return nullptr;
    
    
    void** inputSystemPtr = absolute_to<void**>(reinterpret_cast<uintptr_t>(inputPattern), 0x3, 0x0);
    if (!inputSystemPtr || !*inputSystemPtr) return nullptr;
    
    std::cout << "[test_input] Input System found via VTable at 0x" << std::hex
              << reinterpret_cast<uintptr_t>(*inputSystemPtr) << std::dec << std::endl;
    
    return *inputSystemPtr;
}
 
static std::atomic<bool> g_consoleAttached{false};
 
 
static void __fastcall CreateMove_Hook(void* rcx, int edx, char r8, void* r9, void* a5, void* a6, void* a7, const char* a8) {
    
    g_originalCreateMove(rcx, edx, r8, r9, a5, a6, a7, a8);
 
    if (!ccsgoInputPtr) return;
    uintptr_t input = *reinterpret_cast<uintptr_t*>(ccsgoInputPtr);
    if (!input || !IsReadablePtr(reinterpret_cast<void*>(input))) return;
 
    uintptr_t localPawn = GetLocalPawn();
    if (!localPawn) return;
 
    int tickBase = *reinterpret_cast<int*>(localPawn + cs2_dumper::schemas::client_dll::CBasePlayerController::m_nTickBase);
    int index = tickBase % 150;
 
    CUserCmd* cmd = reinterpret_cast<CUserCmd*>(input + 0x170 + index * sizeof(CUserCmd));
    if (!cmd || !IsReadablePtr(cmd)) return;
 
    
    if (cmd->buttons & (1ULL << 1)) {
        if (!IsOnGround(localPawn)) {
            cmd->buttons &= ~(1ULL << 1);
        }
    }
 
    
    cmd->viewangles[0] = 0.f;
}
 
static void AttachDebugConsole() {
    if (g_consoleAttached.load()) return;
    
    AllocConsole();
    freopen_s(reinterpret_cast<FILE**>(stdout), "CONOUT$", "w", stdout);
    freopen_s(reinterpret_cast<FILE**>(stdin), "CONIN$", "r", stdin);
    freopen_s(reinterpret_cast<FILE**>(stderr), "CONOUT$", "w", stderr);
    
    g_consoleAttached.store(true);
    std::cout << "[test_input] Debug console attached!" << std::endl;
}
 
static void FreeDebugConsole() {
    if (!g_consoleAttached.load()) return;
    
    FreeConsole();
    g_consoleAttached.store(false);
}
 
static void InitializeHook() {
    if (MH_Initialize() != MH_OK) {
        if (g_consoleAttached.load()) std::cout << "[test_input] MH_Initialize failed" << std::endl;
        return;
    }
 
    
    HMODULE client = nullptr;
    for (int i = 0; i < 50; i++) {
        client = GetModuleHandleA("client.dll");
        if (client) break;
        Sleep(100);
    }
    if (!client) {
        std::cout << "[test_input] client.dll not found after 5s" << std::endl;
        MH_Uninitialize();
        return;
    }
    std::cout << "[test_input] client.dll found at 0x" << std::hex << reinterpret_cast<uintptr_t>(client) << std::dec << std::endl;
 
    
    std::cout << "[test_input] Trying to get Input System via interface..." << std::endl;
    void* inputSystem = GetInputSystemInterface();
    
    if (inputSystem) {
        std::cout << "[test_input] Input System obtained via interface successfully!" << std::endl;
        
        
        int index = 5;
        uintptr_t createMoveAddr = GetVTable(inputSystem, index);
        if (createMoveAddr && IsReadablePtr(reinterpret_cast<void*>(createMoveAddr))) {
            std::cout << "[test_input] Found CreateMove at VTable index " << index << " at 0x" << std::hex << createMoveAddr << std::dec << std::endl;
            
            if (MH_CreateHook(reinterpret_cast<LPVOID>(createMoveAddr), reinterpret_cast<LPVOID>(&CreateMove_Hook),
                              reinterpret_cast<LPVOID*>(&g_originalCreateMove)) == MH_OK) {
                if (MH_EnableHook(reinterpret_cast<LPVOID>(createMoveAddr)) == MH_OK) {
                    std::cout << "[test_input] Input System CreateMove hook enabled successfully at index " << index << "!" << std::endl;
                    return;
                } else {
                    std::cout << "[test_input] MH_EnableHook failed for Input System CreateMove at index " << index << std::endl;
                    MH_RemoveHook(reinterpret_cast<LPVOID>(createMoveAddr));
                }
            } else {
                std::cout << "[test_input] MH_CreateHook failed for Input System CreateMove at index " << index << std::endl;
            }
        }
        
        std::cout << "[test_input] Input System CreateMove hook failed, trying fallback methods..." << std::endl;
    } else {
        std::cout << "[test_input] Input System interface failed, trying VTable method..." << std::endl;
        void* inputSystem = GetInputSystemViaVTable();
        if (inputSystem) {
            
            int index = 5;
            uintptr_t createMoveAddr = GetVTable(inputSystem, index);
            if (createMoveAddr && IsReadablePtr(reinterpret_cast<void*>(createMoveAddr))) {
                std::cout << "[test_input] Found CreateMove at VTable index " << index << " at 0x" << std::hex << createMoveAddr << std::dec << std::endl;
                
                if (MH_CreateHook(reinterpret_cast<LPVOID>(createMoveAddr), reinterpret_cast<LPVOID>(&CreateMove_Hook),
                                  reinterpret_cast<LPVOID*>(&g_originalCreateMove)) == MH_OK) {
                    if (MH_EnableHook(reinterpret_cast<LPVOID>(createMoveAddr)) == MH_OK) {
                        std::cout << "[test_input] VTable Input System CreateMove hook enabled successfully at index " << index << "!" << std::endl;
                        return;
                    } else {
                        std::cout << "[test_input] MH_EnableHook failed for VTable Input System CreateMove at index " << index << std::endl;
                        MH_RemoveHook(reinterpret_cast<LPVOID>(createMoveAddr));
                    }
                } else {
                    std::cout << "[test_input] MH_CreateHook failed for VTable Input System CreateMove at index " << index << std::endl;
                }
            }
        }
    }
 
    
    std::cout << "[test_input] Trying direct CreateMove hook..." << std::endl;
    std::uint8_t* createMoveAddr = PatternScan("client.dll", kCreateMovePattern);
    if (createMoveAddr) {
        std::cout << "[test_input] CreateMove found at 0x" << std::hex << reinterpret_cast<uintptr_t>(createMoveAddr) << std::dec << std::endl;
        
        if (MH_CreateHook(reinterpret_cast<LPVOID>(createMoveAddr), reinterpret_cast<LPVOID>(&CreateMove_Hook),
                          reinterpret_cast<LPVOID*>(&g_originalCreateMove)) == MH_OK) {
            if (MH_EnableHook(reinterpret_cast<LPVOID>(createMoveAddr)) == MH_OK) {
                std::cout << "[test_input] Direct CreateMove hook enabled successfully!" << std::endl;
                return;
            } else {
                std::cout << "[test_input] MH_EnableHook failed for direct CreateMove" << std::endl;
            }
        } else {
            std::cout << "[test_input] MH_CreateHook failed for direct CreateMove" << std::endl;
        }
        std::cout << "[test_input] Direct CreateMove hook failed, trying VTable..." << std::endl;
    }
 
    
    std::cout << "[test_input] Trying VTable hook on CCSGOInput..." << std::endl;
    std::uint8_t* ccsgoInput = PatternScan("client.dll", kCCSGOInputPattern);
    if (!ccsgoInput) {
        std::cout << "[test_input] CCSGOInput not found!" << std::endl;
        MH_Uninitialize();
        return;
    }
    std::cout << "[test_input] CCSGOInput pattern found at 0x" << std::hex << reinterpret_cast<uintptr_t>(ccsgoInput) << std::dec << std::endl;
 
    void** ccsgoInputPtrTemp = absolute_to<void**>(reinterpret_cast<uintptr_t>(ccsgoInput), 0x3, 0x0);
    if (!ccsgoInputPtrTemp || !*ccsgoInputPtrTemp) {
        std::cout << "[test_input] Failed to get CCSGOInput pointer!" << std::endl;
        MH_Uninitialize();
        return;
    }
    
    if (!IsReadablePtr(*ccsgoInputPtrTemp)) {
        std::cout << "[test_input] CCSGOInput pointer is not readable!" << std::endl;
        MH_Uninitialize();
        return;
    }
    
    
    ccsgoInputPtr = reinterpret_cast<uintptr_t>(ccsgoInputPtrTemp);
    std::cout << "[test_input] CCSGOInput pointer found at 0x" << std::hex << reinterpret_cast<uintptr_t>(*ccsgoInputPtrTemp) << std::dec << std::endl;
 
    
    int index = 5;
    uintptr_t vtable = GetVTable(*ccsgoInputPtrTemp, index);
    if (vtable && IsReadablePtr(reinterpret_cast<void*>(vtable))) {
        std::cout << "[test_input] Found CreateMove at CCSGOInput VTable index " << index << " at 0x" << std::hex << vtable << std::dec << std::endl;
        
        if (MH_CreateHook(reinterpret_cast<LPVOID>(vtable), reinterpret_cast<LPVOID>(&CreateMove_Hook),
                          reinterpret_cast<LPVOID*>(&g_originalCreateMove)) == MH_OK) {
            if (MH_EnableHook(reinterpret_cast<LPVOID>(vtable)) == MH_OK) {
                std::cout << "[test_input] VTable hook on CCSGOInput CreateMove enabled successfully at index " << index << "!" << std::endl;
                return;
            } else {
                std::cout << "[test_input] MH_EnableHook failed for CCSGOInput VTable hook at index " << index << std::endl;
                MH_RemoveHook(reinterpret_cast<LPVOID>(vtable));
            }
        } else {
            std::cout << "[test_input] MH_CreateHook failed for CCSGOInput VTable hook at index " << index << std::endl;
        }
    }
    
    std::cout << "[test_input] Failed to hook CreateMove!" << std::endl;
    MH_Uninitialize();
}
 
static void ShutdownHook() {
    MH_DisableHook(MH_ALL_HOOKS);
    MH_Uninitialize();
}
 
static DWORD WINAPI InitThread(LPVOID module) {
    AttachDebugConsole();
    InitializeHook();
    
    
    int counter = 0;
    while (true) {
        Sleep(1000);
        counter++;
        std::cout << "[test_input] Thread alive, counter: " << counter << std::endl;
        
        
        if (GetAsyncKeyState(VK_DELETE) & 0x8000) {
            std::cout << "[test_input] DELETE key detected!" << std::endl;
        }
        if (GetAsyncKeyState(VK_SPACE) & 0x8000) {
            std::cout << "[test_input] SPACE key detected!" << std::endl;
        }
    }
    
    return 0;
}
 
}
 
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID) {
    using namespace test_input;
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hModule);
        HANDLE h = CreateThread(nullptr, 0, InitThread, hModule, 0, nullptr);
        if (h) CloseHandle(h);
    } else if (ul_reason_for_call == DLL_PROCESS_DETACH) {
        ShutdownHook();
        FreeDebugConsole();
    }
    return TRUE;
}
 
void* rcx, int edx, char r8, void* r9, void* a5, void* a6, void* a7, const char* a8
у него всего 2 аргумента(третий это rcx и указатель на csgo_input остальные два это slot, active)
также неправильный rel для csgo_input
короче переписывай это я не могу это читать даже нормально потому что это very kinda unreadable
 
у него всего 2 аргумента(третий это rcx и указатель на csgo_input остальные два это slot, active)
также неправильный rel для csgo_input
короче переписывай это я не могу это читать даже нормально потому что это very kinda unreadable
Переписал

code:
Expand Collapse Copy
#include "pch.h"
#include <Windows.h>
#include <MinHook.h>
#include <iostream>
#include <vector>
#include <cstring>
#include <atomic>


constexpr const char* kCreateMovePattern = "48 8B C4 4C 89 40 ? 48 89 48 ? 55 53 41 57";
constexpr const char* kCCSGOInputPattern = "48 89 05 ? ? ? ? 0F 57 C0 0F 11 05";

static std::atomic<bool> g_consoleAttached = false;


static uintptr_t g_ccsgoInputPtr = 0;


using CreateMoveFn = bool(__fastcall*)(void* rcx, int slot, bool active);
static CreateMoveFn g_originalCreateMove = nullptr;


struct CUserCmd {
    int32_t command_number;
    int32_t tick_count;   
    float viewangles[3];   
    float forwardmove;     
    float sidemove;       
    float upmove;         
    uint64_t buttons;     
    
};


static uint8_t* PatternScan(const char* module_name, const char* pattern) {
    HMODULE module = GetModuleHandleA(module_name);
    if (!module) return nullptr;

    static auto pattern_to_bytes = [](const char* pattern_str) {
        std::vector<int> bytes;
        const char* current = pattern_str;
        while (*current) {
            if (*current == ' ') {
                ++current;
                continue;
            }
            if (*current == '?') {
                bytes.push_back(-1);
                if (*(current + 1) == '?') ++current;
                ++current;
            }
            else {
                bytes.push_back(std::strtoul(current, const_cast<char**>(&current), 16));
            }
        }
        return bytes;
        };

    auto dos_header = (PIMAGE_DOS_HEADER)module;
    auto nt_headers = (PIMAGE_NT_HEADERS)((uint8_t*)module + dos_header->e_lfanew);
    size_t size_of_image = nt_headers->OptionalHeader.SizeOfImage;

    std::vector<int> pattern_bytes = pattern_to_bytes(pattern);
    uint8_t* base = (uint8_t*)module;

    for (size_t i = 0; i < size_of_image - pattern_bytes.size(); ++i) {
        bool found = true;
        for (size_t j = 0; j < pattern_bytes.size(); ++j) {
            if (pattern_bytes[j] != -1 && base[i + j] != pattern_bytes[j]) {
                found = false;
                break;
            }
        }
        if (found)
            return &base[i];
    }
    return nullptr;
}


template<typename T>
static T RelativeToAbsolute(uintptr_t instr_addr, int offset_to_rel = 3) {
    int32_t rel = *reinterpret_cast<int32_t*>(instr_addr + offset_to_rel);
    return reinterpret_cast<T>(instr_addr + offset_to_rel + 4 + rel);
}


static bool IsReadable(const void* ptr) {
    if (!ptr) return false;
    MEMORY_BASIC_INFORMATION mbi{};
    if (!VirtualQuery(ptr, &mbi, sizeof(mbi))) return false;
    return mbi.State == MEM_COMMIT && (mbi.Protect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE));
}


static bool __fastcall Hooked_CreateMove(void* rcx, int slot, bool active) {
    std::cout << "[test_input] Hooked_CreateMove called: rcx=" << std::hex << rcx << ", slot=" << slot << ", active=" << active << std::dec << std::endl;

    if (!g_originalCreateMove) {
        std::cout << "[test_input] g_originalCreateMove is null, returning false" << std::endl;
        return false;
    }

    bool result = g_originalCreateMove(rcx, slot, active);
    std::cout << "[test_input] Original CreateMove returned: " << result << std::endl;
    if (!result) return false;

    if (!g_ccsgoInputPtr) {
        std::cout << "[test_input] g_ccsgoInputPtr is null" << std::endl;
        return result;
    }

    uintptr_t input_ptr = *reinterpret_cast<uintptr_t*>(g_ccsgoInputPtr);
    std::cout << "[test_input] input_ptr: " << std::hex << input_ptr << std::dec << std::endl;
    if (!IsReadable(reinterpret_cast<void*>(input_ptr))) {
        std::cout << "[test_input] input_ptr is not readable" << std::endl;
        return result;
    }

    
    if (slot < 0 || slot > 3) {
        std::cout << "[test_input] Invalid slot value: " << slot << std::endl;
        return result;
    }

    uintptr_t cmd_addr = input_ptr + 0x170 + slot * sizeof(CUserCmd);
    std::cout << "[test_input] cmd_addr: " << std::hex << cmd_addr << std::dec << std::endl;
    if (!IsReadable(reinterpret_cast<void*>(cmd_addr))) {
        std::cout << "[test_input] cmd_addr is not readable" << std::endl;
        return result;
    }

    CUserCmd* cmd = reinterpret_cast<CUserCmd*>(cmd_addr);
    std::cout << "[test_input] Modifying viewangles[0] at cmd: " << std::hex << cmd << std::dec << std::endl;
    cmd->viewangles[0] = 0.0f;

    return result;
}


static void InitializeHook() {
    if (MH_Initialize() != MH_OK) {
        std::cout << "[test_input] MH_Initialize failed" << std::endl;
        return;
    }

    HMODULE client = nullptr;
    for (int i = 0; i < 50 && !client; ++i) {
        client = GetModuleHandleA("client.dll");
        Sleep(100);
    }
    if (!client) {
        std::cout << "[test_input] client.dll not found" << std::endl;
        MH_Uninitialize();
        return;
    }

    
    uint8_t* ccsgoInputPatternAddr = PatternScan("client.dll", kCCSGOInputPattern);
    if (!ccsgoInputPatternAddr) {
        std::cout << "[test_input] CCSGOInput pattern not found" << std::endl;
        MH_Uninitialize();
        return;
    }

    void** ccsgoInputPtrTemp = RelativeToAbsolute<void**>(reinterpret_cast<uintptr_t>(ccsgoInputPatternAddr), 3);
    if (!ccsgoInputPtrTemp || !IsReadable(ccsgoInputPtrTemp)) {
        std::cout << "[test_input] CCSGOInput pointer invalid" << std::endl;
        MH_Uninitialize();
        return;
    }

    g_ccsgoInputPtr = reinterpret_cast<uintptr_t>(ccsgoInputPtrTemp);
    std::cout << "[test_input] CCSGOInput pointer: " << std::hex << *ccsgoInputPtrTemp << std::dec << std::endl;

    
    uintptr_t createMoveAddr = 0;
    uintptr_t vtable = 0;
    for (int i = 0; i < 150; ++i) {
        uintptr_t input = *reinterpret_cast<uintptr_t*>(g_ccsgoInputPtr);
        if (input && IsReadable(reinterpret_cast<void*>(input))) {
            vtable = *reinterpret_cast<uintptr_t*>(input);
            if (vtable && IsReadable(reinterpret_cast<void*>(vtable))) {
                
                createMoveAddr = *reinterpret_cast<uintptr_t*>(vtable + 21 * sizeof(void*));
                if (createMoveAddr && IsReadable(reinterpret_cast<void*>(createMoveAddr))) {
                    uint8_t* p = (uint8_t*)createMoveAddr;
                    if (p[0] == 0x48 && p[1] == 0x8B && p[2] == 0xC4) {
                        std::cout << "[test_input] Found CreateMove at vtable index 21" << std::endl;
                        break;
                    }
                    createMoveAddr = 0;
                }
                
                for (int j = 0; j < 30 && !createMoveAddr; ++j) {
                    createMoveAddr = *reinterpret_cast<uintptr_t*>(vtable + j * sizeof(void*));
                    if (createMoveAddr && IsReadable(reinterpret_cast<void*>(createMoveAddr))) {
                        uint8_t* p = (uint8_t*)createMoveAddr;
                        if (p[0] == 0x48 && p[1] == 0x8B && p[2] == 0xC4) {
                            std::cout << "[test_input] Found CreateMove at vtable index " << j << std::endl;
                            break;
                        }
                        createMoveAddr = 0;
                    }
                }
                if (createMoveAddr) break;
            }
        }
        std::cout << "[test_input] Retry " << i + 1 << ": Waiting for valid vtable (input=" << std::hex << input << ", vtable=" << vtable << ", createMoveAddr=" << createMoveAddr << ")" << std::dec << std::endl;
        Sleep(200);
    }

    
    if (!createMoveAddr || !IsReadable(reinterpret_cast<void*>(createMoveAddr))) {
        std::cout << "[test_input] VTable CreateMove invalid, trying pattern scan" << std::endl;
        uint8_t* createMovePatternAddr = PatternScan("client.dll", kCreateMovePattern);
        if (!createMovePatternAddr) {
            std::cout << "[test_input] CreateMove pattern not found" << std::endl;
            MH_Uninitialize();
            return;
        }
        createMoveAddr = reinterpret_cast<uintptr_t>(createMovePatternAddr);
    }

    std::cout << "[test_input] createMoveAddr = " << std::hex << createMoveAddr << std::dec << std::endl;

    
    if (!createMoveAddr || !IsReadable(reinterpret_cast<void*>(createMoveAddr))) {
        std::cout << "[test_input] Invalid createMoveAddr (likely uninitialized), aborting hook" << std::endl;
        MH_Uninitialize();
        return;
    }

    uint8_t* p = (uint8_t*)createMoveAddr;
    std::cout << "[test_input] createMoveAddr first bytes: ";
    for (int i = 0; i < 10; ++i) {
        std::cout << std::hex << (int)p[i] << " ";
    }
    std::cout << std::dec << std::endl;

    if (MH_CreateHook(reinterpret_cast<LPVOID>(createMoveAddr), reinterpret_cast<LPVOID>(&Hooked_CreateMove),
        reinterpret_cast<LPVOID*>(&g_originalCreateMove)) != MH_OK) {
        std::cout << "[test_input] MH_CreateHook failed" << std::endl;
        MH_Uninitialize();
        return;
    }

    if (MH_EnableHook(reinterpret_cast<LPVOID>(createMoveAddr)) != MH_OK) {
        std::cout << "[test_input] MH_EnableHook failed" << std::endl;
        MH_RemoveHook(reinterpret_cast<LPVOID>(createMoveAddr));
        MH_Uninitialize();
        return;
    }

    std::cout << "[test_input] CreateMove hook installed at " << std::hex << createMoveAddr << std::dec << std::endl;
}


static void AttachConsole() {
    if (g_consoleAttached.load()) return;
    AllocConsole();
    freopen_s(reinterpret_cast<FILE**>(stdout), "CONOUT$", "w", stdout);
    freopen_s(reinterpret_cast<FILE**>(stdin), "CONIN$", "r", stdin);
    freopen_s(reinterpret_cast<FILE**>(stderr), "CONOUT$", "w", stderr);
    g_consoleAttached = true;
    std::cout << "[test_input] Console attached" << std::endl;
}

static void FreeConsoleIfAttached() {
    if (!g_consoleAttached.load()) return;
    FreeConsole();
    g_consoleAttached = false;
}


static DWORD WINAPI InitThread(LPVOID) {
    AttachConsole();
    InitializeHook();

    while (true) {
        Sleep(1000);
        if (GetAsyncKeyState(VK_DELETE) & 0x8000) break;
    }

    MH_DisableHook(MH_ALL_HOOKS);
    MH_Uninitialize();
    FreeConsoleIfAttached();
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hModule);
        CreateThread(nullptr, 0, InitThread, nullptr, 0, nullptr);
    }
    return TRUE;
}
 
Назад
Сверху Снизу