From 59508b182baac67d812eb43b12fa3b9c1123e75b Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 06:48:09 +0300 Subject: [PATCH 01/10] Team chat uber spam --- src/chatstack.cpp | 18 +++++++++++++----- src/chatstack.h | 8 +++++++- src/gui/ncc/Menu.cpp | 1 + src/hacks/KillSay.cpp | 2 +- src/hacks/Spam.cpp | 2 +- src/hacks/UberSpam.cpp | 13 ++++++++----- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/chatstack.cpp b/src/chatstack.cpp index 689e3bac..b73bab20 100644 --- a/src/chatstack.cpp +++ b/src/chatstack.cpp @@ -11,15 +11,23 @@ namespace chat_stack { + +void Say(const std::string& message, bool team) { + stack.push({ message, team }); +} + void OnCreateMove() { if (last_say > g_GlobalVars->curtime) last_say = 0; if (g_GlobalVars->curtime - last_say <= CHATSTACK_INTERVAL) return; - std::string message; if (!stack.empty()) { - message = stack.top(); + const msg_t& msg = stack.top(); stack.pop(); - if (message.size()) { - g_IEngine->ServerCmd(format("say \"", message, '"').c_str()); + if (msg.text.size()) { + //logging::Info("Saying %s %i", msg.text.c_str(), msg.text.size()); + if (msg.team) + g_IEngine->ServerCmd(format("say_team \"", msg.text.c_str(), '"').c_str()); + else + g_IEngine->ServerCmd(format("say \"", msg.text.c_str(), '"').c_str()); last_say = g_GlobalVars->curtime; } } @@ -30,7 +38,7 @@ void Reset() { last_say = 0.0f; } -std::stack stack; +std::stack stack; float last_say = 0.0f; } diff --git a/src/chatstack.h b/src/chatstack.h index 10c68de4..4026a9fd 100644 --- a/src/chatstack.h +++ b/src/chatstack.h @@ -18,10 +18,16 @@ namespace chat_stack { +struct msg_t { + std::string text; + bool team; +}; + +void Say(const std::string& message, bool team = false); void OnCreateMove(); void Reset(); -extern std::stack stack; +extern std::stack stack; extern float last_say; }; diff --git a/src/gui/ncc/Menu.cpp b/src/gui/ncc/Menu.cpp index 7e45c31d..2d7017cf 100644 --- a/src/gui/ncc/Menu.cpp +++ b/src/gui/ncc/Menu.cpp @@ -536,6 +536,7 @@ static const std::string list_tf2 = R"( "uberspam_ready" "uberspam_used" "uberspam_ended" + "uberspam_team" ] "Follow Bot" [ diff --git a/src/hacks/KillSay.cpp b/src/hacks/KillSay.cpp index c2c147dd..71cb0397 100644 --- a/src/hacks/KillSay.cpp +++ b/src/hacks/KillSay.cpp @@ -130,6 +130,6 @@ void KillSayEventListener::FireGameEvent(IGameEvent* event) { if (!hacks::shared::killsay::killsay_mode) return; std::string message = hacks::shared::killsay::ComposeKillSay(event); if (message.size()) { - chat_stack::stack.push(message); + chat_stack::Say(message); } } diff --git a/src/hacks/Spam.cpp b/src/hacks/Spam.cpp index defc8fad..12d6e5d7 100644 --- a/src/hacks/Spam.cpp +++ b/src/hacks/Spam.cpp @@ -62,7 +62,7 @@ void CreateMove() { if (random_order) current_index = rand() % source->size(); std::string spamString = source->at(current_index); ReplaceString(spamString, "\\n", "\n"); - chat_stack::stack.push(spamString); + chat_stack::Say(spamString); current_index++; } } diff --git a/src/hacks/UberSpam.cpp b/src/hacks/UberSpam.cpp index 962c9bfe..b76c0890 100644 --- a/src/hacks/UberSpam.cpp +++ b/src/hacks/UberSpam.cpp @@ -17,6 +17,7 @@ static CatVar on_ready(CV_SWITCH, "uberspam_ready", "1", "Uber Ready"); static CatVar on_used(CV_SWITCH, "uberspam_used", "1", "Uber Used"); static CatVar on_ended(CV_SWITCH, "uberspam_ended", "1", "Uber Ended"); static CatVar on_build(CV_INT, "uberspam_build", "25", "Uber Build", "Send a message every #% ubercharge. 0 = never send", 0, 100); +static CatVar team_chat(CV_SWITCH, "uberspam_team", "1", "Uber Team Chat", "Send uberspam messages in team chat"); static CatVar custom_file(CV_STRING, "uberspam_file", "uberspam.txt", "Ubercharge Spam File", "Use cat_uberspam_file_reload! Same as spam/killsay files."); static CatCommand custom_file_reload("uberspam_file_reload", "Reload Ubercharge Spam File", []() { custom_lines.Load(std::string(custom_file.GetString())); @@ -56,20 +57,22 @@ void CreateMove() { bool release = CE_BYTE(LOCAL_W, netvar.bChargeRelease); if (release_last_frame != release) { if (release) { - if (on_used) chat_stack::stack.push(GetSource()->at(1)); + if (on_used) chat_stack::Say(GetSource()->at(1), !!team_chat); } else { - if (on_ended) chat_stack::stack.push(GetSource()->at(2)); + if (on_ended) chat_stack::Say(GetSource()->at(2), !!team_chat); } } if (!release && ((int)(100.0f * charge) != last_charge)) { if (charge == 1.0f) { - if (on_ready) chat_stack::stack.push(GetSource()->at(0)); + if (on_ready) chat_stack::Say(GetSource()->at(0), !!team_chat); } else { if ((int)(charge * 100.0f) != 0 && on_build) { - if (((int)(charge * 100.0f) % (int)on_build) == 0) { + int chargeperline = ((int)on_build >= 100) ? (100 / (GetSource()->size() - 2)) : (int)on_build; + if (chargeperline < 1) chargeperline = 1; + if ((int)(charge * 100.0f) % chargeperline == 0) { std::string res = GetSource()->at(ChargePercentLineIndex(charge)); ReplaceString(res, "%i%", std::to_string((int)(charge * 100.0f))); - chat_stack::stack.push(res); + chat_stack::Say(res, !!team_chat); } } } From 245d717834cea4c92fe3b11ebdfea2195e6a82ca Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 16:55:39 +0300 Subject: [PATCH 02/10] multiplatform offset support + faster hooks --- src/common.h | 1 + src/hack.cpp | 82 ++++++++++---------------- src/hacks/Misc.cpp | 9 ++- src/hooks.cpp | 114 ++++++++++++++++++------------------ src/hooks.h | 88 +++++++++++++--------------- src/hooks/BeginFrame.cpp | 14 ----- src/hooks/CreateMove.cpp | 20 ++++--- src/hooks/PaintTraverse.cpp | 5 +- src/hooks/hookedmethods.h | 38 ++++++------ src/hooks/others.cpp | 82 +++++++++++++------------- src/offsets.hpp | 66 +++++++++++++++++++++ 11 files changed, 273 insertions(+), 246 deletions(-) delete mode 100644 src/hooks/BeginFrame.cpp create mode 100644 src/offsets.hpp diff --git a/src/common.h b/src/common.h index fdd0772d..dd0f9dd4 100644 --- a/src/common.h +++ b/src/common.h @@ -27,6 +27,7 @@ #include #include #include "aftercheaders.h" +#include "offsets.hpp" #include "drawing.h" #include "resource.hpp" #include "entitycache.h" diff --git a/src/hack.cpp b/src/hack.cpp index 1432a221..f36d2423 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -127,49 +127,39 @@ void hack::Initialize() { InitNetVars(); g_pLocalPlayer = new LocalPlayer(); g_pPlayerResource = new TFPlayerResource(); - hooks::hkPanel = new hooks::VMTHook(); - hooks::hkPanel->Init(g_IPanel, 0); - //hooks::hkPanel->HookMethod((void*)&hack::Hk_PaintTraverse, hooks::offPaintTraverse); - hooks::hkPanel->HookMethod((void*)PaintTraverse_hook, hooks::offPaintTraverse); - hooks::hkPanel->Apply(); - hooks::hkClientMode = new hooks::VMTHook(); + + /* + * TIME FOR HOOKING! wow + */ + hooks::panel.Set(g_IPanel); + hooks::panel.HookMethod((void*)PaintTraverse_hook, offsets::PaintTraverse()); + hooks::panel.Apply(); uintptr_t* clientMode = 0; + // Bad way to get clientmode. + // FIXME [MP]? while(!(clientMode = **(uintptr_t***)((uintptr_t)((*(void***)g_IBaseClient)[10]) + 1))) { sleep(1); } - //hooks::hkMatSurface = new hooks::VMTHook(); - //hooks::hkMatSurface->Init((void*)matsurface, 0); - //hooks::hkMatSurface->HookMethod((void*)test_handleevent, 1); - hooks::hkClientMode->Init((void*)clientMode, 0); - //hooks::hkClientMode->HookMethod((void*)&hack::Hk_CreateMove, hooks::offCreateMove); - hooks::hkClientMode->HookMethod((void*)CreateMove_hook, hooks::offCreateMove); - hooks::hkClientMode->HookMethod((void*)OverrideView_hook, hooks::offOverrideView); - hooks::hkClientMode->HookMethod((void*)LevelInit_hook, hooks::offLevelInit); - hooks::hkClientMode->HookMethod((void*)LevelShutdown_hook, hooks::offLevelShutdown); - hooks::hkClientMode->Apply(); - hooks::hkStudioRender = new hooks::VMTHook(); - hooks::hkStudioRender->Init((void*)g_IStudioRender, 0); - hooks::hkStudioRender->HookMethod((void*)BeginFrame_hook, hooks::offBeginFrame); - hooks::hkStudioRender->Apply(); - hooks::hkClient = new hooks::VMTHook(); - hooks::hkClient->Init((void*)g_IBaseClient, 0); - hooks::hkClient->HookMethod((void*)FrameStageNotify_hook, hooks::offFrameStageNotify); - hooks::hkClient->HookMethod((void*)DispatchUserMessage_hook, hooks::offFrameStageNotify + 1); - hooks::hkClient->HookMethod((void*)IN_KeyEvent_hook, hooks::offKeyEvent); - hooks::hkClient->Apply(); - hooks::hkInput = new hooks::VMTHook(); - hooks::hkInput->Init((void*)g_IInput, 0); - hooks::hkInput->HookMethod((void*)GetUserCmd_hook, hooks::offGetUserCmd); - hooks::hkInput->Apply(); - //logging::Info("Before hacking: %s", g_ISteamFriends->GetPersonaName()); - hooks::hkIVModelRender = new hooks::VMTHook(); - hooks::hkIVModelRender->Init(g_IVModelRender, 0); - hooks::hkIVModelRender->HookMethod((void*)DrawModelExecute_hook, hooks::offDrawModelExecute); - hooks::hkIVModelRender->Apply(); - hooks::hkSteamFriends = new hooks::VMTHook(); - hooks::hkSteamFriends->Init(g_ISteamFriends, 0); - hooks::hkSteamFriends->HookMethod((void*)GetFriendPersonaName_hook, hooks::offGetFriendPersonaName); - hooks::hkSteamFriends->Apply(); + hooks::clientmode.Set((void*)clientMode); + hooks::clientmode.HookMethod((void*)CreateMove_hook, offsets::CreateMove()); + hooks::clientmode.HookMethod((void*)OverrideView_hook, offsets::OverrideView()); + hooks::clientmode.HookMethod((void*)LevelInit_hook, offsets::LevelInit()); + hooks::clientmode.HookMethod((void*)LevelShutdown_hook, offsets::LevelShutdown()); + hooks::clientmode.Apply(); + hooks::client.Set(g_IBaseClient); + hooks::client.HookMethod((void*)FrameStageNotify_hook, offsets::FrameStageNotify()); + hooks::client.HookMethod((void*)DispatchUserMessage_hook, offsets::DispatchUserMessage()); + hooks::client.HookMethod((void*)IN_KeyEvent_hook, offsets::IN_KeyEvent()); + hooks::client.Apply(); + hooks::input.Set(g_IInput); + hooks::input.HookMethod((void*)GetUserCmd_hook, offsets::GetUserCmd()); + hooks::input.Apply(); + hooks::modelrender.Set(g_IVModelRender); + hooks::modelrender.HookMethod((void*)DrawModelExecute_hook, offsets::DrawModelExecute()); + hooks::modelrender.Apply(); + hooks::steamfriends.Set(g_ISteamFriends); + hooks::steamfriends.HookMethod((void*)GetFriendPersonaName_hook, offsets::GetFriendPersonaName()); + hooks::steamfriends.Apply(); //logging::Info("After hacking: %s", g_ISteamFriends->GetPersonaName()); // Sadly, it doesn't work as expected :( /*hooks::hkBaseClientState = new hooks::VMTHook(); @@ -181,6 +171,8 @@ void hack::Initialize() { //hooks::hkBaseClientState8->HookMethod((void*)ProcessSetConVar_hook, hooks::offProcessSetConVar); //hooks::hkBaseClientState8->HookMethod((void*)ProcessGetCvarValue_hook, hooks::offProcessGetCvarValue); //hooks::hkBaseClientState8->Apply(); + + // FIXME [MP] if (TF2) g_GlowObjectManager = *reinterpret_cast(gSignatures.GetClientSignature("C1 E0 05 03 05") + 5); InitStrings(); hacks::shared::killsay::Init(); @@ -211,18 +203,6 @@ void hack::Shutdown() { if (hack::shutdown) return; hack::shutdown = true; playerlist::Save(); - logging::Info("Killing hooks.."); - if (hooks::hkPanel) hooks::hkPanel->Kill(); - if (hooks::hkClientMode) hooks::hkClientMode->Kill(); - if (hooks::hkClient) hooks::hkClient->Kill(); - if (hooks::hkMatSurface) hooks::hkMatSurface->Kill(); - if (hooks::hkNetChannel) hooks::hkNetChannel->Kill(); - 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(); logging::Info("Shutting down killsay..."); diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index 3a33c915..ecde5b93 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -112,16 +112,15 @@ static int last_number = 0; void CreateMove() { static bool flswitch = false; - - // TODO FIXME HOOKING WITHOUT UNHOOKING = 100% SEGV ON UNINJECT. + // TODO FIXME this should be moved out of here IClientEntity* localplayer = g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer()); if (TF && render_zoomed && localplayer) { void** vtable = *(void***)(localplayer); - if (vtable[hooks::offShouldDraw] != C_TFPlayer__ShouldDraw_hook) { - C_TFPlayer__ShouldDraw_original = vtable[hooks::offShouldDraw]; + if (vtable[offsets::ShouldDraw()] != C_TFPlayer__ShouldDraw_hook) { + C_TFPlayer__ShouldDraw_original = vtable[offsets::ShouldDraw()]; void* page = (void*)((uintptr_t)vtable &~ 0xFFF); mprotect(page, 0xFFF, PROT_READ | PROT_WRITE | PROT_EXEC); - vtable[hooks::offShouldDraw] = (void*)C_TFPlayer__ShouldDraw_hook; + vtable[offsets::ShouldDraw()] = (void*)C_TFPlayer__ShouldDraw_hook; mprotect(page, 0xFFF, PROT_READ | PROT_EXEC); } } diff --git a/src/hooks.cpp b/src/hooks.cpp index 1c3c0fce..1ae0eae0 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -10,78 +10,78 @@ #include "logging.h" #include +#include -unsigned int hooks::offCreateMove = 22; -unsigned int hooks::offPaintTraverse = 42; -unsigned int hooks::offOverrideView = 17; -unsigned int hooks::offFrameStageNotify = 35; -unsigned int hooks::offCanPacket = 57; -unsigned int hooks::offSendNetMsg = 41; -unsigned int hooks::offShutdown = 37; -unsigned int hooks::offKeyEvent = 20; -unsigned int hooks::offHandleInputEvent = 78; -unsigned int hooks::offLevelInit = 23; -unsigned int hooks::offLevelShutdown = 24; -unsigned int hooks::offBeginFrame = 5; +namespace hooks { -// This thing had been copypasted from somewhere, maybe from F1Public. - -bool hooks::IsHooked(void* inst) { - return hooks::GetVMT(inst, 0)[-2] == (void*)VMTHook::GUARD; -} - -unsigned int hooks::CountMethods(void** vmt) { +unsigned CountMethods(method_table_t table) { unsigned int i = -1; - do ++i; while (vmt[i]); + do ++i; while (table[i]); return i; } -void**& hooks::GetVMT(void* inst, unsigned int offset) { - return *reinterpret_cast((char*)inst + offset); +table_ref_t GetVMT(ptr_t inst, uint32_t offset) { + return *reinterpret_cast((uint32_t)inst + offset); } -void hooks::VMTHook::Init(void* inst, unsigned int offset) { - vmt = &GetVMT(inst, offset); - oldvmt = *vmt; - unsigned int cnt = CountMethods(oldvmt); - void **arr = array = (void**)malloc((cnt + 4) * sizeof(void*)); - arr[0] = this; - arr[1] = (void* )GUARD; - (arr + 3)[cnt] = 0; - unsigned int i = -1; - do arr[i + 3] = oldvmt[i]; while (++i < cnt); +bool IsHooked(ptr_t inst, uint32_t offset) { + return GetVMT(inst, offset)[-1] == (method_t)GUARD; } -void hooks::VMTHook::Kill() { - if (vmt) - *vmt = oldvmt; - vmt = 0; - free(array); - array = 0; +VMTHook::VMTHook() { + static_assert(ptr_size == 4, "Pointer size must be DWORD."); +}; + +VMTHook::~VMTHook() { + Release(); } -void hooks::VMTHook::HookMethod(void* func, unsigned int idx) { - array[idx + 3] = func; +void VMTHook::Set(ptr_t inst, uint32_t offset) { + Release(); + vtable_ptr = &GetVMT(inst, offset); + vtable_original = *vtable_ptr; + int mc = CountMethods(vtable_original); + vtable_hooked = static_cast(calloc(mc + 3, sizeof(ptr_t))); + memcpy(&vtable_hooked[2], vtable_original, sizeof(ptr_t) * mc); + vtable_hooked[0] = this; + vtable_hooked[1] = (void*)GUARD; } -void* hooks::VMTHook::GetMethod(unsigned int idx) const { - return oldvmt[idx]; +void VMTHook::Release() { + if (vtable_ptr) { + if ((*vtable_ptr)[-1] == (method_t)GUARD) { + *vtable_ptr = vtable_original; + } + free(vtable_hooked); + vtable_ptr = nullptr; + vtable_hooked = nullptr; + vtable_original = nullptr; + } } -void hooks::VMTHook::Apply() { - *vmt = array + 3; +void* VMTHook::GetMethod(uint32_t idx) const { + return vtable_original[idx]; } -//hooks::VMTHook* hooks::hkCTFPlayer = nullptr; -hooks::VMTHook* hooks::hkInput = nullptr; -hooks::VMTHook* hooks::hkSteamFriends = 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; -hooks::VMTHook* hooks::hkNetChannel = 0; -hooks::VMTHook* hooks::hkClientDLL = 0; -hooks::VMTHook* hooks::hkMatSurface = 0; -hooks::VMTHook* hooks::hkStudioRender = 0; -hooks::VMTHook* hooks::hkIVModelRender = nullptr; +void VMTHook::HookMethod(ptr_t func, uint32_t idx) { + vtable_hooked[2 + idx] = func; +} + +void VMTHook::Apply() { + *vtable_ptr = &vtable_hooked[2]; +} + +VMTHook input {}; +VMTHook steamfriends {}; +VMTHook baseclientstate {}; +VMTHook baseclientstate8 {}; +VMTHook clientmode {}; +VMTHook panel {}; +VMTHook client {}; +VMTHook netchannel {}; +VMTHook clientdll {}; +VMTHook matsurface {}; +VMTHook studiorender {}; +VMTHook modelrender {}; + +} diff --git a/src/hooks.h b/src/hooks.h index 1a75bfdb..74af6205 100644 --- a/src/hooks.h +++ b/src/hooks.h @@ -8,62 +8,56 @@ #ifndef HOOKS_H_ #define HOOKS_H_ -namespace hooks { - // Parts of copypasted code // Credits: Casual_Hacker -unsigned int CountMethods(void** vmt); -void**& GetVMT(void* inst, unsigned int offset); -bool IsHooked(void* inst); +#include +#include + +namespace hooks { + +typedef void* ptr_t; +typedef void* method_t; +typedef method_t* method_table_t; +typedef method_table_t* table_ptr_t; +typedef method_table_t& table_ref_t; + +constexpr size_t ptr_size = sizeof(ptr_t); + +unsigned CountMethods(method_table_t table); +table_ref_t GetVMT(ptr_t inst, uint32_t offset = 0); +bool IsHooked(ptr_t inst, uint32_t offset = 0); + +constexpr uint32_t GUARD = 0xD34DC477; class VMTHook { public: - enum { GUARD = 0xD34DC477 }; - void Init(void* inst, unsigned int offset); - void Kill(); - void HookMethod(void* func, unsigned int idx); - void* GetMethod(unsigned int idx) const; + VMTHook(); + ~VMTHook(); + void Set(ptr_t inst, uint32_t offset = 0); + void Release(); + void HookMethod(ptr_t func, uint32_t idx); + void* GetMethod(uint32_t idx) const; void Apply(); -protected: - void ***vmt; - void **oldvmt; - void **array; +public: + ptr_t object { nullptr }; + table_ptr_t vtable_ptr { nullptr }; + method_table_t vtable_original { nullptr }; + method_table_t vtable_hooked { nullptr }; }; -//extern VMTHook* hkCTFPlayer; -extern VMTHook* hkPanel; -extern VMTHook* hkClientMode; -extern VMTHook* hkClient; -extern VMTHook* hkNetChannel; -extern VMTHook* hkClientDLL; -extern VMTHook* hkMatSurface; -extern VMTHook* hkStudioRender; -extern VMTHook* hkInput; -extern VMTHook* hkIVModelRender; -extern VMTHook* hkBaseClientState; -extern VMTHook* hkBaseClientState8; -extern VMTHook* hkSteamFriends; - -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; -constexpr unsigned int offGetFriendPersonaName = 7; -extern unsigned int offHandleInputEvent; -extern unsigned int offPaintTraverse; -extern unsigned int offCreateMove; -extern unsigned int offOverrideView; -extern unsigned int offFrameStageNotify; -extern unsigned int offCanPacket; -extern unsigned int offSendNetMsg; -extern unsigned int offShutdown; -extern unsigned int offKeyEvent; -extern unsigned int offLevelInit; -extern unsigned int offLevelShutdown; -extern unsigned int offBeginFrame; +extern VMTHook panel; +extern VMTHook clientmode; +extern VMTHook client; +extern VMTHook netchannel; +extern VMTHook clientdll; +extern VMTHook matsurface; +extern VMTHook studiorender; +extern VMTHook input; +extern VMTHook modelrender; +extern VMTHook baseclientstate; +extern VMTHook baseclientstate8; +extern VMTHook steamfriends; } diff --git a/src/hooks/BeginFrame.cpp b/src/hooks/BeginFrame.cpp deleted file mode 100644 index 63a25206..00000000 --- a/src/hooks/BeginFrame.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* - * BeginFrame.cpp - * - * Created on: Feb 10, 2017 - * Author: nullifiedcat - */ - -#include "hookedmethods.h" -#include "../common.h" -#include "../sdk.h" - -void BeginFrame_hook(IStudioRender* _this) { - ((BeginFrame_t*)hooks::hkStudioRender->GetMethod(hooks::offBeginFrame))(_this); -} diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 7295211d..22dfa88a 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -12,6 +12,7 @@ #include "../common.h" #include "hookedmethods.h" +// FIXME remove this temporary code already! float AngleDiff( float destAngle, float srcAngle ) { float delta; @@ -28,7 +29,7 @@ float AngleDiff( float destAngle, float srcAngle ) delta += 360; } return delta; -}//TODO temporary +} #include "../profiler.h" @@ -70,7 +71,9 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { if (TF2C && CE_GOOD(LOCAL_W) && minigun_jump && LOCAL_W->m_iClassID == g_pClassID->CTFMinigun) { CE_INT(LOCAL_W, netvar.iWeaponState) = 0; } - bool ret = ((CreateMove_t*)hooks::hkClientMode->GetMethod(hooks::offCreateMove))(thisptr, inputSample, cmd); + + static CreateMove_t original_method = (CreateMove_t)hooks::clientmode.GetMethod(offsets::CreateMove()); + bool ret = original_method(thisptr, inputSample, cmd); PROF_SECTION(CreateMove); @@ -90,13 +93,12 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { // PROF_BEGIN(); INetChannel* ch = (INetChannel*)g_IEngine->GetNetChannelInfo(); - if (ch && !hooks::IsHooked((void*)((uintptr_t)ch))) { - hooks::hkNetChannel = new hooks::VMTHook(); - hooks::hkNetChannel->Init(ch, 0); - hooks::hkNetChannel->HookMethod((void*)CanPacket_hook, hooks::offCanPacket); - hooks::hkNetChannel->HookMethod((void*)SendNetMsg_hook, hooks::offSendNetMsg); - hooks::hkNetChannel->HookMethod((void*)Shutdown_hook, hooks::offShutdown); - hooks::hkNetChannel->Apply(); + if (ch && !hooks::IsHooked((void*)ch)) { + hooks::netchannel.Set(ch); + hooks::netchannel.HookMethod((void*)CanPacket_hook, offsets::CanPacket()); + hooks::netchannel.HookMethod((void*)SendNetMsg_hook, offsets::SendNetMsg()); + hooks::netchannel.HookMethod((void*)Shutdown_hook, offsets::Shutdown()); + hooks::netchannel.Apply(); } //logging::Info("canpacket: %i", ch->CanPacket()); //if (!cmd) return ret; diff --git a/src/hooks/PaintTraverse.cpp b/src/hooks/PaintTraverse.cpp index bcfb49d0..a775d499 100644 --- a/src/hooks/PaintTraverse.cpp +++ b/src/hooks/PaintTraverse.cpp @@ -26,7 +26,8 @@ void** pure_addr = nullptr; CatEnum software_cursor_enum({"KEEP", "ALWAYS", "NEVER", "MENU ON", "MENU OFF"}); CatVar software_cursor_mode(software_cursor_enum, "software_cursor_mode", "1", "Software cursor", "Try to change this and see what works best for you"); -void PaintTraverse_hook(void* p, unsigned int vp, bool fr, bool ar) { +void PaintTraverse_hook(void* _this, unsigned int vp, bool fr, bool ar) { + static const PaintTraverse_t original = (PaintTraverse_t)hooks::panel.GetMethod(offsets::PaintTraverse()); #if DEBUG_SEGV == true if (!segvcatch::handler_fpe || !segvcatch::handler_segv) { if (!segvcatch::handler_fpe) segvcatch::init_segv(); @@ -83,7 +84,7 @@ void PaintTraverse_hook(void* p, unsigned int vp, bool fr, bool ar) { } } - if (call_default) SAFE_CALL(((PaintTraverse_t*)hooks::hkPanel->GetMethod(hooks::offPaintTraverse))(p, vp, fr, ar)); + if (call_default) SAFE_CALL(original(_this, vp, fr, ar)); // To avoid threading problems. PROF_SECTION(PaintTraverse); diff --git a/src/hooks/hookedmethods.h b/src/hooks/hookedmethods.h index c93787d4..85436c8b 100644 --- a/src/hooks/hookedmethods.h +++ b/src/hooks/hookedmethods.h @@ -10,36 +10,32 @@ #include "../common.h" -typedef bool(CreateMove_t)(void*, float, CUserCmd*); -typedef void(PaintTraverse_t)(void*, unsigned int, bool, bool); -typedef bool(CanPacket_t)(void*); -typedef int(IN_KeyEvent_t)(void*, int, int, const char*); -typedef bool(SendNetMsg_t)(void*, INetMessage&, bool, bool); -typedef void(Shutdown_t)(void*, const char*); -typedef void(OverrideView_t)(void*, CViewSetup*); -typedef bool(DispatchUserMessage_t)(void*, int, bf_read&); -typedef void(FrameStageNotify_t)(void*, int); -typedef void(LevelInit_t)(void*, const char*); -typedef void(LevelShutdown_t)(void*); -typedef void(BeginFrame_t)(IStudioRender*); +typedef bool(*CreateMove_t)(void*, float, CUserCmd*); +typedef void(*PaintTraverse_t)(void*, unsigned int, bool, bool); +typedef bool(*CanPacket_t)(void*); +typedef int(*IN_KeyEvent_t)(void*, int, int, const char*); +typedef bool(*SendNetMsg_t)(void*, INetMessage&, bool, bool); +typedef void(*Shutdown_t)(void*, const char*); +typedef void(*OverrideView_t)(void*, CViewSetup*); +typedef bool(*DispatchUserMessage_t)(void*, int, bf_read&); +typedef void(*FrameStageNotify_t)(void*, int); +typedef void(*LevelInit_t)(void*, const char*); +typedef void(*LevelShutdown_t)(void*); +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*); +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*); -const unsigned int offCanInspect = 512; - -typedef const char*(GetFriendPersonaName_t)(ISteamFriends*, CSteamID); +typedef const char*(*GetFriendPersonaName_t)(ISteamFriends*, CSteamID); const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID); -void BeginFrame_hook(IStudioRender*); CUserCmd* GetUserCmd_hook(IInput*, int); void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, const ModelRenderInfo_t& info, matrix3x4_t* matrix); diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index 603d6a9a..b62a18fb 100644 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -12,6 +12,7 @@ static CatVar no_invisibility(CV_SWITCH, "no_invis", "0", "Remove Invisibility", "Useful with chams!"); +// This hook isn't used yet! int C_TFPlayer__DrawModel_hook(IClientEntity* _this, int flags) { float old_invis = *(float*)((uintptr_t)_this + 79u); if (no_invisibility) { @@ -27,17 +28,9 @@ static CatVar no_arms(CV_SWITCH, "no_arms", "0", "No Arms", "Removes arms from f static CatVar no_hats(CV_SWITCH, "no_hats", "0", "No Hats", "Removes non-stock hats"); void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, const ModelRenderInfo_t& info, matrix3x4_t* matrix) { - /*IClientUnknown* unknown = info.pRenderable->GetIClientUnknown(); - if (unknown) { - IClientEntity* entity = unknown->GetIClientEntity(); - if (entity && entity->entindex() != -1) { - if (entity->GetClientClass()->m_ClassID == g_pClassID->C_Player) { - //CMatRenderContextPtr ptr(); - } - } - }*/ + static const DrawModelExecute_t original = (DrawModelExecute_t)hooks::modelrender.GetMethod(offsets::DrawModelExecute()); if (!cathook || !(no_arms || no_hats || (clean_screenshots && g_IEngine->IsTakingScreenshot()))) { - ((DrawModelExecute_t)(hooks::hkIVModelRender->GetMethod(hooks::offDrawModelExecute)))(_this, state, info, matrix); + original(_this, state, info, matrix); return; } @@ -63,18 +56,20 @@ void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, } } - ((DrawModelExecute_t)(hooks::hkIVModelRender->GetMethod(hooks::offDrawModelExecute)))(_this, state, info, matrix); + original(_this, state, info, matrix); } -bool CanPacket_hook(void* thisptr) { +bool CanPacket_hook(void* _this) { + const CanPacket_t original = (CanPacket_t)hooks::netchannel.GetMethod(offsets::CanPacket()); SEGV_BEGIN; - return send_packets && ((CanPacket_t*)hooks::hkNetChannel->GetMethod(hooks::offCanPacket))(thisptr); + return send_packets && original(_this); SEGV_END; return false; } -CUserCmd* GetUserCmd_hook(IInput* thisptr, int sequence_number) { - CUserCmd* def = ((GetUserCmd_t*)(hooks::hkInput->GetMethod(hooks::offGetUserCmd)))(thisptr, sequence_number); +CUserCmd* GetUserCmd_hook(IInput* _this, int sequence_number) { + static const GetUserCmd_t original = (GetUserCmd_t)hooks::input.GetMethod(offsets::GetUserCmd()); + CUserCmd* def = original(_this, sequence_number); if (def && command_number_mod.find(def->command_number) != command_number_mod.end()) { logging::Info("Replacing command %i with %i", def->command_number, command_number_mod[def->command_number]); int oldcmd = def->command_number; @@ -85,12 +80,13 @@ CUserCmd* GetUserCmd_hook(IInput* thisptr, int sequence_number) { return def; } -int IN_KeyEvent_hook(void* thisptr, int eventcode, int keynum, const char* pszCurrentBinding) { +int IN_KeyEvent_hook(void* _this, int eventcode, int keynum, const char* pszCurrentBinding) { + static const IN_KeyEvent_t original = (IN_KeyEvent_t)hooks::client.GetMethod(offsets::IN_KeyEvent()); SEGV_BEGIN; if (g_pGUI->ConsumesKey((ButtonCode_t)keynum) && g_pGUI->Visible()) { return 0; } - return ((IN_KeyEvent_t*)hooks::hkClient->GetMethod(hooks::offKeyEvent))(thisptr, eventcode, keynum, pszCurrentBinding); + return original(_this, eventcode, keynum, pszCurrentBinding); SEGV_END; return 0; } @@ -112,7 +108,9 @@ static CatVar newlines_msg(CV_INT, "chat_newlines", "0", "Prefix newlines", "Add // TODO name \\n = \n //static CatVar queue_messages(CV_SWITCH, "chat_queue", "0", "Queue messages", "Use this if you want to use spam/killsay and still be able to chat normally (without having your msgs eaten by valve cooldown)"); -bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = false, bool bVoice = false) { +bool SendNetMsg_hook(void* _this, INetMessage& msg, bool bForceReliable = false, bool bVoice = false) { + // This is a INetChannel hook - it SHOULDN'T be static because netchannel changes. + const SendNetMsg_t original = (SendNetMsg_t)hooks::netchannel.GetMethod(offsets::SendNetMsg()); SEGV_BEGIN; // net_StringCmd if (msg.GetType() == 4 && (newlines_msg)) { @@ -128,7 +126,7 @@ bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = fals str = str.substr(16, str.length() - 17); //if (queue_messages && !chat_stack::CanSend()) { NET_StringCmd stringcmd(str.c_str()); - return ((SendNetMsg_t*)hooks::hkNetChannel->GetMethod(hooks::offSendNetMsg))(thisptr, stringcmd, bForceReliable, bVoice); + return original(_this, stringcmd, bForceReliable, bVoice); //} } } @@ -145,19 +143,21 @@ bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = fals } logging::Info("%i bytes => %s", buffer.GetNumBytesWritten(), bytes.c_str()); } - return ((SendNetMsg_t*)hooks::hkNetChannel->GetMethod(hooks::offSendNetMsg))(thisptr, msg, bForceReliable, bVoice); + return original(_this, msg, bForceReliable, bVoice); SEGV_END; return false; } CatVar disconnect_reason(CV_STRING, "disconnect_reason", "", "Disconnect reason", "A custom disconnect reason"); -void Shutdown_hook(void* thisptr, const char* reason) { +void Shutdown_hook(void* _this, const char* reason) { + // This is a INetChannel hook - it SHOULDN'T be static because netchannel changes. + const Shutdown_t original = (Shutdown_t)hooks::netchannel.GetMethod(offsets::Shutdown()); SEGV_BEGIN; if (cathook && (disconnect_reason.convar_parent->m_StringLength > 3) && strstr(reason, "user")) { - ((Shutdown_t*)hooks::hkNetChannel->GetMethod(hooks::offShutdown))(thisptr, disconnect_reason.GetString()); + original(_this, disconnect_reason.GetString()); } else { - ((Shutdown_t*)hooks::hkNetChannel->GetMethod(hooks::offShutdown))(thisptr, reason); + original(_this, reason); } SEGV_END; } @@ -167,13 +167,15 @@ static CatVar glow_alpha(CV_FLOAT, "glow_old_alpha", "1", "Alpha", "Glow Transpa static CatVar resolver(CV_SWITCH, "resolver", "0", "Resolve angles"); const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID) { + static const GetFriendPersonaName_t original = (GetFriendPersonaName_t)hooks::steamfriends.GetMethod(offsets::GetFriendPersonaName()); if ((force_name.convar->m_StringLength > 2) && steamID == g_ISteamUser->GetSteamID()) { return force_name.GetString(); } - return ((GetFriendPersonaName_t*)(hooks::hkSteamFriends->GetMethod(hooks::offGetFriendPersonaName)))(_this, steamID); + return original(_this, steamID); } -void FrameStageNotify_hook(void* thisptr, int stage) { +void FrameStageNotify_hook(void* _this, int stage) { + static const FrameStageNotify_t original = (FrameStageNotify_t)hooks::client.GetMethod(offsets::FrameStageNotify()); SEGV_BEGIN; if (!g_IEngine->IsInGame()) g_Settings.bInvalid = true; // TODO hack FSN hook @@ -255,16 +257,17 @@ void FrameStageNotify_hook(void* thisptr, int stage) { } } } - SAFE_CALL(((FrameStageNotify_t*)hooks::hkClient->GetMethod(hooks::offFrameStageNotify))(thisptr, stage)); + SAFE_CALL(original(_this, stage)); SEGV_END; } CatVar override_fov_zoomed(CV_FLOAT, "fov_zoomed", "0", "FOV override (zoomed)", "Overrides FOV with this value when zoomed in (default FOV when zoomed is 20)"); CatVar override_fov(CV_FLOAT, "fov", "0", "FOV override", "Overrides FOV with this value"); -void OverrideView_hook(void* thisptr, CViewSetup* setup) { +void OverrideView_hook(void* _this, CViewSetup* setup) { + static const OverrideView_t original = (OverrideView_t)hooks::clientmode.GetMethod(offsets::OverrideView()); SEGV_BEGIN; - ((OverrideView_t*)hooks::hkClientMode->GetMethod(hooks::offOverrideView))(thisptr, setup); + original(_this, setup); if (!cathook) return; bool zoomed = g_pLocalPlayer->bZoomed; if (zoomed && override_fov_zoomed) { @@ -280,7 +283,8 @@ void OverrideView_hook(void* thisptr, CViewSetup* setup) { static CatVar clean_chat(CV_SWITCH, "clean_chat", "0", "Clean chat", "Removes newlines from chat"); static CatVar dispatch_log(CV_SWITCH, "debug_log_usermessages", "0", "Log dispatched user messages"); -bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) { +bool DispatchUserMessage_hook(void* _this, int type, bf_read& buf) { + static const DispatchUserMessage_t original = (DispatchUserMessage_t)hooks::client.GetMethod(offsets::DispatchUserMessage()); SEGV_BEGIN; if (clean_chat) { if (type == 4) { @@ -301,31 +305,29 @@ bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) { if (dispatch_log) { logging::Info("D> %i", type); } - //if (type != net_Tick) logging::Info("Got message: %s", type); - return ((DispatchUserMessage_t*)hooks::hkClient->GetMethod(hooks::offFrameStageNotify + 1))(thisptr, type, buf); - SEGV_END; return false; + return original(_this, type, buf); + SEGV_END; + return false; } -void LevelInit_hook(void* thisptr, const char* newmap) { +void LevelInit_hook(void* _this, const char* newmap) { + static const LevelInit_t original = (LevelInit_t)hooks::clientmode.GetMethod(offsets::LevelInit()); playerlist::Save(); - ((LevelInit_t*) hooks::hkClientMode->GetMethod(hooks::offLevelInit))(thisptr, newmap); g_IEngine->ClientCmd_Unrestricted("exec cat_matchexec"); hacks::shared::aimbot::Reset(); -// LEVEL_SHUTDOWN(FollowBot); - //if (TF) LEVEL_INIT(SpyAlert); chat_stack::Reset(); hacks::shared::spam::Reset(); + original(_this, newmap); } -bool CanInspect_hook(IClientEntity*) { return true; } - -void LevelShutdown_hook(void* thisptr) { +void LevelShutdown_hook(void* _this) { + static const LevelShutdown_t original = (LevelShutdown_t)hooks::clientmode.GetMethod(offsets::LevelShutdown()); need_name_change = true; playerlist::Save(); - ((LevelShutdown_t*) hooks::hkClientMode->GetMethod(hooks::offLevelShutdown))(thisptr); g_Settings.bInvalid = true; hacks::shared::aimbot::Reset(); chat_stack::Reset(); hacks::shared::spam::Reset(); + original(_this); } diff --git a/src/offsets.hpp b/src/offsets.hpp new file mode 100644 index 00000000..c634ed19 --- /dev/null +++ b/src/offsets.hpp @@ -0,0 +1,66 @@ +/* + * offsets.hpp + * + * Created on: May 4, 2017 + * Author: nullifiedcat + */ + +#ifndef OFFSETS_HPP_ +#define OFFSETS_HPP_ + +#include +#include + +enum class platform { + PLATFORM_LINUX, + PLATFORM_WINDOWS, + PLATFORM_OSX, + PLATFORM_UNSUPPORTED +}; + +#ifdef LINUX +constexpr platform PLATFORM = platform::PLATFORM_LINUX; +#else +constexpr platform PLATFORM = platform::PLATFORM_UNSUPPORTED; +#endif + +struct offsets { + static constexpr uint32_t PlatformOffset(uint32_t offset_linux, uint32_t offset_windows, uint32_t offset_osx) { + uint32_t result = -1; + switch (PLATFORM) { + case platform::PLATFORM_LINUX: + result = offset_linux; break; + case platform::PLATFORM_WINDOWS: + result = offset_windows; break; + case platform::PLATFORM_OSX: + result = offset_osx; break; + } + if (result == -1) { + throw std::logic_error("No offset defined for this platform!"); + } + return result; + } + static constexpr uint32_t GetUserCmd() { return PlatformOffset(8, -1, -1); } + static constexpr uint32_t ShouldDraw() { return PlatformOffset(136, -1, -1); } + static constexpr uint32_t DrawModelExecute() { return PlatformOffset(19, -1, -1); } + static constexpr uint32_t GetClientName() { return PlatformOffset(44, -1, -1); } + static constexpr uint32_t ProcessSetConVar() { return PlatformOffset(4, -1, -1); } + static constexpr uint32_t ProcessGetCvarValue() { return PlatformOffset(29, -1, -1); } + static constexpr uint32_t GetFriendPersonaName() { return PlatformOffset(7, -1, -1); } + static constexpr uint32_t CreateMove() { return PlatformOffset(22, -1, -1); } + static constexpr uint32_t PaintTraverse() { return PlatformOffset(42, -1, -1); } + static constexpr uint32_t OverrideView() { return PlatformOffset(17, -1, -1); } + static constexpr uint32_t FrameStageNotify() { return PlatformOffset(35, -1, -1); } + static constexpr uint32_t DispatchUserMessage() { return PlatformOffset(36, -1, -1); } + static constexpr uint32_t CanPacket() { return PlatformOffset(57, -1, -1); } + static constexpr uint32_t SendNetMsg() { return PlatformOffset(41, -1, -1); } + static constexpr uint32_t Shutdown() { return PlatformOffset(37, -1, -1); } + static constexpr uint32_t IN_KeyEvent() { return PlatformOffset(20, -1, -1); } + static constexpr uint32_t HandleInputEvent() { return PlatformOffset(78, -1, -1); } + static constexpr uint32_t LevelInit() { return PlatformOffset(23, -1, -1); } + static constexpr uint32_t LevelShutdown() { return PlatformOffset(24, -1, -1); } + static constexpr uint32_t BeginFrame() { return PlatformOffset(5, -1, -1); } + +}; + +#endif /* OFFSETS_HPP_ */ From 59b530b20c1228ac17799d9d2bafdc2bcc85e73e Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 17:07:35 +0300 Subject: [PATCH 03/10] fix crash on joining new server caused by last update. sorry --- src/hooks.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks.cpp b/src/hooks.cpp index 1ae0eae0..6ee8013f 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -48,7 +48,8 @@ void VMTHook::Set(ptr_t inst, uint32_t offset) { } void VMTHook::Release() { - if (vtable_ptr) { + if (vtable_ptr && *vtable_ptr == &vtable_hooked[2]) { + logging::Info("Un-hooking 0x%08x (vtable @ 0x%08x)", vtable_ptr, *vtable_ptr); if ((*vtable_ptr)[-1] == (method_t)GUARD) { *vtable_ptr = vtable_original; } From f60f9ba051886b0b3a7cb2fefc6830702269a3ed Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 18:30:38 +0300 Subject: [PATCH 04/10] add IPC_ENABLED macro --- TODO | 10 ++++++++++ src/common.h | 6 ++++++ src/hacks/Aimbot.cpp | 6 +++++- src/hacks/AutoHeal.cpp | 2 ++ src/hacks/ESP.cpp | 2 ++ src/hacks/FollowBot.cpp | 4 ++++ src/hacks/FollowBot.h | 4 ++++ src/hooks/CreateMove.cpp | 8 ++++++-- src/ipc.cpp | 4 ++++ src/ipc.h | 4 ++++ src/playerlist.cpp | 4 ++++ 11 files changed, 51 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 6e1921f0..9075f1e7 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,13 @@ +MULTIPLATFORM: + +Signature Scanner +Whole IPC thing | actually, no. cathook for windows WON'T have followbots/ipc. +Signatures and offsets +File handling (playerlist, spam, etc...) +CMake? + +------------====----------- + alias clearcond "host_timescale 300;wait 500;host_timescale 1" alias clearcond_taunt "taunt;wait 50;host_timescale 300;wait 500;host_timescale 1" bind l clearcond_taunt diff --git a/src/common.h b/src/common.h index dd0f9dd4..5bc3002e 100644 --- a/src/common.h +++ b/src/common.h @@ -133,6 +133,12 @@ constexpr T _clamp(T _min, T _max, T _val) { #define GET_RENDER_CONTEXT (TF2 ? g_IMaterialSystem->GetRenderContext() : g_IMaterialSystemHL->GetRenderContext()) +#ifdef LINUX +#define IPC_ENABLED 1 +#else +#undef IPC_ENABLED +#endif + /*#define ADD_HACK(x) \ hack::AddHack(g_ph##x = new x()); diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index aac0f9f0..9120bd00 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -517,11 +517,15 @@ bool ShouldAim(CUserCmd* cmd) { if (!HasCondition(g_pLocalPlayer->entity, TFCond_Slowed)) { return false; } + // syntax gymnastics +#ifdef IPC_ENABLED if (hacks::shared::followbot::bot) { CachedEntity* player = ENTITY(hacks::shared::followbot::following_idx); if (CE_BAD(player)) return false; if (!HasCondition(player, TFCond_Slowed)) return false; - } else { + } else +#endif + { if (!(cmd->buttons & IN_ATTACK2)) { return false; } diff --git a/src/hacks/AutoHeal.cpp b/src/hacks/AutoHeal.cpp index 0da9d00c..57ba0a52 100644 --- a/src/hacks/AutoHeal.cpp +++ b/src/hacks/AutoHeal.cpp @@ -388,11 +388,13 @@ int HealingPriority(int idx) { priority += 50 * (1 - healthp); priority += 10 * (1 - overhealp); } +#ifdef IPC_ENABLED if (ipc::peer) { if (hacks::shared::followbot::bot && hacks::shared::followbot::following_idx == idx) { priority *= 3.0f; } } +#endif return priority; } diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 47fb43fa..05a6f442 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -418,6 +418,7 @@ void ProcessEntity(CachedEntity* ent) { if (pclass > 0 && pclass < 10) AddEntityString(ent, classes[pclass - 1]); } +#ifdef IPC_ENABLED if (show_bot_id && ipc::peer && ent != LOCAL_E) { for (unsigned i = 1; i < cat_ipc::max_peers; i++) { if (!ipc::peer->memory->peer_data[i].free && ipc::peer->memory->peer_user_data[i].friendid == info.friendsID) { @@ -426,6 +427,7 @@ void ProcessEntity(CachedEntity* ent) { } } } +#endif if (show_health) { AddEntityString(ent, format(ent->m_iHealth, '/', ent->m_iMaxHealth, " HP"), colors::Health(ent->m_iHealth, ent->m_iMaxHealth)); } diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index 9754c64c..eea5946c 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -5,6 +5,8 @@ * Author: nullifiedcat */ +#ifdef IPC_ENABLED + #include "FollowBot.h" #include "../common.h" @@ -321,3 +323,5 @@ void DoWalking() { } }}} + +#endif diff --git a/src/hacks/FollowBot.h b/src/hacks/FollowBot.h index bf06cccb..a97cdfd8 100644 --- a/src/hacks/FollowBot.h +++ b/src/hacks/FollowBot.h @@ -5,6 +5,8 @@ * Author: nullifiedcat */ +#ifdef IPC_ENABLED + #ifndef HACKS_FOLLOWBOT_H_ #define HACKS_FOLLOWBOT_H_ @@ -33,3 +35,5 @@ void AfterCreateMove(); }}} #endif /* HACKS_FOLLOWBOT_H_ */ + +#endif diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 22dfa88a..20da18c1 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -122,7 +122,7 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { g_Settings.bInvalid = false; // Disabled because this causes EXTREME aimbot inaccuracy //if (!cmd->command_number) return ret; - +#ifdef IPC_ENABLED if (hacks::shared::followbot::bot) { static int team_joining_state = 0; static float last_jointeam_try = 0; @@ -172,6 +172,7 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { } } +#endif if (CE_GOOD(g_pLocalPlayer->entity)) { ResetCritHack(); if (TF2) SAFE_CALL(UpdateHoovyList()); @@ -209,7 +210,9 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { // TODO Auto Steam Friend if (g_GlobalVars->framecount % 1000 == 0) { playerlist::DoNotKillMe(); +#ifdef IPC_ENABLED ipc::UpdatePlayerlist(); +#endif } if (CE_GOOD(g_pLocalPlayer->entity)) { @@ -258,10 +261,11 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { ret = false; } - +#ifdef IPC_ENABLED if (CE_GOOD(g_pLocalPlayer->entity) && !g_pLocalPlayer->life_state) { SAFE_CALL(hacks::shared::followbot::AfterCreateMove()); } +#endif if (cmd) g_Settings.last_angles = cmd->viewangles; } diff --git a/src/ipc.cpp b/src/ipc.cpp index 56b6ec8c..a67a75e6 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -5,6 +5,8 @@ * Author: nullifiedcat */ +#ifdef IPC_ENABLED + #include "ipc.h" #include "common.h" @@ -138,3 +140,5 @@ void UpdatePlayerlist() { } } + +#endif diff --git a/src/ipc.h b/src/ipc.h index 8d8a0285..5f7da201 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -5,6 +5,8 @@ * Author: nullifiedcat */ +#ifdef IPC_ENABLED + #ifndef IPC_H_ #define IPC_H_ @@ -58,3 +60,5 @@ void UpdatePlayerlist(); } #endif /* IPC_H_ */ + +#endif diff --git a/src/playerlist.cpp b/src/playerlist.cpp index f3d11241..145222a8 100644 --- a/src/playerlist.cpp +++ b/src/playerlist.cpp @@ -8,6 +8,10 @@ #include "playerlist.hpp" #include "common.h" +#include +#include +#include + namespace playerlist { std::unordered_map data {}; From 98ad2e94226044c2e7e8743220951ef28bb21487 Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 18:33:22 +0300 Subject: [PATCH 05/10] foolish --- src/common.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/common.h b/src/common.h index 5bc3002e..9a405a95 100644 --- a/src/common.h +++ b/src/common.h @@ -10,6 +10,14 @@ #include + +#ifdef LINUX +#define IPC_ENABLED 1 +#else +#undef IPC_ENABLED +#endif + + #include "beforecheaders.h" #include #include @@ -132,13 +140,6 @@ constexpr T _clamp(T _min, T _max, T _val) { #endif #define GET_RENDER_CONTEXT (TF2 ? g_IMaterialSystem->GetRenderContext() : g_IMaterialSystemHL->GetRenderContext()) - -#ifdef LINUX -#define IPC_ENABLED 1 -#else -#undef IPC_ENABLED -#endif - /*#define ADD_HACK(x) \ hack::AddHack(g_ph##x = new x()); From f4f47df3a7c682461ba1d9cc399fc5b7a537e37f Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 19:11:48 +0300 Subject: [PATCH 06/10] FIX compile error related to offsets.hpp --- .settings/language.settings.xml | 8 ++++---- src/offsets.hpp | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 4573b4fd..3b6c7dff 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -38,7 +38,7 @@ - + diff --git a/src/offsets.hpp b/src/offsets.hpp index c634ed19..61a90415 100644 --- a/src/offsets.hpp +++ b/src/offsets.hpp @@ -35,9 +35,8 @@ struct offsets { case platform::PLATFORM_OSX: result = offset_osx; break; } - if (result == -1) { - throw std::logic_error("No offset defined for this platform!"); - } + // pCompileError. + //static_assert(result != -1, "No offset defined for this platform!"); return result; } static constexpr uint32_t GetUserCmd() { return PlatformOffset(8, -1, -1); } From d02db0cdb44411cadab6d30dd153620455c9a85d Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 20:36:10 +0300 Subject: [PATCH 07/10] OMAN I AM NOT GOOD WITH COMPUTERS PLZ TO HELP --- src/hacks/FollowBot.cpp | 3 +- src/hacks/SkinChanger.cpp | 142 ++++++++++++++++++++++++++++++++++++ src/hacks/SkinChanger.hpp | 87 ++++++++++++++++++++++ src/hacks/hacklist.h | 1 + src/hooks/PaintTraverse.cpp | 1 + src/hooks/others.cpp | 1 + src/ipc.cpp | 3 +- 7 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 src/hacks/SkinChanger.cpp create mode 100644 src/hacks/SkinChanger.hpp diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index eea5946c..b52df27b 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -5,12 +5,13 @@ * Author: nullifiedcat */ -#ifdef IPC_ENABLED #include "FollowBot.h" #include "../common.h" +#ifdef IPC_ENABLED + namespace hacks { namespace shared { namespace followbot { unsigned follow_steamid { 0 }; diff --git a/src/hacks/SkinChanger.cpp b/src/hacks/SkinChanger.cpp new file mode 100644 index 00000000..3e10e829 --- /dev/null +++ b/src/hacks/SkinChanger.cpp @@ -0,0 +1,142 @@ +/* + * SkinChanger.cpp + * + * Created on: May 4, 2017 + * Author: nullifiedcat + */ + +#include "SkinChanger.hpp" + +namespace hacks { namespace tf2 { namespace skinchanger { + +CAttribute::CAttribute(uint16_t iAttributeDefinitionIndex, float flValue) { + data.defidx = iAttributeDefinitionIndex; + data.value = flValue; +} + +void CAttributeList::RemoveAttribute(int index) { + for (int i = 0; i < m_Attributes.Count(); i++) { + const auto& a = m_Attributes[i]; + if (a.data.defidx == index) { + m_Attributes.Remove(i); + return; + } + } +} + +void CAttributeList::SetAttribute(int index, float value) { + // Let's check if attribute exists already. We don't want dupes. + for (int i = 0; i < m_Attributes.Count(); i++) { + auto& a = m_Attributes[i]; + if (a.data.defidx == index) { + a.data.value = value; + return; + } + } + + if (m_Attributes.Count() > 14) + return; + + m_Attributes.AddToTail(CAttribute { index, value }); +} + +static CatVar enabled(CV_SWITCH, "skinchanger", "0", "Skin Changer"); +static CatCommand set_attr("skinchanger_set", "Set Attribute", [](const CCommand& args) { + unsigned attrid = strtoul(args.Arg(1), nullptr, 10); + unsigned attrv = strtoul(args.Arg(2), nullptr, 10); + GetModifier(LOCAL_W->m_IDX).Set(attrid, attrv); + InvalidateCookies(); +}); + +void FrameStageNotify(int stage) { + if (!enabled) return; + CachedEntity* weapon = LOCAL_W; + if (CE_BAD(weapon)) return; + if (!GetCookie(weapon->m_IDX).Check()) { + logging::Info("Cookie bad for %i", weapon->m_IDX); // FIXME DEBUG LOGS! + GetModifier(CE_INT(weapon, netvar.iItemDefinitionIndex)).Apply(weapon->m_IDX); + GetCookie(weapon->m_IDX).Update(weapon->m_IDX); + } +} + +void PaintTraverse() { + if (!enabled) return; + // Debug info? +} + +void def_attribute_modifier::Set(int id, float value) { + for (auto& i : modifiers) { + if (i.defidx == id) { + i.value = value; + return; + } + } + attribute_s& attr = modifiers.at(modifiers.size()); + attr.defidx = id; + attr.value = value; +} + +void InvalidateCookies() { + logging::Info("All cookies invalidated!"); // FIXME DEBUG LOGS! + for (auto& cookie : cookie_map) { + cookie.second.valid = false; + } +} + +patched_weapon_cookie::patched_weapon_cookie(int entity) { + Update(entity); +} + +void patched_weapon_cookie::Update(int entity) { + IClientEntity* ent = g_IEntityList->GetClientEntity(entity); + if (!ent || ent->IsDormant()) return; + logging::Info("Updating cookie for %i", entity); // FIXME DEBUG LOGS! + eidx = entity; + defidx = NET_INT(ent, netvar.iItemDefinitionIndex); + eclass = ent->GetClientClass()->m_ClassID; + valid = true; +} + +bool patched_weapon_cookie::Check() { + if (!valid) return false; + IClientEntity* ent = g_IEntityList->GetClientEntity(eidx); + if (!ent || ent->IsDormant()) return false; + if (eclass != ent->GetClientClass()->m_ClassID) return false; + if (defidx != NET_INT(ent, netvar.iItemDefinitionIndex)) return false; +} + +void def_attribute_modifier::Apply(int entity) { + IClientEntity* ent = g_IEntityList->GetClientEntity(entity); + if (!ent || ent->IsDormant()) return; + CAttributeList* list = NET_VAR(ent, netvar.AttributeList, CAttributeList*); + logging::Info("Applying modifiers for %i", entity); + for (const auto& mod : modifiers) { + if (mod.defidx) { + logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS! + list->SetAttribute(mod.defidx, mod.value); + } + } +} + +def_attribute_modifier& GetModifier(int idx) { + try { + return modifier_map.at(idx); + } catch (std::out_of_range& oor) { + modifier_map.emplace(idx, def_attribute_modifier{}); + return modifier_map.at(idx); + } +} + +patched_weapon_cookie& GetCookie(int idx) { + try { + return cookie_map.at(idx); + } catch (std::out_of_range& oor) { + cookie_map.emplace(idx, patched_weapon_cookie{idx}); + return cookie_map.at(idx); + } +} + +std::unordered_map modifier_map {}; +std::unordered_map cookie_map {}; + +}}} diff --git a/src/hacks/SkinChanger.hpp b/src/hacks/SkinChanger.hpp new file mode 100644 index 00000000..149152c3 --- /dev/null +++ b/src/hacks/SkinChanger.hpp @@ -0,0 +1,87 @@ +/* + * SkinChanger.hpp + * + * Created on: May 4, 2017 + * Author: nullifiedcat + */ + +#ifndef HACKS_SKINCHANGER_HPP_ +#define HACKS_SKINCHANGER_HPP_ + +#include "../common.h" + +namespace hacks { namespace tf2 { namespace skinchanger { + +// TOTALLY NOT A PASTE. +// Seriously tho, it's modified at least. +// Credits: blackfire62 + +struct attribute_s { + uint16_t defidx; + float value; +}; + +class CAttribute { +public: + CAttribute(uint16_t iAttributeDefinitionIndex, float flValue); +public: + uint32_t pad00; + attribute_s data; + uint32_t pad01; +}; + +class CAttributeList { +public: + void SetAttribute(int index, float value); + void RemoveAttribute(int index); +public: + uint32_t pad00; + CUtlVector> m_Attributes; +}; + +enum class Attributes { + loot_rarity = 2022, + is_australium_item = 2027, + item_style_override = 542, + sheen = 2014, + killstreak_tier = 2025 +}; + +enum class UnusualEffects { + HOT = 701, + ISOTOPE, + COOL, + ENERGY_ORB +}; + +struct patched_weapon_cookie { + patched_weapon_cookie(int entity); + void Update(int entity); + bool Check(); +public: + int eidx { 0 }; + int defidx { 0 }; + int eclass { 0 }; + bool valid { false }; +}; + +struct def_attribute_modifier { + void Apply(int entity); + void Set(int id, float value); + int defidx { 0 }; + std::array modifiers { attribute_s{ 0, 0 } }; +}; + +extern std::unordered_map modifier_map; +extern std::unordered_map cookie_map; + +def_attribute_modifier& GetModifier(int idx); +patched_weapon_cookie& GetCookie(int idx); + +void InvalidateCookies(); +void FrameStageNotify(int stage); +void PaintTraverse(); + +}}} + +#endif /* HACKS_SKINCHANGER_HPP_ */ diff --git a/src/hacks/hacklist.h b/src/hacks/hacklist.h index fe453563..0f8586a3 100644 --- a/src/hacks/hacklist.h +++ b/src/hacks/hacklist.h @@ -24,6 +24,7 @@ #include "Trigger.h" #include "KillSay.h" #include "UberSpam.hpp" +#include "SkinChanger.hpp" #include "Achievement.h" #include "Spam.h" #include "Noisemaker.h" diff --git a/src/hooks/PaintTraverse.cpp b/src/hooks/PaintTraverse.cpp index a775d499..91585815 100644 --- a/src/hooks/PaintTraverse.cpp +++ b/src/hooks/PaintTraverse.cpp @@ -157,6 +157,7 @@ void PaintTraverse_hook(void* _this, unsigned int vp, bool fr, bool ar) { SAFE_CALL(hacks::shared::esp::Draw()); if (TF) SAFE_CALL(hacks::tf::spyalert::Draw()); if (TF) SAFE_CALL(hacks::tf::radar::Draw()); + if (TF2) SAFE_CALL(hacks::tf2::skinchanger::PaintTraverse()); } diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index b62a18fb..84331068 100644 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -179,6 +179,7 @@ void FrameStageNotify_hook(void* _this, int stage) { SEGV_BEGIN; if (!g_IEngine->IsInGame()) g_Settings.bInvalid = true; // TODO hack FSN hook + hacks::tf2::skinchanger::FrameStageNotify(stage); if (resolver && cathook && !g_Settings.bInvalid && stage == FRAME_NET_UPDATE_POSTDATAUPDATE_START) { for (int i = 1; i < 32 && i < HIGHEST_ENTITY; i++) { if (i == g_IEngine->GetLocalPlayer()) continue; diff --git a/src/ipc.cpp b/src/ipc.cpp index a67a75e6..ce4bce6c 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -5,13 +5,14 @@ * Author: nullifiedcat */ -#ifdef IPC_ENABLED #include "ipc.h" #include "common.h" #include "hack.h" +#ifdef IPC_ENABLED + namespace ipc { std::atomic thread_running(false); From ee66887e4ec72fdf3fbdedeee728254c4048bc25 Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 21:55:39 +0300 Subject: [PATCH 08/10] the heck is wrong with this code --- src/hacks/SkinChanger.cpp | 43 +++++++++++++++++++++++++++++++-------- src/hacks/SkinChanger.hpp | 12 +++++++---- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/hacks/SkinChanger.cpp b/src/hacks/SkinChanger.cpp index 3e10e829..14c738d7 100644 --- a/src/hacks/SkinChanger.cpp +++ b/src/hacks/SkinChanger.cpp @@ -10,26 +10,28 @@ namespace hacks { namespace tf2 { namespace skinchanger { CAttribute::CAttribute(uint16_t iAttributeDefinitionIndex, float flValue) { - data.defidx = iAttributeDefinitionIndex; - data.value = flValue; + defidx = iAttributeDefinitionIndex; + value = flValue; } void CAttributeList::RemoveAttribute(int index) { for (int i = 0; i < m_Attributes.Count(); i++) { const auto& a = m_Attributes[i]; - if (a.data.defidx == index) { + if (a.defidx == index) { m_Attributes.Remove(i); return; } } } +CAttributeList::CAttributeList() {} + void CAttributeList::SetAttribute(int index, float value) { // Let's check if attribute exists already. We don't want dupes. for (int i = 0; i < m_Attributes.Count(); i++) { auto& a = m_Attributes[i]; - if (a.data.defidx == index) { - a.data.value = value; + if (a.defidx == index) { + a.value = value; return; } } @@ -37,6 +39,10 @@ void CAttributeList::SetAttribute(int index, float value) { if (m_Attributes.Count() > 14) return; + //m_Attributes.m_Memory.m_nGrowSize = -1; + logging::Info("0x%08x 0x%08x 0x%08x", m_Attributes.m_Memory.m_nAllocationCount, m_Attributes.m_Memory.m_nGrowSize, m_Attributes.m_Memory.m_pMemory); + //m_Attributes.m_Memory.SetExternalBuffer(m_Attributes.m_Memory.Base(), 15); + m_Attributes.AddToTail(CAttribute { index, value }); } @@ -44,9 +50,15 @@ static CatVar enabled(CV_SWITCH, "skinchanger", "0", "Skin Changer"); static CatCommand set_attr("skinchanger_set", "Set Attribute", [](const CCommand& args) { unsigned attrid = strtoul(args.Arg(1), nullptr, 10); unsigned attrv = strtoul(args.Arg(2), nullptr, 10); - GetModifier(LOCAL_W->m_IDX).Set(attrid, attrv); + GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).Set(attrid, attrv); InvalidateCookies(); }); +static CatCommand set_redirect("skinchanger_redirect", "Set Redirect", [](const CCommand& args) { + unsigned redirect = strtoul(args.Arg(1), nullptr, 10); + GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).defidx_redirect = redirect; + InvalidateCookies(); +}); +static CatCommand invalidate_cookies("skinchanger_invalidate_cookies", "Invalidate Cookies", InvalidateCookies); void FrameStageNotify(int stage) { if (!enabled) return; @@ -61,6 +73,8 @@ void FrameStageNotify(int stage) { void PaintTraverse() { if (!enabled) return; + if (CE_GOOD(LOCAL_W)) + AddSideString(format("dIDX: ", CE_INT(LOCAL_W, netvar.iItemDefinitionIndex))); // Debug info? } @@ -71,7 +85,8 @@ void def_attribute_modifier::Set(int id, float value) { return; } } - attribute_s& attr = modifiers.at(modifiers.size()); + attribute_s& attr = modifiers.at(first_free_mod); + first_free_mod++; attr.defidx = id; attr.value = value; } @@ -103,13 +118,23 @@ bool patched_weapon_cookie::Check() { if (!ent || ent->IsDormant()) return false; if (eclass != ent->GetClientClass()->m_ClassID) return false; if (defidx != NET_INT(ent, netvar.iItemDefinitionIndex)) return false; + return true; } void def_attribute_modifier::Apply(int entity) { IClientEntity* ent = g_IEntityList->GetClientEntity(entity); if (!ent || ent->IsDormant()) return; - CAttributeList* list = NET_VAR(ent, netvar.AttributeList, CAttributeList*); - logging::Info("Applying modifiers for %i", entity); + logging::Info("Applying modifiers for %i %i %i", entity, NET_INT(ent, netvar.iItemDefinitionIndex), defidx_redirect); + if (defidx_redirect && NET_INT(ent, netvar.iItemDefinitionIndex) != defidx_redirect) { + NET_INT(ent, netvar.iItemDefinitionIndex) = defidx_redirect; + logging::Info("Updated DefIDX to %i", NET_INT(ent, netvar.iItemDefinitionIndex)); + GetCookie(entity).valid = false; + return; + } + CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*); + logging::Info("Attribute list: 0x%08x 0x%08x 0x%08x 0x%08x", 0x9c0, ent, list, (uint32_t)list - (uint32_t)ent); + logging::Info("Length: %i", list->m_Attributes.m_Size); + logging::Info("Base: 0x%08x", list->m_Attributes.Base()); for (const auto& mod : modifiers) { if (mod.defidx) { logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS! diff --git a/src/hacks/SkinChanger.hpp b/src/hacks/SkinChanger.hpp index 149152c3..f09ebb7e 100644 --- a/src/hacks/SkinChanger.hpp +++ b/src/hacks/SkinChanger.hpp @@ -25,17 +25,19 @@ class CAttribute { public: CAttribute(uint16_t iAttributeDefinitionIndex, float flValue); public: - uint32_t pad00; - attribute_s data; - uint32_t pad01; + void* pad00; + uint16_t defidx; + float value; + unsigned int pad01; }; class CAttributeList { public: + CAttributeList(); void SetAttribute(int index, float value); void RemoveAttribute(int index); public: - uint32_t pad00; + void* pad; CUtlVector> m_Attributes; }; @@ -69,7 +71,9 @@ struct def_attribute_modifier { void Apply(int entity); void Set(int id, float value); int defidx { 0 }; + int defidx_redirect { 0 }; std::array modifiers { attribute_s{ 0, 0 } }; + int first_free_mod { 0 }; }; extern std::unordered_map modifier_map; From 53c4c147a4d7b1bd66e9eb813e8a5be807a994bf Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 22:29:21 +0300 Subject: [PATCH 09/10] no work --- src/hacks/SkinChanger.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hacks/SkinChanger.cpp b/src/hacks/SkinChanger.cpp index 14c738d7..5650071b 100644 --- a/src/hacks/SkinChanger.cpp +++ b/src/hacks/SkinChanger.cpp @@ -40,10 +40,10 @@ void CAttributeList::SetAttribute(int index, float value) { return; //m_Attributes.m_Memory.m_nGrowSize = -1; - logging::Info("0x%08x 0x%08x 0x%08x", m_Attributes.m_Memory.m_nAllocationCount, m_Attributes.m_Memory.m_nGrowSize, m_Attributes.m_Memory.m_pMemory); + //logging::Info("0x%08x 0x%08x 0x%08x", m_Attributes.m_Memory.m_nAllocationCount, m_Attributes.m_Memory.m_nGrowSize, m_Attributes.m_Memory.m_pMemory); //m_Attributes.m_Memory.SetExternalBuffer(m_Attributes.m_Memory.Base(), 15); - - m_Attributes.AddToTail(CAttribute { index, value }); + CAttribute attr( index, value ); + m_Attributes.AddToTail(attr); } static CatVar enabled(CV_SWITCH, "skinchanger", "0", "Skin Changer"); @@ -65,9 +65,18 @@ void FrameStageNotify(int stage) { CachedEntity* weapon = LOCAL_W; if (CE_BAD(weapon)) return; if (!GetCookie(weapon->m_IDX).Check()) { + CAttributeList* list = CE_VAR(weapon, 0x9c0, CAttributeList*); + logging::Info("ATTRIBUTE LIST (BEFORE UPDATE): "); + for (int i = 0; i < list->m_Attributes.Size(); i++) { + logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value); + } logging::Info("Cookie bad for %i", weapon->m_IDX); // FIXME DEBUG LOGS! GetModifier(CE_INT(weapon, netvar.iItemDefinitionIndex)).Apply(weapon->m_IDX); GetCookie(weapon->m_IDX).Update(weapon->m_IDX); + logging::Info("ATTRIBUTE LIST (AFTER UPDATE): "); + for (int i = 0; i < list->m_Attributes.Size(); i++) { + logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value); + } } } @@ -89,6 +98,7 @@ void def_attribute_modifier::Set(int id, float value) { first_free_mod++; attr.defidx = id; attr.value = value; + logging::Info("new attr: %i %.2f %i", attr.defidx, attr.value, first_free_mod); } void InvalidateCookies() { @@ -132,9 +142,10 @@ void def_attribute_modifier::Apply(int entity) { return; } CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*); - logging::Info("Attribute list: 0x%08x 0x%08x 0x%08x 0x%08x", 0x9c0, ent, list, (uint32_t)list - (uint32_t)ent); + //::Info("Attribute list: 0x%08x 0x%08x 0x%08x 0x%08x", 0x9c0, ent, list, (uint32_t)list - (uint32_t)ent); + list->m_Attributes.m_Size = list->m_Attributes.Size(); logging::Info("Length: %i", list->m_Attributes.m_Size); - logging::Info("Base: 0x%08x", list->m_Attributes.Base()); + //logging::Info("Base: 0x%08x", list->m_Attributes.Base()); for (const auto& mod : modifiers) { if (mod.defidx) { logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS! From 25ede155d63346e95593a129d40ddfad91578314 Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Thu, 4 May 2017 23:14:29 +0300 Subject: [PATCH 10/10] =?UTF-8?q?skin=20machine=20=F0=9F=85=B1roke?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hacks/SkinChanger.cpp | 41 ++++++++++++++++++++++----------------- src/hacks/SkinChanger.hpp | 5 +++-- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/hacks/SkinChanger.cpp b/src/hacks/SkinChanger.cpp index 5650071b..98bb88ce 100644 --- a/src/hacks/SkinChanger.cpp +++ b/src/hacks/SkinChanger.cpp @@ -58,26 +58,27 @@ static CatCommand set_redirect("skinchanger_redirect", "Set Redirect", [](const GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).defidx_redirect = redirect; InvalidateCookies(); }); +static CatCommand dump_attrs("skinchanger_debug_attrs", "Dump attributes", []() { + CAttributeList* list = CE_VAR(LOCAL_W, netvar.AttributeList, CAttributeList*); + logging::Info("ATTRIBUTE LIST: %i", list->m_Attributes.Size()); + for (int i = 0; i < 15; i++) { + logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value); + } +}); static CatCommand invalidate_cookies("skinchanger_invalidate_cookies", "Invalidate Cookies", InvalidateCookies); void FrameStageNotify(int stage) { if (!enabled) return; - CachedEntity* weapon = LOCAL_W; - if (CE_BAD(weapon)) return; - if (!GetCookie(weapon->m_IDX).Check()) { - CAttributeList* list = CE_VAR(weapon, 0x9c0, CAttributeList*); - logging::Info("ATTRIBUTE LIST (BEFORE UPDATE): "); - for (int i = 0; i < list->m_Attributes.Size(); i++) { - logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value); - } + if (stage != FRAME_NET_UPDATE_POSTDATAUPDATE_START) return; + int handle = CE_INT(g_pLocalPlayer->entity, netvar.hActiveWeapon); + int eid = handle & 0xFFF; + IClientEntity* entity = g_IEntityList->GetClientEntity(eid); + GetModifier(NET_INT(entity, netvar.iItemDefinitionIndex)).Apply(eid); + /*if (!GetCookie(weapon->m_IDX).Check()) { logging::Info("Cookie bad for %i", weapon->m_IDX); // FIXME DEBUG LOGS! GetModifier(CE_INT(weapon, netvar.iItemDefinitionIndex)).Apply(weapon->m_IDX); GetCookie(weapon->m_IDX).Update(weapon->m_IDX); - logging::Info("ATTRIBUTE LIST (AFTER UPDATE): "); - for (int i = 0; i < list->m_Attributes.Size(); i++) { - logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value); - } - } + }*/ } void PaintTraverse() { @@ -116,6 +117,8 @@ void patched_weapon_cookie::Update(int entity) { IClientEntity* ent = g_IEntityList->GetClientEntity(entity); if (!ent || ent->IsDormant()) return; logging::Info("Updating cookie for %i", entity); // FIXME DEBUG LOGS! + CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*); + attrs = list->m_Attributes.Size(); eidx = entity; defidx = NET_INT(ent, netvar.iItemDefinitionIndex); eclass = ent->GetClientClass()->m_ClassID; @@ -126,6 +129,8 @@ bool patched_weapon_cookie::Check() { if (!valid) return false; IClientEntity* ent = g_IEntityList->GetClientEntity(eidx); if (!ent || ent->IsDormant()) return false; + CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*); + if (attrs != list->m_Attributes.Size()) return false; if (eclass != ent->GetClientClass()->m_ClassID) return false; if (defidx != NET_INT(ent, netvar.iItemDefinitionIndex)) return false; return true; @@ -133,22 +138,22 @@ bool patched_weapon_cookie::Check() { void def_attribute_modifier::Apply(int entity) { IClientEntity* ent = g_IEntityList->GetClientEntity(entity); - if (!ent || ent->IsDormant()) return; - logging::Info("Applying modifiers for %i %i %i", entity, NET_INT(ent, netvar.iItemDefinitionIndex), defidx_redirect); + if (!ent) return; + //logging::Info("Applying modifiers for %i %i %i", entity, NET_INT(ent, netvar.iItemDefinitionIndex), defidx_redirect); if (defidx_redirect && NET_INT(ent, netvar.iItemDefinitionIndex) != defidx_redirect) { NET_INT(ent, netvar.iItemDefinitionIndex) = defidx_redirect; logging::Info("Updated DefIDX to %i", NET_INT(ent, netvar.iItemDefinitionIndex)); GetCookie(entity).valid = false; return; } - CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*); + CAttributeList* list = NET_VAR(ent, netvar.AttributeList, CAttributeList*); //::Info("Attribute list: 0x%08x 0x%08x 0x%08x 0x%08x", 0x9c0, ent, list, (uint32_t)list - (uint32_t)ent); list->m_Attributes.m_Size = list->m_Attributes.Size(); - logging::Info("Length: %i", list->m_Attributes.m_Size); + //logging::Info("Length: %i", list->m_Attributes.m_Size); //logging::Info("Base: 0x%08x", list->m_Attributes.Base()); for (const auto& mod : modifiers) { if (mod.defidx) { - logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS! + //logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS! list->SetAttribute(mod.defidx, mod.value); } } diff --git a/src/hacks/SkinChanger.hpp b/src/hacks/SkinChanger.hpp index f09ebb7e..d75481e9 100644 --- a/src/hacks/SkinChanger.hpp +++ b/src/hacks/SkinChanger.hpp @@ -25,7 +25,7 @@ class CAttribute { public: CAttribute(uint16_t iAttributeDefinitionIndex, float flValue); public: - void* pad00; + void* vtable; uint16_t defidx; float value; unsigned int pad01; @@ -37,7 +37,7 @@ public: void SetAttribute(int index, float value); void RemoveAttribute(int index); public: - void* pad; + uint32_t unknown; CUtlVector> m_Attributes; }; @@ -64,6 +64,7 @@ public: int eidx { 0 }; int defidx { 0 }; int eclass { 0 }; + int attrs { 0 }; bool valid { false }; };