Начинающий
Начинающий
- Статус
- Оффлайн
- Регистрация
- 19 Мар 2021
- Сообщения
- 5
- Реакции
- 0
Кароче, пытаюсь сделать так чтобы он ходил но либо меня блочит, либо происходит так что когда я смотрю вниз дает идти, кароче бред.
Нужно чтобы шло вперед и все, я хз что не так делаю, а я делаю что то не так я в этом уверен. Вообщем помогите плис..
Я так же пробовал так:
Но ничего не получилось.
Нужно чтобы шло вперед и все, я хз что не так делаю, а я делаю что то не так я в этом уверен. Вообщем помогите плис..
CreateMove:
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;
}
Я так же пробовал так:
второй вариант:
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;
}
Но ничего не получилось.
полный код:
// 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;
}