From d75a2da2b857775c2a9b1ed20fbb09a049719859 Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Wed, 3 May 2017 17:35:50 +0300 Subject: [PATCH] some questionable shit and spam safety --- src/hack.cpp | 12 ++++++++++++ src/hacks/Spam.cpp | 15 ++++++++++++++- src/hooks.cpp | 2 ++ src/hooks.h | 5 +++++ src/hooks/hookedmethods.h | 6 ++++++ src/hooks/others.cpp | 2 +- src/interfaces.cpp | 2 ++ src/interfaces.h | 2 ++ src/netmessage.cpp | 35 +++++++++++++++++++++++++++++++++++ src/netmessage.h | 38 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 117 insertions(+), 2 deletions(-) diff --git a/src/hack.cpp b/src/hack.cpp index 64336ae5..46685ebd 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -171,6 +171,16 @@ void hack::Initialize() { hooks::hkIVModelRender->Init(g_IVModelRender, 0); hooks::hkIVModelRender->HookMethod((void*)DrawModelExecute_hook, hooks::offDrawModelExecute); hooks::hkIVModelRender->Apply(); + // Sadly, it doesn't work as expected :( + /*hooks::hkBaseClientState = new hooks::VMTHook(); + hooks::hkBaseClientState->Init((void*)g_IBaseClientState, 0); + hooks::hkBaseClientState->HookMethod((void*)GetClientName_hook, hooks::offGetClientName); + hooks::hkBaseClientState->Apply();*/ + //hooks::hkBaseClientState8 = new hooks::VMTHook(); + //hooks::hkBaseClientState8->Init((void*)g_IBaseClientState, 8); + //hooks::hkBaseClientState8->HookMethod((void*)ProcessSetConVar_hook, hooks::offProcessSetConVar); + //hooks::hkBaseClientState8->HookMethod((void*)ProcessGetCvarValue_hook, hooks::offProcessGetCvarValue); + //hooks::hkBaseClientState8->Apply(); if (TF2) g_GlowObjectManager = *reinterpret_cast(gSignatures.GetClientSignature("C1 E0 05 03 05") + 5); InitStrings(); hacks::shared::killsay::Init(); @@ -210,6 +220,8 @@ void hack::Shutdown() { if (hooks::hkStudioRender) hooks::hkStudioRender->Kill(); if (hooks::hkInput) hooks::hkInput->Kill(); if (hooks::hkIVModelRender) hooks::hkIVModelRender->Kill(); + if (hooks::hkBaseClientState) hooks::hkBaseClientState->Kill(); + if (hooks::hkBaseClientState8) hooks::hkBaseClientState8->Kill(); //if (hooks::hkCTFPlayer) hooks::hkCTFPlayer->Kill(); logging::Info("Unregistering convars.."); ConVar_Unregister(); diff --git a/src/hacks/Spam.cpp b/src/hacks/Spam.cpp index 8ec644e6..defc8fad 100644 --- a/src/hacks/Spam.cpp +++ b/src/hacks/Spam.cpp @@ -23,6 +23,18 @@ TextFile file {}; void CreateMove() { if (!spam_source) return; + static int safety_ticks = 0; + static int last_spam = 0; + if ((int)spam_source != last_spam) { + safety_ticks = 300; + last_spam = (int)spam_source; + } + if (safety_ticks > 0) { + safety_ticks--; + return; + } else { + safety_ticks = 0; + } if (last_spam > g_GlobalVars->curtime) last_spam = 0.0f; const std::vector* source = nullptr; switch ((int)spam_source) { @@ -68,7 +80,8 @@ const std::vector builtin_default = { "cathook - more fun than a ball of yarn!", "GNU/Linux is the best OS!", "get cathook: discord.gg/7bu3AFw", - "cathook - free tf2 cheat!" + "cathook - free tf2 cheat!", + "cathook - ca(n)t stop me meow!" }; const std::vector builtin_lennyfaces = { "( ͡° ͜ʖ ͡°)", "( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°)", "ʕ•ᴥ•ʔ", diff --git a/src/hooks.cpp b/src/hooks.cpp index 142cae49..e1011122 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -74,6 +74,8 @@ void hooks::VMTHook::Apply() { //hooks::VMTHook* hooks::hkCTFPlayer = nullptr; hooks::VMTHook* hooks::hkInput = nullptr; +hooks::VMTHook* hooks::hkBaseClientState = nullptr; +hooks::VMTHook* hooks::hkBaseClientState8 = nullptr; hooks::VMTHook* hooks::hkClientMode = 0; hooks::VMTHook* hooks::hkPanel = 0; hooks::VMTHook* hooks::hkClient = 0; diff --git a/src/hooks.h b/src/hooks.h index 3f4a8a89..c5f3257e 100644 --- a/src/hooks.h +++ b/src/hooks.h @@ -41,10 +41,15 @@ extern VMTHook* hkMatSurface; extern VMTHook* hkStudioRender; extern VMTHook* hkInput; extern VMTHook* hkIVModelRender; +extern VMTHook* hkBaseClientState; +extern VMTHook* hkBaseClientState8; constexpr unsigned int offGetUserCmd = 8; constexpr unsigned int offShouldDraw = 136; constexpr unsigned int offDrawModelExecute = 19; +constexpr unsigned int offGetClientName = 44; +constexpr unsigned int offProcessSetConVar = 4; +constexpr unsigned int offProcessGetCvarValue = 29; extern unsigned int offHandleInputEvent; extern unsigned int offPaintTraverse; extern unsigned int offCreateMove; diff --git a/src/hooks/hookedmethods.h b/src/hooks/hookedmethods.h index 9a43891a..9838cf9a 100644 --- a/src/hooks/hookedmethods.h +++ b/src/hooks/hookedmethods.h @@ -25,6 +25,12 @@ typedef void(BeginFrame_t)(IStudioRender*); typedef bool(*CanInspect_t)(IClientEntity*); typedef void(*DrawModelExecute_t)(IVModelRender*, const DrawModelState_t&, const ModelRenderInfo_t&, matrix3x4_t*); typedef CUserCmd*(GetUserCmd_t)(IInput*, int); +typedef const char*(GetClientName_t)(CBaseClientState*); +typedef bool(ProcessSetConVar_t)(CBaseClientState*, NET_SetConVar*); +typedef bool(ProcessGetCvarValue_t)(CBaseClientState*, SVC_GetCvarValue*); +const char* GetClientName_hook(CBaseClientState* _this); +bool ProcessSetConVar_hook(CBaseClientState* _this, NET_SetConVar* msg); +bool ProcessGetCvarValue_hook(CBaseClientState* _this, SVC_GetCvarValue* msg); //typedef void(*CInput__CreateMove_t)(void*, int, float, bool); //void CInput__CreateMove_hook(void*, int sequence_number, float input_sample_frametime, bool active); bool CanInspect_hook(IClientEntity*); diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index e15df73b..ca981d2d 100644 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -303,7 +303,7 @@ bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) { int j = 0; for (int i = 0; i < 3; i++) { while (char c = data[j++]) { - if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '?'; + if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '*'; } } buf = bf_read(data, s); diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 88133c18..57e2e666 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -47,6 +47,7 @@ IMaterialSystemFixed* g_IMaterialSystem = nullptr; IVRenderView* g_IVRenderView = nullptr; IMaterialSystem* g_IMaterialSystemHL = nullptr; IMoveHelperServer* g_IMoveHelperServer = nullptr; +CBaseClientState* g_IBaseClientState = nullptr; template T* BruteforceInterface(std::string name, sharedobj::SharedObject* object, int start) { @@ -111,6 +112,7 @@ void CreateInterfaces() { else if (TF2C) g_IInput = **(reinterpret_cast((uintptr_t)1 + gSignatures.GetClientSignature("A1 ? ? ? ? C6 05 ? ? ? ? 01 8B 10 89 04 24 FF 92 A8 00 00 00 A1 ? ? ? ? 8B 10"))); else if (HL2DM) g_IInput = **(reinterpret_cast((uintptr_t)1 + gSignatures.GetClientSignature("A1 ? ? ? ? 8B 10 89 04 24 FF 52 78 A1 ? ? ? ? 8B 10"))); g_ISteamUser = g_ISteamClient->GetISteamUser(su, sp, "SteamUser018"); + g_IBaseClientState = *(reinterpret_cast(gSignatures.GetEngineSignature("55 89 E5 83 EC 18 C7 44 24 04 01 00 00 00 C7 04 24 ? ? ? ? E8 ? ? ? ? C7 04 24 ? ? ? ? 89 44 24 04 E8 ? ? ? ? A1 ? ? ? ? 85 C0 74 15 A1 ? ? ? ? 8B 10 89 04 24 FF 52 38 C9 C3") + 17)); g_IAchievementMgr = g_IEngine->GetAchievementMgr(); g_ISteamUserStats = g_ISteamClient->GetISteamUserStats(su, sp, "STEAMUSERSTATS_INTERFACE_VERSION011"); } diff --git a/src/interfaces.h b/src/interfaces.h index d47544c9..b32a082c 100644 --- a/src/interfaces.h +++ b/src/interfaces.h @@ -48,6 +48,7 @@ class IVRenderView; class IMaterialSystemFixed; class IMaterialSystem; class IMoveHelperServer; +class CBaseClientState; extern ISteamClient* g_ISteamClient; extern ISteamFriends* g_ISteamFriends; @@ -75,6 +76,7 @@ extern IMaterialSystem* g_IMaterialSystemHL; extern IVModelRender* g_IVModelRender; extern IVRenderView* g_IVRenderView; extern IMoveHelperServer* g_IMoveHelperServer; +extern CBaseClientState* g_IBaseClientState; template T* BruteforceInterface(std::string name, sharedobj::SharedObject* object, int start = 0); diff --git a/src/netmessage.cpp b/src/netmessage.cpp index 3f791fdf..f1517572 100644 --- a/src/netmessage.cpp +++ b/src/netmessage.cpp @@ -7,6 +7,7 @@ #include "netmessage.h" #include "logging.h" +#include "common.h" bf_write::bf_write() { @@ -336,6 +337,40 @@ void bf_write::WriteLong(long val) WriteSBitLong(val, sizeof(long) << 3); } +bool CLC_RespondCvarValue::WriteToBuffer( bf_write &buffer ) +{ + buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS ); + + buffer.WriteSBitLong( m_iCookie, 32 ); + buffer.WriteSBitLong( m_eStatusCode, 4 ); + + buffer.WriteString( m_szCvarName ); + buffer.WriteString( m_szCvarValue ); + + return !buffer.IsOverflowed(); +} + +bool CLC_RespondCvarValue::ReadFromBuffer( bf_read &buffer ) +{ + m_iCookie = buffer.ReadSBitLong( 32 ); + m_eStatusCode = (EQueryCvarValueStatus)buffer.ReadSBitLong( 4 ); + + // Read the name. + buffer.ReadString( m_szCvarNameBuffer, sizeof( m_szCvarNameBuffer ) ); + m_szCvarName = m_szCvarNameBuffer; + + // Read the value. + buffer.ReadString( m_szCvarValueBuffer, sizeof( m_szCvarValueBuffer ) ); + m_szCvarValue = m_szCvarValueBuffer; + + return !buffer.IsOverflowed(); +} + +const char *CLC_RespondCvarValue::ToString(void) const +{ + return strfmt("%s: status: %d, value: %s, cookie: %d", GetName(), m_eStatusCode, m_szCvarValue, m_iCookie ); +} + bool NET_NOP::WriteToBuffer( bf_write &buffer ) { buffer.WriteUBitLong( GetType(), 6 ); diff --git a/src/netmessage.h b/src/netmessage.h index 8cb1d597..5974e373 100644 --- a/src/netmessage.h +++ b/src/netmessage.h @@ -137,6 +137,33 @@ protected: #define MAX_OSPATH 260 +#define NETMSG_TYPE_BITS 5 +typedef int QueryCvarCookie_t; +typedef enum +{ + eQueryCvarValueStatus_ValueIntact=0, // It got the value fine. + eQueryCvarValueStatus_CvarNotFound=1, + eQueryCvarValueStatus_NotACvar=2, // There's a ConCommand, but it's not a ConVar. + eQueryCvarValueStatus_CvarProtected=3 // The cvar was marked with FCVAR_SERVER_CAN_NOT_QUERY, so the server is not allowed to have its value. +} EQueryCvarValueStatus; + +class CLC_RespondCvarValue : public CNetMessage +{ +public: + DECLARE_CLC_MESSAGE( RespondCvarValue ); + + QueryCvarCookie_t m_iCookie; + + const char *m_szCvarName; + const char *m_szCvarValue; // The sender sets this, and it automatically points it at m_szCvarNameBuffer when receiving. + + EQueryCvarValueStatus m_eStatusCode; + +private: + char m_szCvarNameBuffer[256]; + char m_szCvarValueBuffer[256]; +}; + class NET_NOP : public CNetMessage { DECLARE_NET_MESSAGE( NOP ); @@ -158,6 +185,17 @@ public: int m_nSpawnCount; // server spawn count (session number) }; +class SVC_GetCvarValue : public CNetMessage +{ +public: + DECLARE_SVC_MESSAGE( GetCvarValue ); + + QueryCvarCookie_t m_iCookie; + const char *m_szCvarName; // The sender sets this, and it automatically points it at m_szCvarNameBuffer when receiving. + +private: + char m_szCvarNameBuffer[256]; +}; class NET_SetConVar : public CNetMessage {