From 285e22accbc81e137ef48ccd6986e693260ad78a Mon Sep 17 00:00:00 2001 From: BenCat07 Date: Fri, 13 Aug 2021 15:00:04 +0200 Subject: [PATCH] Add a bypass to some community AntiCheats and small anti-afk change --- include/hacks/AntiCheatBypass.hpp | 14 ++++++++ include/sdk/netmessage.hpp | 9 +++--- src/crits.cpp | 25 +++++++++++++- src/hacks/Aimbot.cpp | 4 +++ src/hacks/AntiCheatBypass.cpp | 54 +++++++++++++++++++++++++++++++ src/hacks/Backtrack.cpp | 12 ++++++- src/hacks/CMakeLists.txt | 1 + src/hacks/Misc.cpp | 20 ++---------- src/hooks/SendDatagram.cpp | 4 ++- src/hooks/SendNetMsg.cpp | 3 ++ 10 files changed, 122 insertions(+), 24 deletions(-) create mode 100644 include/hacks/AntiCheatBypass.hpp create mode 100644 src/hacks/AntiCheatBypass.cpp diff --git a/include/hacks/AntiCheatBypass.hpp b/include/hacks/AntiCheatBypass.hpp new file mode 100644 index 00000000..9c73f895 --- /dev/null +++ b/include/hacks/AntiCheatBypass.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace hacks::tf2::antianticheat +{ + +extern settings::Boolean enabled; + +void SendNetMsg(INetMessage &msg); + +bool CanSetCmdNum(int new_cmdnum); +} // namespace hacks::tf2::antianticheat diff --git a/include/sdk/netmessage.hpp b/include/sdk/netmessage.hpp index 626e9141..36b3144b 100644 --- a/include/sdk/netmessage.hpp +++ b/include/sdk/netmessage.hpp @@ -105,8 +105,8 @@ public: { // Call original to be sure nothing breaks typedef bool (*BIncomingMessageForProcessing_t)(CNetMessage *, double, int); - static auto addr = gSignatures.GetEngineSignature("55 89 E5 56 53 83 EC 10 8B 5D ? F2 0F 10 45"); - BIncomingMessageForProcessing_t BIncomingMessageForProcessing_fn = (BIncomingMessageForProcessing_t)addr; + static auto addr = gSignatures.GetEngineSignature("55 89 E5 56 53 83 EC 10 8B 5D ? F2 0F 10 45"); + BIncomingMessageForProcessing_t BIncomingMessageForProcessing_fn = (BIncomingMessageForProcessing_t) addr; return BIncomingMessageForProcessing_fn(this, param_1, param_2); }; // I don't get what it does but we need it @@ -114,8 +114,8 @@ public: { // Call original to be sure nothing breaks typedef bool (*SetRatePolicy_t)(CNetMessage *); - static auto addr = gSignatures.GetEngineSignature("55 89 E5 83 EC 18 C7 04 24 2C 00 00 00"); - SetRatePolicy_t SetRatePolicy_fn = (SetRatePolicy_t)addr; + static auto addr = gSignatures.GetEngineSignature("55 89 E5 83 EC 18 C7 04 24 2C 00 00 00"); + SetRatePolicy_t SetRatePolicy_fn = (SetRatePolicy_t) addr; SetRatePolicy_fn(this); }; @@ -214,6 +214,7 @@ class CLC_RespondCvarValue : public CNetMessage public: DECLARE_CLC_MESSAGE(RespondCvarValue); + char pad[4]; QueryCvarCookie_t m_iCookie; const char *m_szCvarName; diff --git a/src/crits.cpp b/src/crits.cpp index d4e0aedd..8bed9864 100644 --- a/src/crits.cpp +++ b/src/crits.cpp @@ -3,6 +3,7 @@ #include "Backtrack.hpp" #include "WeaponData.hpp" #include "netadr.h" +#include "AntiCheatBypass.hpp" std::unordered_map command_number_mod{}; @@ -214,6 +215,7 @@ static int nextCritTick(int loops = 4096) for (int i = 0; i < loops; i++) { int cmd_number = current_late_user_cmd->command_number + i; + // Set random seed *g_PredictionRandomSeed = MD5_PseudoRandom(cmd_number) & 0x7FFFFFFF; // Save weapon state to not break anything @@ -420,8 +422,29 @@ bool prevent_crit() // Main function that forces a crit void force_crit() { + // Can't use normal methods here + if (hacks::tf2::antianticheat::enabled) + { + // We have to ignore these sadly + if (CE_GOOD(LOCAL_W) && (LOCAL_W->m_iClassID() == CL_CLASS(CTFCannon) || LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher) || CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 730)) + return; + // May only go up to 60 ticks in the future + int next_crit = nextCritTick(60); + + // None found, release m1 + if (next_crit == -1) + current_late_user_cmd->buttons &= ~IN_ATTACK; + // Force crit + else + { + current_late_user_cmd->command_number = next_crit; + current_late_user_cmd->random_seed = MD5_PseudoRandom(current_late_user_cmd->command_number) & 0x7FFFFFFF; + current_index++; + } + } + // New mode stuff (well when not using melee nor using pipe launcher) - if (g_pLocalPlayer->weapon_mode != weapon_melee && LOCAL_W->m_iClassID() != CL_CLASS(CTFPipebombLauncher)) + else if (g_pLocalPlayer->weapon_mode != weapon_melee && LOCAL_W->m_iClassID() != CL_CLASS(CTFPipebombLauncher)) { // We have valid crit command numbers if (crit_cmds.size() && crit_cmds.find(LOCAL_W->m_IDX) != crit_cmds.end() && crit_cmds.find(LOCAL_W->m_IDX)->second.size()) diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index abf6970d..d78ae480 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -18,6 +18,7 @@ #include "hitrate.hpp" #include "FollowBot.hpp" #include "Warp.hpp" +#include "AntiCheatBypass.hpp" namespace hacks::shared::aimbot { @@ -264,6 +265,9 @@ static void CreateMove() fov = *normal_fov; spectatorUpdate(); + // Adjust for AC + if (hacks::tf2::antianticheat::enabled) + fov = std::min(fov > 0.0f ? fov : FLT_MAX, 10.0f); if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) enable = false; diff --git a/src/hacks/AntiCheatBypass.cpp b/src/hacks/AntiCheatBypass.cpp new file mode 100644 index 00000000..81b228aa --- /dev/null +++ b/src/hacks/AntiCheatBypass.cpp @@ -0,0 +1,54 @@ +#include "common.hpp" + +namespace hacks::tf2::antianticheat +{ + +settings::Boolean enabled("misc.antianticheat.enabled", "false"); + +// Always a good idea to spoof these +void SendNetMsg(INetMessage &msg) +{ + if (msg.GetType() == clc_RespondCvarValue) + { + CLC_RespondCvarValue *cvar_msg = (CLC_RespondCvarValue *) &msg; + if (!cvar_msg->m_szCvarName) + return; + // Remove cat_ commands and the linux unique sdl_double_click_size from cvar list + if (!strcmp(cvar_msg->m_szCvarName, "cat") || !strcmp(cvar_msg->m_szCvarName, "sdl_double_click_size")) + cvar_msg->m_eStatusCode = EQueryCvarValueStatus::eQueryCvarValueStatus_CvarNotFound; + + // Spoof ourselves as Windows, bypassing Linux detection addons + else if (std::string(cvar_msg->m_szCvarName) == "windows_speaker_config") + { + cvar_msg->m_eStatusCode = EQueryCvarValueStatus::eQueryCvarValueStatus_ValueIntact; + cvar_msg->m_szCvarValue = "8"; + } + } +} + +// Currently unused, may be useful for stuff modifying cmdnum though. +bool CanSetCmdNum(int new_cmdnum) +{ + if (!enabled) + return true; + if (new_cmdnum - current_late_user_cmd->command_number >= 64) + return false; + return true; +} + +void CreateMoveLate() +{ + if (!enabled) + return; + static int silent_ticks = 0; + // "Silent" detection mostly just checks if cursor was where it was 2 ticks ago while having moved 1 tick before + if (silent_ticks == 1 && !g_pLocalPlayer->bUseSilentAngles) + current_late_user_cmd->viewangles += Vector(RandomFloat(-1.0f, 1.0f)); + + silent_ticks++; + if (!g_pLocalPlayer->bUseSilentAngles) + silent_ticks = 0; +} + +static InitRoutine init([]() { EC::Register(EC::CreateMoveLate, CreateMoveLate, "acb_cml"); }); +} // namespace hacks::tf2::antianticheat diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index a2cdf391..ddea5136 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -1,5 +1,6 @@ #include "common.hpp" #include "Backtrack.hpp" +#include "AntiCheatBypass.hpp" namespace hacks::tf2::backtrack { @@ -106,7 +107,10 @@ float getLatency() bool isTickInRange(int tickcount) { int delta_tickcount = abs(tickcount - current_user_cmd->tick_count + TIME_TO_TICKS(getLatency() / 1000.0f)); - return TICKS_TO_TIME(delta_tickcount) <= 0.2f - TICKS_TO_TIME(2); + if (!hacks::tf2::antianticheat::enabled) + return TICKS_TO_TIME(delta_tickcount) <= 0.2f - TICKS_TO_TIME(2); + else + return delta_tickcount <= TICKS_TO_TIME(1); } // Is backtrack enabled? @@ -116,7 +120,11 @@ bool isEnabled() return false; CachedEntity *wep = LOCAL_W; if (CE_BAD(wep)) + { + if (hacks::tf2::antianticheat::enabled) + return true; return false; + } int slot = re::C_BaseCombatWeapon::GetSlot(RAW_ENT(wep)); switch (*bt_slots) { @@ -250,6 +258,8 @@ void RestoreEntity(int entidx) void CreateMoveEarly() { + if (hacks::tf2::antianticheat::enabled && *latency > 200.0f) + latency = 200.0f; draw_positions.clear(); isBacktrackEnabled = isEnabled(); if (!isBacktrackEnabled) diff --git a/src/hacks/CMakeLists.txt b/src/hacks/CMakeLists.txt index 778f1f0a..b229b686 100755 --- a/src/hacks/CMakeLists.txt +++ b/src/hacks/CMakeLists.txt @@ -1,4 +1,5 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp" + "${CMAKE_CURRENT_LIST_DIR}/AntiCheatBypass.cpp" "${CMAKE_CURRENT_LIST_DIR}/CatBot.cpp" "${CMAKE_CURRENT_LIST_DIR}/Spam.cpp" "${CMAKE_CURRENT_LIST_DIR}/AutoItem.cpp" diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index dec20df5..54129fde 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -17,6 +17,7 @@ #include "core/sharedobj.hpp" #include "filesystem.h" #include "DetourHook.hpp" +#include "AntiCheatBypass.hpp" #include "hack.hpp" #include @@ -85,28 +86,12 @@ static void updateAntiAfk() } else { - Vector vel(0.0f); - if (CE_GOOD(LOCAL_E) && LOCAL_E->m_bAlivePlayer()) - velocity::EstimateAbsVelocity(RAW_ENT(LOCAL_E), vel); - // We are moving, make the timer a bit longer (only a bit to avoid issues with random movement) - if (!vel.IsZero(1.0f)) - { - anti_afk_timer.last += std::chrono::milliseconds(400); - if (anti_afk_timer.last > std::chrono::system_clock::now()) - anti_afk_timer.update(); - } static auto afk_timer = g_ICvar->FindVar("mp_idlemaxtime"); if (!afk_timer) afk_timer = g_ICvar->FindVar("mp_idlemaxtime"); // Trigger 10 seconds before kick else if (afk_timer->GetInt() != 0 && anti_afk_timer.check(afk_timer->m_nValue * 60 * 1000 - 10000)) { - // Just duck tf - if (current_user_cmd->buttons & (IN_DUCK | IN_JUMP)) - current_user_cmd->buttons &= ~(IN_DUCK | IN_JUMP); - else - current_user_cmd->buttons = IN_DUCK | IN_JUMP; - // Game also checks if you move if you are in spawn, so spam movement keys alternatingly bool flip = false; current_user_cmd->buttons |= flip ? IN_FORWARD : IN_BACK; @@ -117,6 +102,7 @@ static void updateAntiAfk() anti_afk_timer.update(); } } + last_buttons = current_user_cmd->buttons; } } @@ -306,7 +292,7 @@ void CreateMove() teammatesPushaway = g_ICvar->FindVar("tf_avoidteammates_pushaway"); // Ping Reducer - if (ping_reducer) + if (ping_reducer && !hacks::tf2::antianticheat::enabled) { static ConVar *cmdrate = g_ICvar->FindVar("cl_cmdrate"); if (cmdrate == nullptr) diff --git a/src/hooks/SendDatagram.cpp b/src/hooks/SendDatagram.cpp index fc69f5c0..c76196c0 100644 --- a/src/hooks/SendDatagram.cpp +++ b/src/hooks/SendDatagram.cpp @@ -6,11 +6,13 @@ */ #include "HookedMethods.hpp" #include "Backtrack.hpp" +#include "AntiCheatBypass.hpp" + namespace hooked_methods { DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf) { - if (!isHackActive() || !ch || CE_BAD(LOCAL_E) || std::floor(*hacks::tf2::backtrack::latency) == 0) + if (!isHackActive() || !ch || (CE_BAD(LOCAL_E) && !hacks::tf2::antianticheat::enabled) || std::floor(*hacks::tf2::backtrack::latency) == 0) return original::SendDatagram(ch, buf); int in = ch->m_nInSequenceNr; diff --git a/src/hooks/SendNetMsg.cpp b/src/hooks/SendNetMsg.cpp index e77657dc..ecaec712 100644 --- a/src/hooks/SendNetMsg.cpp +++ b/src/hooks/SendNetMsg.cpp @@ -12,6 +12,7 @@ #include "e8call.hpp" #include "Warp.hpp" #include "nospread.hpp" +#include "AntiCheatBypass.hpp" #include "SteamIDStealer.hpp" static settings::Int newlines_msg{ "chat.prefix-newlines", "0" }; @@ -228,6 +229,8 @@ DEFINE_HOOKED_METHOD(SendNetMsg, bool, INetChannel *this_, INetMessage &msg, boo else hacks::tf2::warp::SendNetMessage(msg); + hacks::tf2::antianticheat::SendNetMsg(msg); + // net_StringCmd if (msg.GetType() == 4 && (newlines_msg || crypt_chat)) {