Вопрос Пытаюсь сделать движения через хук CreateMove, но все четно

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

Нужно чтобы шло вперед и все, я хз что не так делаю, а я делаю что то не так я в этом уверен. Вообщем помогите плис..

CreateMove:
Expand Collapse Copy
bool __fastcall CreateMove_Hook(void* pCSGOInput, int nSlot, CUserCmd* pUserCmd) {
    if (!pUserCmd || !pUserCmd->pBaseUserCmdPB || !pUserCmd->pBaseUserCmdPB->pInButtonState)
        return g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

    bool ret = g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

    auto* base = pUserCmd->pBaseUserCmdPB;
    auto* buttons = base->pInButtonState;
    auto* pButtons = &pUserCmd->InButtonState;


    auto& subtick = base->SubtickMoveStep;
    subtick.nCurrentSize = 0; 


    if (GetAsyncKeyState('I') & 0x8000) {
        base->flForwardMove = 450.0f;
        base->flSideMove = 0.0f;
        buttons->nButtonHeld &= ~IN_FORWARD;
        buttons->nButtonChanged &= ~IN_FORWARD;
        base->nImpulse = 1;
    }


    if (GetAsyncKeyState('H') & 0x8000) {
        buttons->nButtonHeld |= IN_BACK;
        buttons->nButtonChanged |= IN_BACK;
    }

    // метовые АА без хука на кам
    if (base->pViewAngles) {
        QAngle_t fakeAngles = base->pViewAngles->angValue;
        if (GetAsyncKeyState('K') & 0x8000) {
            fakeAngles.pitch = ((float)rand() / RAND_MAX) * 178.0f - 89.0f;
            fakeAngles.yaw = ((float)rand() / RAND_MAX) * 360.0f - 180.0f;
        }
        base->pViewAngles->angValue = fakeAngles;
    }

    return ret;
}

Я так же пробовал так:

второй вариант:
Expand Collapse Copy
bool __fastcall CreateMove_Hook(void* pCSGOInput, int nSlot, CUserCmd* pUserCmd) {
    if (!pUserCmd || !pUserCmd->pBaseUserCmdPB || !pUserCmd->pBaseUserCmdPB->pInButtonState)
        return g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

    bool ret = g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

    auto* base = pUserCmd->pBaseUserCmdPB;
    auto* buttons = base->pInButtonState;

    auto& subtick = base->SubtickMoveStep;
    subtick.nCurrentSize = 1;
    auto* step = subtick.IsValid(0) ? subtick[0] : nullptr;
    if (!step) return ret;

    step->bIsPressed = false;
    step->nButton = 0;
    step->flAnalogForwardDelta = 0.0f;
    step->flAnalogLeftDelta = 0.0f;
    step->flWhen = static_cast<float>(GetTickCount64()) * 0.001f;

    static const std::pair<ECommandButtons, float> directions[] = {
        {ECommandButtons::IN_FORWARD, 1.0f},      // I
        {ECommandButtons::IN_MOVERIGHT, 1.0f},    // L
        {ECommandButtons::IN_BACK, -1.0f},        // K
        {ECommandButtons::IN_MOVELEFT, -1.0f}     // J
    };
    static int dirIndex = 0;
    static DWORD lastChange = 0;
    DWORD now = GetTickCount();

    const DWORD delayMs = 250;

    if (now - lastChange >= delayMs) {
        dirIndex = (dirIndex + 1) % 4;
        lastChange = now;
    }

    ECommandButtons btn = directions[dirIndex].first;
    float analogVal = directions[dirIndex].second;

    step->bIsPressed = true;
    step->nButton |= btn;

    if (btn == ECommandButtons::IN_FORWARD || btn == ECommandButtons::IN_BACK)
        step->flAnalogForwardDelta = analogVal;
    else
        step->flAnalogLeftDelta = analogVal;

    buttons->nButtonHeld |= btn;
    buttons->nButtonChanged |= btn;

    base->flForwardMove = step->flAnalogForwardDelta * 450.0f;
    base->flSideMove = step->flAnalogLeftDelta * 450.0f;

    return ret;
}


Но ничего не получилось.

полный код:
Expand Collapse Copy
// dllmain.cpp
#include "pch.h"
#include <Windows.h>
#include <MinHook.h>
#include <iostream>
#include <atomic>
#include <vector>
#include "pointer.h"
#include "../includes/client_dll.hpp"
#include "../includes/offsets.hpp" // actual

namespace test_input {

    static std::atomic<bool> g_consoleAttached{ false };

    // ---------------- Types & Globals ----------------
    class CUserCmd;
    using CreateMoveFn = bool(__fastcall*)(void* pCSGOInput, int nSlot, CUserCmd* pUserCmd);
    static CreateMoveFn g_originalCreateMove = nullptr;




    class CUserCmdBase {
    public:
        void* vTable;

        //virtual ~CUserCmdBase() = 0;

        //virtual void Unk1() = 0;
        //virtual void Unk2() = 0;
        //virtual void Unk3() = 0;
        //virtual void Unk4() = 0;
        //virtual void Unk5() = 0;
        //virtual void Unk6() = 0;
        //virtual void Unk7() = 0;

        std::uint32_t nSequenceNumber;
    };
    struct Vector4D_t { float x, y, z, w; };
    struct QAngle_t { float pitch, yaw, roll; };
    template<typename T>
    class CUserCmdBaseHost : public CUserCmdBase, public T {
    public:
        //virtual ~CUserCmdBaseHost() = 0;
    };

    class CMessageLite {
    public:
        void* vTable;

        //virtual ~CMessageLite() = 0;

        //virtual void Unk1() = 0;
        //virtual void Unk2() = 0;
        //virtual void Unk3() = 0;
        //virtual void Unk4() = 0;
        //virtual void Unk5() = 0;
        //virtual void Unk6() = 0;
        //virtual std::size_t ByteSizeLong() = 0;
        //virtual void Unk8() = 0;
        //virtual void Unk9() = 0;
        //virtual void Unk10() = 0;
        //virtual void Unk11() = 0;
    };

    class CMessage : public CMessageLite {
    public:
        //virtual void Unk1() = 0;
        //virtual void Unk2() = 0;
        //virtual void Unk3() = 0;
        //virtual void Unk4() = 0;
        //virtual void Unk5() = 0;
    };



    class CBasePB : public CMessage {
    public:
        std::uint32_t nHasBits;
        std::uint64_t nCachedBits;

        void SetBits(std::uint64_t nBits) {
            nCachedBits |= nBits;
        }

        std::uint64_t GetAlignedBits() const {
            std::uint32_t nAlignedBits = nHasBits & ~3U;
            if (nHasBits & 0x1)
                return *reinterpret_cast<std::uint64_t*>(nAlignedBits);

            return static_cast<std::uint64_t>(nAlignedBits);
        }
    };

    class CCSGOInterpolationInfoPB_CL : public CBasePB {
    public:
        float flFraction;
    };

    class CMsgQAngle : public CBasePB {
    public:
        QAngle_t angValue;
    };

    class CCSGOInterpolationInfoPB : public CBasePB {
    public:
        float flFraction;
        int nSrcTick;
        int nDstTick;
    };
    class CMsgVector : public CBasePB {
    public:
        Vector4D_t vecValue;
    };

    class CCSGOInputHistoryEntryPB : public CBasePB {
    public:
        CMsgQAngle* pViewAngles;
        CCSGOInterpolationInfoPB_CL* cl_interp;
        CCSGOInterpolationInfoPB* sv_interp0;
        CCSGOInterpolationInfoPB* sv_interp1;
        CCSGOInterpolationInfoPB* player_interp;
        CMsgVector* pShootPosition;
        CMsgVector* pTargetHeadPositionCheck;
        CMsgVector* pTargetAbsPositionCheck;
        CMsgQAngle* pTargetAngPositionCheck;
        int nRenderTickCount;
        float flRenderTickFraction;
        int nPlayerTickCount;
        float flPlayerTickFraction;
        int nFrameNumber;
        int nTargetEntityIndex;
    };

#define MAX_ELEMENTS ((INT_MAX - 2 * sizeof(int)) / sizeof(void*))





    template<typename T>
    class CRepeatedPtrFieldBase {
    public:
        struct Rep_t {
            int nAllocatedSize;
            T* pElements[MAX_ELEMENTS];
        };

        void* pArena;
        int nCurrentSize;
        int nTotalSize;
        Rep_t* pRep;
    };

    template<typename T>
    class CRepeatedPtrField : public CRepeatedPtrFieldBase<T> {
    public:
        T* operator[](int nIndex) {
            if (!IsValid(nIndex))
                return nullptr;

            return this->pRep->pElements[nIndex];
        }

        bool IsValid(int nIndex) {
            if (this->pRep == nullptr)
                return false;

            if (nIndex >= this->pRep->nAllocatedSize)
                return false;

            if (nIndex >= this->nCurrentSize)
                return false;

            return true;
        }

        //Element* Add();
        //void AddAllocated(Element* value);
    };



    class CInButtonStatePB : public CBasePB {
    public:
        std::uint64_t nButtonHeld;
        std::uint64_t nButtonChanged;
        std::uint64_t nButtonScroll;
    };

    class CSubtickMoveStep : CBasePB {
    public:
        std::uint64_t nButton;
        bool bIsPressed;
        float flWhen;
        float flAnalogForwardDelta;
        float flAnalogLeftDelta;
        float flAnalogPitchDelta;
        float flAnalogYawDelta;
    };



    class CBaseUserCmdPB : public CBasePB {
    public:
        CRepeatedPtrField<CSubtickMoveStep> SubtickMoveStep;
        std::string* strMoveCrc;
        CInButtonStatePB* pInButtonState;
        CMsgQAngle* pViewAngles;
        int nLegacyCommandNumber;
        int nClientTick;
        float flForwardMove;
        float flSideMove;
        float flUpMove;
        int nImpulse;
        int nWeaponSelect;
        int nRandomSeed;
        int nMousedX;
        int nMousedY;
        std::uint32_t nConsumedServerAngleChanges;
        int nCmdFlags;
        std::uint32_t nPawnEntityHandle;
    };

    class CCSGOUserCmdPB : public CBasePB {
    public:
        CRepeatedPtrField<CCSGOInputHistoryEntryPB> InputHistoryEntryPB;
        CBaseUserCmdPB* pBaseUserCmdPB;
        void* unk;
        int nAttack1StartHistoryIndex;
        int nAttack2StartHistoryIndex;
        int nAttack3StartHistoryIndex;

        //bool bLeftHandDesired;
        //bool bIsPredictingBodyShotFX;
        //bool bIsPredictingHeadShotFX;
        //bool bIsPredictingKillRagdolls;

        void CheckAndSetBits(std::uint32_t nBits) {
            if (!(nHasBits & nBits))
                nHasBits |= nBits;
        }
    };


    class CCSGOUserCmd : public CUserCmdBaseHost<CCSGOUserCmdPB> {
    public:
    };
    class CInButtonState {
    public:
        void* vTable;
        std::uint64_t nButtonHeld;
        std::uint64_t nButtonChanged;
        std::uint64_t nButtonScroll;
    };





    uintptr_t PatternScan(const char* moduleName, const char* pattern) {
        HMODULE hModule = GetModuleHandleA(moduleName);
        if (!hModule) return 0;

        auto dos = reinterpret_cast<PIMAGE_DOS_HEADER>(hModule);
        auto nt = reinterpret_cast<PIMAGE_NT_HEADERS>((uintptr_t)hModule + dos->e_lfanew);
        auto size = nt->OptionalHeader.SizeOfImage;
        uint8_t* base = reinterpret_cast<uint8_t*>(hModule);

        std::vector<int> pat;
        const char* cur = pattern;
        while (*cur) {
            if (*cur == ' ') { cur++; continue; }
            if (*cur == '?') {
                pat.push_back(-1);
                if (*(cur + 1) == '?') cur++;
                cur++;
            }
            else {
                unsigned int byte = 0;
                sscanf_s(cur, "%2x", &byte);
                pat.push_back((int)byte);
                cur += 2;
            }
        }
        size_t s = pat.size();
        for (size_t i = 0; i + s < (size_t)size; ++i) {
            bool ok = true;
            for (size_t j = 0; j < s; ++j) {
                if (pat[j] != -1 && pat[j] != base[i + j]) { ok = false; break; }
            }
            if (ok) return reinterpret_cast<uintptr_t>(base + i);
        }
        return 0;
    }




















    constexpr int CMD_MAX = 150;
    size_t g_cmd_slot_offset_guess = 0x170;


    // ---------------- Helpers ----------------

    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 | PAGE_GUARD));
    }

    static uintptr_t GetVTable(void* obj, int index) {
        if (!obj) return 0;
        uintptr_t* vtable = *reinterpret_cast<uintptr_t**>(obj);
        if (!vtable) return 0;
        return vtable[index];
    }




    class CUserCmd : public CCSGOUserCmd {
    public:
        //virtual ~CUserCmd() = 0;

        CInButtonState InButtonState;
        int nUnknown;
        double dbAbsoluteTime;
        bool bHasBeenPredicted;
        int nUnknown1;
        int nUnknown2;
    };
    size_t g_cmd_size_guess = sizeof(CUserCmd);
    class CUserCmdArray {
    public:
        CUserCmd arrUserCmd[150];
        std::uint32_t nSequenceNumber;
        double dbAbsoluteTime;

        CUserCmd* GetCurrentUserCmd() {
            return &arrUserCmd[nSequenceNumber % 150U];
        }
    };

    CUserCmd* GetUserCmd() {
        static uintptr_t pattern = PatternScan("client.dll", "48 8B 0D ? ? ? ? E8 ? ? ? ? 49 8B CC");
        CUserCmdArray* pUserCmdArray = CPointer(pattern).rel()[2];
        if (pUserCmdArray == nullptr)
            return nullptr;

        return pUserCmdArray->GetCurrentUserCmd();
    }

    enum EButtonStatePBBits : uint32_t
    {
        BUTTON_STATE_PB_BITS_BUTTONSTATE1 = 0x1U,
        BUTTON_STATE_PB_BITS_BUTTONSTATE2 = 0x2U,
        BUTTON_STATE_PB_BITS_BUTTONSTATE3 = 0x4U
    };

    enum EFlags : int
    {
        FL_ONGROUND = (1 << 0), // entity is at rest / on the ground
        FL_DUCKING = (1 << 1), // player is fully crouched/uncrouched
        FL_ANIMDUCKING = (1 << 2), // player is in the process of crouching or uncrouching but could be in transition
        FL_WATERJUMP = (1 << 3), // player is jumping out of water
        FL_ONTRAIN = (1 << 4), // player is controlling a train, so movement commands should be ignored on client during prediction
        FL_INRAIN = (1 << 5), // entity is standing in rain
        FL_FROZEN = (1 << 6), // player is frozen for 3rd-person camera
        FL_ATCONTROLS = (1 << 7), // player can't move, but keeps key inputs for controlling another entity
        FL_CLIENT = (1 << 8), // entity is a client (player)
        FL_FAKECLIENT = (1 << 9), // entity is a fake client, simulated server side; don't send network messages to them
        FL_INWATER = (1 << 10), // entity is in water
        FL_FLY = (1 << 11),
        FL_SWIM = (1 << 12),
        FL_CONVEYOR = (1 << 13),
        FL_NPC = (1 << 14),
        FL_GODMODE = (1 << 15),
        FL_NOTARGET = (1 << 16),
        FL_AIMTARGET = (1 << 17),
        FL_PARTIALGROUND = (1 << 18), // entity is standing on a place where not all corners are valid
        FL_STATICPROP = (1 << 19), // entity is a static property
        FL_GRAPHED = (1 << 20),
        FL_GRENADE = (1 << 21),
        FL_STEPMOVEMENT = (1 << 22),
        FL_DONTTOUCH = (1 << 23),
        FL_BASEVELOCITY = (1 << 24), // entity have applied base velocity this frame
        FL_WORLDBRUSH = (1 << 25), // entity is not moveable/removeable brush (part of the world, but represented as an entity for transparency or something)
        FL_OBJECT = (1 << 26),
        FL_KILLME = (1 << 27), // entity is marked for death and will be freed by the game
        FL_ONFIRE = (1 << 28),
        FL_DISSOLVING = (1 << 29),
        FL_TRANSRAGDOLL = (1 << 30), // entity is turning into client-side ragdoll
        FL_UNBLOCKABLE_BY_PLAYER = (1 << 31)
    };

    enum ECommandButtons : std::uint64_t
    {
        IN_ATTACK = (1 << 0),
        IN_JUMP = (1 << 1),
        IN_DUCK = (1 << 2),
        IN_FORWARD = (1 << 3),
        IN_BACK = (1 << 4),
        IN_USE = (1 << 5),
        IN_CANCEL = (1 << 6),
        IN_LEFT = (1 << 7),
        IN_RIGHT = (1 << 8),
        IN_MOVELEFT = (1 << 9),
        IN_MOVERIGHT = (1 << 10),
        IN_SECOND_ATTACK = (1 << 11),
        IN_RUN = (1 << 12),
        IN_RELOAD = (1 << 13),
        IN_LEFT_ALT = (1 << 14),
        IN_RIGHT_ALT = (1 << 15),
        IN_SCORE = (1 << 16),
        IN_SPEED = (1 << 17),
        IN_WALK = (1 << 18),
        IN_ZOOM = (1 << 19),
        IN_FIRST_WEAPON = (1 << 20),
        IN_SECOND_WEAPON = (1 << 21),
        IN_BULLRUSH = (1 << 22),
        IN_FIRST_GRENADE = (1 << 23),
        IN_SECOND_GRENADE = (1 << 24),
        IN_MIDDLE_ATTACK = (1 << 25),
        IN_USE_OR_RELOAD = (1 << 26)
    };

    // ---------------- Diagnostic CreateMove Hook ----------------
    /*
    class CCSGOInput {
    public:
        template <typename T>
        void SetViewAngle(T& angView) {
            using SetViewAngles_t = std::int64_t(CS_FASTCALL*)(void*, std::int32_t, T&);
            static auto fnSetViewAngles = reinterpret_cast<SetViewAngles_t>(PatternScan("client.dll",("85 D2 75 ? 48 63 81")));

            fnSetViewAngles(this, 0, std::ref(angView));
        }

        QAngle_t GetViewAngles() {
            using GetViewAngles_t = void* (__fastcall*)(CCSGOInput*, int);
            static auto fnGetViewAngles = reinterpret_cast<GetViewAngles_t>(PatternScan("client.dll", ("4C 8B C1 85 D2 74 08 48 8D 05 ? ? ? ? C3")));

            return *reinterpret_cast<QAngle_t*>(fnGetViewAngles(this, 0));
        }
    };
    void AllowCameraAngleChange(CCSGOInput* pCSGOInput, int a2) {
        QAngle_t angOriginalAngle = pCSGOInput->GetViewAngles();

        hkAllowCameraChange.GetOriginal()(pCSGOInput, a2);
        pCSGOInput->SetViewAngle(angOriginalAngle);
    }*/
    bool __fastcall CreateMove_Hook(void* pCSGOInput, int nSlot, CUserCmd* pUserCmd) {
        if (!pUserCmd || !pUserCmd->pBaseUserCmdPB || !pUserCmd->pBaseUserCmdPB->pInButtonState)
            return g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

        bool ret = g_originalCreateMove(pCSGOInput, nSlot, pUserCmd);

        auto* base = pUserCmd->pBaseUserCmdPB;
        auto* buttons = base->pInButtonState;
        auto* pButtons = &pUserCmd->InButtonState;


        auto& subtick = base->SubtickMoveStep;
        subtick.nCurrentSize = 0; 


        if (GetAsyncKeyState('I') & 0x8000) {
            base->flForwardMove = 450.0f;
            base->flSideMove = 0.0f;
            buttons->nButtonHeld &= ~IN_FORWARD;
            buttons->nButtonChanged &= ~IN_FORWARD;
            base->nImpulse = 1;
        }


        if (GetAsyncKeyState('H') & 0x8000) {
            buttons->nButtonHeld |= IN_BACK;
            buttons->nButtonChanged |= IN_BACK;
        }

        // метовые АА без хука на кам
        if (base->pViewAngles) {
            QAngle_t fakeAngles = base->pViewAngles->angValue;
            if (GetAsyncKeyState('K') & 0x8000) {
                fakeAngles.pitch = ((float)rand() / RAND_MAX) * 178.0f - 89.0f;
                fakeAngles.yaw = ((float)rand() / RAND_MAX) * 360.0f - 180.0f;
            }
            base->pViewAngles->angValue = fakeAngles;
        }

        return ret;
    }


    // команд индекс1
    using RunCommand1Fn = void(__fastcall*)(void* pMovementServices, CUserCmd* pUserCmd);
    static RunCommand1Fn g_originalRunCommand1 = nullptr;

    void __fastcall RunCommand1_Hook(void* pMovementServices, CUserCmd* pUserCmd) {
        if (!pUserCmd || !pUserCmd->pBaseUserCmdPB || !pUserCmd->pBaseUserCmdPB->pViewAngles || !pUserCmd->pBaseUserCmdPB->pInButtonState)
        {
            if (g_originalRunCommand1)
                g_originalRunCommand1(pMovementServices, pUserCmd);
            return;
        }

        auto* pBase = pUserCmd->pBaseUserCmdPB;
        auto* pViewAngles = pBase->pViewAngles;
        auto* pButtons = pBase->pInButtonState;

        static QAngle_t originalAngles = pViewAngles->angValue;

        if (GetAsyncKeyState('H') & 0x8000) {
            pButtons->nButtonHeld |= ECommandButtons::IN_FORWARD;
            pButtons->nButtonChanged |= ECommandButtons::IN_FORWARD;
        }
        // хук на камеру
        QAngle_t fakeAngles = pViewAngles->angValue;
        if (GetAsyncKeyState('K') & 0x8000) {
            fakeAngles.pitch = (static_cast<float>(rand()) / RAND_MAX) * 178.0f - 89.0f;
            fakeAngles.yaw = (static_cast<float>(rand()) / RAND_MAX) * 360.0f - 180.0f;
        }
        pViewAngles->angValue = fakeAngles;

        if (pBase->SubtickMoveStep.IsValid(0)) {
            auto* stepPtr = pBase->SubtickMoveStep[0];
            if (stepPtr) {
                stepPtr->flAnalogForwardDelta = (GetAsyncKeyState('H') & 0x8000) ? 1.0f : 0.0f;
                stepPtr->nButton |= (GetAsyncKeyState('H') & 0x8000) ? ECommandButtons::IN_FORWARD : 0;
                stepPtr->bIsPressed = (GetAsyncKeyState('H') & 0x8000) != 0;
            }
        }

        if (pViewAngles)
            pViewAngles->angValue = originalAngles;

        if (g_originalRunCommand1)
            g_originalRunCommand1(pMovementServices, pUserCmd);
    }


    // ---------------- Console ----------------

    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 << "[hook] Debug console attached!" << std::endl;
    }

    // ---------------- Hook Initialization ----------------

    static void InitializeHook() {
        if (MH_Initialize() != MH_OK) return;

        HMODULE client = GetModuleHandleA("client.dll");
        for (int i = 0; i < 50 && !client; ++i) { Sleep(100); client = GetModuleHandleA("client.dll"); }
        if (!client) { MH_Uninitialize(); return; }

        uintptr_t ptrRunCommand1 = PatternScan("client.dll",
            "48 8B C4 48 81 EC ? ? ? ? 48 89 58 ? 48 89 68 ? 48 8B EA 48 89 70 ? 48 8B F1");
        /*
        if (ptrRunCommand1) {
            if (MH_CreateHook(reinterpret_cast<LPVOID>(ptrRunCommand1),
                reinterpret_cast<LPVOID>(&RunCommand1_Hook),
                reinterpret_cast<LPVOID*>(&g_originalRunCommand1)) == MH_OK) {
                MH_EnableHook(reinterpret_cast<LPVOID>(ptrRunCommand1));
                std::cout << "[hook] RunCommand1 hooked at 0x" << std::hex << ptrRunCommand1 << std::dec << std::endl;
            }
            else {
                std::cout << "[hook] Failed to hook RunCommand1\n";
            }
        }
        else {
            std::cout << "[hook] RunCommand1 pattern not found!\n";
        }
        */
        uintptr_t ptrToinput = PatternScan("client.dll", "48 8B C4 4C 89 40 ? 48 89 48 ? 55 53 41 57");
        if (MH_CreateHook(reinterpret_cast<LPVOID>(ptrToinput),
            reinterpret_cast<LPVOID>(&CreateMove_Hook),
            reinterpret_cast<LPVOID*>(&g_originalCreateMove)) == MH_OK)
        {
            MH_EnableHook(reinterpret_cast<LPVOID>(ptrToinput));
            std::cout << "[hook] CreateMove hooked at 0x" << std::hex << ptrToinput << std::dec << std::endl;
        }
        else {
            std::cout << "porno\n";
        }
    }

    static void UnloadDLL() {
        std::cout << "[hook] Unloading DLL..." << std::endl;

        // Отключаем все хуки
        MH_DisableHook(MH_ALL_HOOKS);
        MH_Uninitialize();

        // Закрываем консоль
        if (g_consoleAttached.load()) {
            fclose(stdout);
            fclose(stdin);
            fclose(stderr);
            FreeConsole();
            g_consoleAttached.store(false);
        }

        // Выгружаем саму DLL
        HMODULE hModule = nullptr;
        if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
            reinterpret_cast<LPCSTR>(&UnloadDLL), &hModule)) {
            std::cout << "[hook] FreeLibraryAndExitThread..." << std::endl;
            HANDLE hThread = CreateThread(nullptr, 0, [](LPVOID param) -> DWORD {
                FreeLibraryAndExitThread(static_cast<HMODULE>(param), 0);
                return 0;
                }, hModule, 0, nullptr);

            if (hThread) CloseHandle(hThread);
        }
    }

    // ---------------- DLL Main Thread ----------------

    static DWORD WINAPI InitThread(LPVOID module) {
        AttachDebugConsole();
        InitializeHook();

        int counter = 0;
        while (true) {
            Sleep(1000);
            ++counter;
            if (GetAsyncKeyState(VK_F3) & 0x8000) { // F3 для анхука
                UnloadDLL();
                break;
            }
        }
        return 0;
    }

} // namespace test_input

// ---------------- DLL Main ----------------

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID) {
    using namespace test_input;
    if (reason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hModule);
        HANDLE h = CreateThread(nullptr, 0, InitThread, hModule, 0, nullptr);
        if (h) CloseHandle(h);
    }
    else if (reason == DLL_PROCESS_DETACH) {
        MH_DisableHook(MH_ALL_HOOKS);
        MH_Uninitialize();
    }
    return TRUE;
}
 
Назад
Сверху Снизу