From fb67632502e8e55fefdfbaaff124df145e6ce131 Mon Sep 17 00:00:00 2001 From: Huoji's <1296564236@qq.com> Date: Sun, 1 Oct 2023 04:57:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0OnClientConnected=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csgo2/VTHook.cpp | 37 +++++++++++++ csgo2/VTHook.h | 100 ------------------------------------ csgo2/csgo2.vcxproj | 4 +- csgo2/csgo2.vcxproj.filters | 4 +- csgo2/events.cpp | 4 +- csgo2/hooks.cpp | 18 ++++--- csgo2/hooks.h | 4 +- csgo2/offset.cpp | 4 +- csgo2/pch.h | 3 +- csgo2/sdk/convar/convar.hpp | 1 + csgo2/sdk/public/eiface.h | 2 +- csgo2/vmt.cpp | 1 - csgo2/vmthook.h | 21 ++++++++ 13 files changed, 85 insertions(+), 118 deletions(-) create mode 100644 csgo2/VTHook.cpp delete mode 100644 csgo2/VTHook.h delete mode 100644 csgo2/vmt.cpp create mode 100644 csgo2/vmthook.h diff --git a/csgo2/VTHook.cpp b/csgo2/VTHook.cpp new file mode 100644 index 0000000..647df35 --- /dev/null +++ b/csgo2/VTHook.cpp @@ -0,0 +1,37 @@ +#include "vmthook.h" + +VMTHook::VMTHook(void* vmt_addy) +{ + vmt = (void**)vmt_addy; + LOG("vmt: %p \n", vmt); +} + +void* VMTHook::Hook(int index, void* hk) +{ + // Store the index and original function address + hooked_funcs.insert(std::make_pair(index, vmt[index])); + LOG("%s vmt[index]: %p \n", __FUNCTION__ ,vmt[index]); + + // Change the memory's access rights, patch the address to our hook, restore original rights + DWORD old; + VirtualProtect(&vmt[index], sizeof(void*), PAGE_EXECUTE_READWRITE, &old); + vmt[index] = hk; + VirtualProtect(&vmt[index], sizeof(void*), old, NULL); + + return hooked_funcs[index]; +} + +void VMTHook::ClearHooks() +{ + for (func_iterator = hooked_funcs.begin(); func_iterator != hooked_funcs.end(); func_iterator++) + { + DWORD old; + VirtualProtect(&vmt[func_iterator->first], sizeof(void*), PAGE_EXECUTE_READWRITE, &old); + vmt[func_iterator->first] = func_iterator->second; + VirtualProtect(&vmt[func_iterator->first], sizeof(void*), old, NULL); + } + hooked_funcs.clear(); + vmt = nullptr; +} + +VMTHook::~VMTHook() {} \ No newline at end of file diff --git a/csgo2/VTHook.h b/csgo2/VTHook.h deleted file mode 100644 index 1d730d6..0000000 --- a/csgo2/VTHook.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once -#include "pch.h" -class VTHook -{ -public: - VTHook() - { - memset( this, 0, sizeof( VTHook) ); - } - - VTHook( PDWORD64* ppdwClassBase ) - { - bInitialize( ppdwClassBase ); - } - - ~VTHook() - { - UnHook(); - } - void ClearClassBase() - { - m_ClassBase = NULL; - } - bool bInitialize( PDWORD64* ppdwClassBase ) - { - m_ClassBase = ppdwClassBase; - m_OldVT = *ppdwClassBase; - m_VTSize = GetVTCount( *ppdwClassBase ); - m_NewVT = new DWORD64[ m_VTSize ]; - memcpy( m_NewVT, m_OldVT, sizeof( DWORD64) * m_VTSize ); - *ppdwClassBase = m_NewVT; - return true; - } - - bool bInitialize( PDWORD64** pppdwClassBase ) // fix for pp - { - return bInitialize( *pppdwClassBase ); - } - - void UnHook() - { - if( m_ClassBase ) - { - *m_ClassBase = m_OldVT; - } - } - - void ReHook() - { - if( m_ClassBase ) - { - *m_ClassBase = m_NewVT; - } - } - - int iGetFuncCount() - { - return ( int )m_VTSize; - } - - DWORD64 GetFuncAddress( int Index ) - { - if( Index >= 0 && Index <= ( int )m_VTSize && m_OldVT != NULL ) - { - return m_OldVT[ Index ]; - } - return NULL; - } - - PDWORD64 GetOldVT() - { - return m_OldVT; - } - - DWORD64 HookFunction( DWORD64 dwNewFunc, unsigned int iIndex ) - { - if( m_NewVT && m_OldVT && iIndex <= m_VTSize && iIndex >= 0 ) - { - m_NewVT[ iIndex ] = dwNewFunc; - return m_OldVT[ iIndex ]; - } - - return NULL; - } - -private: - DWORD64 GetVTCount( PDWORD64 pdwVMT ) - { - DWORD64 dwIndex = 0; - - while (IsBadCodePtr((FARPROC)pdwVMT[dwIndex]) == false) { - dwIndex++; - } - return dwIndex; - } - - PDWORD64* m_ClassBase; - PDWORD64 m_NewVT, m_OldVT; - DWORD64 m_VTSize; -}; diff --git a/csgo2/csgo2.vcxproj b/csgo2/csgo2.vcxproj index b4e82e3..c3a7bc7 100644 --- a/csgo2/csgo2.vcxproj +++ b/csgo2/csgo2.vcxproj @@ -195,7 +195,7 @@ - + @@ -223,7 +223,7 @@ - + diff --git a/csgo2/csgo2.vcxproj.filters b/csgo2/csgo2.vcxproj.filters index 8589b31..5d181cf 100644 --- a/csgo2/csgo2.vcxproj.filters +++ b/csgo2/csgo2.vcxproj.filters @@ -174,7 +174,7 @@ 头文件\native_sdk\entity - + 头文件\memory @@ -254,7 +254,7 @@ 源文件\native_sdk\interfaces - + 源文件\memory diff --git a/csgo2/events.cpp b/csgo2/events.cpp index 1feab7b..2ce21b4 100644 --- a/csgo2/events.cpp +++ b/csgo2/events.cpp @@ -9,9 +9,11 @@ namespace events { const auto victim = reinterpret_cast(event->GetPlayerPawn(&userIdNameParams)); const auto attacker = reinterpret_cast(event->GetPlayerPawn(&attackerNameParams)); auto victimName = &victim->m_iszPlayerName(); + auto attackerName = &attacker->m_iszPlayerName(); + //victimBasePlayer->ForceRespawn(); printf("victim %s\n", victimName); - printf("attacker %s\n", attacker->m_iszPlayerName()); + printf("attacker %s\n", attackerName); } auto OnPlayerChat(IGameEvent* event) -> void diff --git a/csgo2/hooks.cpp b/csgo2/hooks.cpp index 84ea8f5..1f6a72d 100644 --- a/csgo2/hooks.cpp +++ b/csgo2/hooks.cpp @@ -6,11 +6,12 @@ OnClientConnect_t original_OnClientConnected = NULL; Host_Say_t original_Host_Say = NULL; namespace hooks { - VTHook* HIServerGameClient; - bool __fastcall hook_OnClientConnected(CPlayerSlot slot, const char* pszName, uint64_t xuid, const char* pszNetworkID, bool unk1, CBufferString* pRejectReason) + // "player_connect" + VMTHook* VMT_IServerGameClient; + void __fastcall hook_OnClientConnected(void* rcx, CPlayerSlot slot, const char* pszName, uint64_t xuid, const char* pszNetworkID, const char* pszAddress, bool bFakePlayer) { - LOG("Hook_OnClientConnected(%d, \"%s\", %d, \"%s\")\n", slot, pszName, xuid, pszNetworkID); - return original_OnClientConnected(slot, pszName, xuid, pszNetworkID, unk1, pRejectReason); + LOG("OnClientConnected(%d, \"%s\", %d, \"%s\", \"%s\" \"%d\")\n", slot.Get(), pszName, xuid, pszNetworkID, pszAddress, bFakePlayer); + return original_OnClientConnected(rcx, slot, pszName, xuid, pszNetworkID, pszAddress, bFakePlayer); } void __fastcall hook_Host_Say(void* pEntity, void* args, bool teamonly, int unk1, const char* unk2) { @@ -101,9 +102,10 @@ namespace hooks { } auto initVmtHook() -> bool { + VMT_IServerGameClient = new VMTHook(Memory::read(reinterpret_cast(Offset::InterFaces::IServerGameClient))); + original_OnClientConnected = reinterpret_cast(VMT_IServerGameClient->Hook(11, hook_OnClientConnected)); - HIServerGameClient = new VTHook((DWORD64**)Offset::InterFaces::IServerGameClient); - original_OnClientConnected = (OnClientConnect_t)HIServerGameClient->HookFunction((DWORD64)hook_OnClientConnected, 1); + LOG("%s original_OnClientConnected: %p \n", __FUNCTION__, original_OnClientConnected); return original_OnClientConnected != nullptr; } auto init() -> bool { @@ -113,6 +115,10 @@ namespace hooks { } auto unload() -> void { + VMT_IServerGameClient->ClearHooks(); + + delete VMT_IServerGameClient; + MH_DisableHook(MH_ALL_HOOKS); MH_RemoveHook(MH_ALL_HOOKS); MH_Uninitialize(); diff --git a/csgo2/hooks.h b/csgo2/hooks.h index 6658ef3..ebfec43 100644 --- a/csgo2/hooks.h +++ b/csgo2/hooks.h @@ -1,11 +1,11 @@ #pragma once #include "pch.h" #include "sdk/gameevent/IGameEvent.h" - +#include "sdk/tier1/bufferstring.h" typedef bool(__fastcall* FireEventServerSide_t)(CGameEventManager*, IGameEvent*, bool); typedef void(__fastcall* Host_Say_t)(void*, void*, bool, int, const char*); -typedef bool(__fastcall* OnClientConnect_t)(CPlayerSlot, const char*, uint64_t, const char*, bool unk1, CBufferString*); +typedef void(__fastcall* OnClientConnect_t)(void*, CPlayerSlot, const char*, uint64_t, const char*, const char*, bool); extern FireEventServerSide_t original_FireEventServerSide; extern Host_Say_t original_Host_Say; diff --git a/csgo2/offset.cpp b/csgo2/offset.cpp index 9c371f9..3334d8e 100644 --- a/csgo2/offset.cpp +++ b/csgo2/offset.cpp @@ -30,10 +30,10 @@ auto Init() -> bool { InterFaces::SchemaSystem = reinterpret_cast(schemasystem.FindInterface("SchemaSystem_001").Get()); // engine.dll InterFaces::GameEventManager = reinterpret_cast(engine.FindInterface("GameEventSystemServerV001").Get()); - InterFaces::GameResourceServiceServer = reinterpret_cast(engine.FindInterface("Source2GameClients001").Get()); + InterFaces::GameResourceServiceServer = reinterpret_cast(engine.FindInterface("GameResourceServiceServerV001").Get()); // server.dll - InterFaces::IServerGameClient = reinterpret_cast(server.FindInterface("GameResourceServiceServerV001").Get()); + InterFaces::IServerGameClient = reinterpret_cast(server.FindInterface("Source2GameClients001").Get()); // only init in console server InterFaces::CGameEventManger = reinterpret_cast(CGameEventManagerPtr); diff --git a/csgo2/pch.h b/csgo2/pch.h index a39204a..03933b3 100644 --- a/csgo2/pch.h +++ b/csgo2/pch.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "framework.h" #include "stb.hh" @@ -31,4 +32,4 @@ extern void DebugPrintA(const char* format, ...); #include "offset.h" #include "events.h" #include "hooks.h" -#include "VTHook.h" \ No newline at end of file +#include "vmthook.h" diff --git a/csgo2/sdk/convar/convar.hpp b/csgo2/sdk/convar/convar.hpp index 4ee0400..d12a36b 100644 --- a/csgo2/sdk/convar/convar.hpp +++ b/csgo2/sdk/convar/convar.hpp @@ -1,3 +1,4 @@ +#pragma once #include "../sdk.h" #include "../tier1/UtlVector.hpp" struct characterset_t diff --git a/csgo2/sdk/public/eiface.h b/csgo2/sdk/public/eiface.h index c41f18e..877ac91 100644 --- a/csgo2/sdk/public/eiface.h +++ b/csgo2/sdk/public/eiface.h @@ -7,7 +7,7 @@ struct vis_info_t; class IHLTVServer; class IHLTVDirector; class CSteamID; - +class CCommand; struct CEntityIndex { CEntityIndex(int index) diff --git a/csgo2/vmt.cpp b/csgo2/vmt.cpp deleted file mode 100644 index 8e77a09..0000000 --- a/csgo2/vmt.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "vmt.h" diff --git a/csgo2/vmthook.h b/csgo2/vmthook.h new file mode 100644 index 0000000..7d90a65 --- /dev/null +++ b/csgo2/vmthook.h @@ -0,0 +1,21 @@ +#pragma once +//form https://www.unknowncheats.me/forum/c-and-c-/188449-vmt-hooking-class.html + +#include "pch.h" + +class VMTHook +{ +public: + + void** vmt = nullptr; // Pointer to the VMT, we're using it more as an array of void* + + VMTHook(void* vmt); // Hook original VMT by it's address + VMTHook(DWORD64* vmt_ptr); // Create Shadow VMT from VMT pointer ( Not implemented here ) + ~VMTHook(); // Destructor, removes all hooks + + void* Hook(int index, void* hk); + void ClearHooks(); +private: + std::map::iterator func_iterator; // Iterator so we can iterate the map below + std::map hooked_funcs; // std::map which holds the index hooked and the original function's address +};