From 5fffac5bab74152f365361f94b3c193535a27fa3 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 1 Mar 2016 13:37:51 +0100 Subject: [PATCH] Entirely block dll injections --- deps/protobuf | 2 +- src/Components/Modules/AntiCheat.cpp | 54 ++++++++++++++++++--------- src/Components/Modules/AntiCheat.hpp | 1 + src/Components/Modules/Auth.cpp | 3 +- src/Components/Modules/Dedicated.cpp | 9 +++++ src/Components/Modules/Dedicated.hpp | 2 + src/Components/Modules/Download.cpp | 9 +---- src/Components/Modules/Logger.cpp | 3 +- src/Components/Modules/Node.cpp | 3 +- src/Components/Modules/QuickPatch.cpp | 24 ++++++++++++ src/Components/Modules/QuickPatch.hpp | 3 ++ src/Components/Modules/Renderer.cpp | 9 +++++ src/Components/Modules/Renderer.hpp | 2 + src/Utils/Hooking.hpp | 3 ++ 14 files changed, 95 insertions(+), 32 deletions(-) diff --git a/deps/protobuf b/deps/protobuf index 52f62e36..584233bd 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 52f62e3652ce80ab14593331f4277539e7fa29c8 +Subproject commit 584233bd043a80b2172a598039113d4fe14dc326 diff --git a/src/Components/Modules/AntiCheat.cpp b/src/Components/Modules/AntiCheat.cpp index 6b2590e3..33f7174d 100644 --- a/src/Components/Modules/AntiCheat.cpp +++ b/src/Components/Modules/AntiCheat.cpp @@ -35,11 +35,12 @@ namespace Components 0xDC, 0xC1, 0xDC, 0x05, // Uninstall minidump handler - 0xB8, 0x63, 0xE7, 0x2F, 0x00, // mov eax, 2FE763h - 0x05, 0xAD, 0xAD, 0x3C, 0x00, // add eax, 3CADADh - 0x6A, 0x58, // push 88 - 0x8B, 0x80, 0xEA, 0x01, 0x00, 0x00, // mov eax, [eax + 1EAh] - 0xFF, 0x10, // call dword ptr [eax] + // This doesn't work anymore, due to the SetUnhandledExceptionFilter hook, but that's not important + //0xB8, 0x63, 0xE7, 0x2F, 0x00, // mov eax, 2FE763h + //0x05, 0xAD, 0xAD, 0x3C, 0x00, // add eax, 3CADADh + //0x6A, 0x58, // push 88 + //0x8B, 0x80, 0xEA, 0x01, 0x00, 0x00, // mov eax, [eax + 1EAh] + //0xFF, 0x10, // call dword ptr [eax] // Crash me. 0xB8, 0x4F, 0x91, 0x27, 0x00, // mov eax, 27914Fh @@ -62,15 +63,6 @@ namespace Components // Push the fake var onto the stack push ebx - // Get address to VirtualProtect - mov eax, 6567h - shl eax, 0Ch - or eax, 70000A50h - - // Move the address into ebx - push eax - pop ebx - // Save the address to our crash procedure mov eax, offset crashProcedure push eax @@ -80,9 +72,10 @@ namespace Components push 40h push 2D5FFFh push 401001h - call ebx + call VirtualProtect // Increment to our crash procedure + // Skip variable space add dword ptr [esp], 4h // This basically removes the pushed ebx value from the stack, so returning results in a call to the procedure @@ -126,12 +119,39 @@ namespace Components AntiCheat::PerformCheck(); } + void AntiCheat::PatchWinAPI() + { + auto loadLibStub = [] () + { + __asm + { + xor eax, eax + retn 4h + } + }; + + auto loadLibExStub = [] () + { + __asm + { + xor eax, eax + retn 0Ch + } + }; + + Utils::Hook(LoadLibraryA, loadLibStub, HOOK_JUMP).Install()->Quick(); + Utils::Hook(LoadLibraryW, loadLibStub, HOOK_JUMP).Install()->Quick(); + Utils::Hook(LoadLibraryExA, loadLibExStub, HOOK_JUMP).Install()->Quick(); + Utils::Hook(LoadLibraryExW, loadLibExStub, HOOK_JUMP).Install()->Quick(); + } + AntiCheat::AntiCheat() { AntiCheat::EmptyHash(); - Renderer::OnFrame(AntiCheat::Frame); - Dedicated::OnFrame(AntiCheat::Frame); + + QuickPatch::OnFrame(AntiCheat::Frame); + QuickPatch::Once(AntiCheat::PatchWinAPI); #ifdef DEBUG Command::Add("penis", [] (Command::Params) diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index 94d89efb..c647db44 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -16,6 +16,7 @@ namespace Components static void Frame(); static void PerformCheck(); + static void PatchWinAPI(); static void NullSub(); }; diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index 1a1c3565..2b7db050 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -375,8 +375,7 @@ namespace Components }); // Install frame handlers - Dedicated::OnFrame(Auth::Frame); - Renderer::OnFrame(Auth::Frame); + QuickPatch::OnFrame(Auth::Frame); // Register dvar Dvar::Register("sv_securityLevel", 23, 0, 512, Game::dvar_flag::DVAR_FLAG_SERVERINFO, "Security level for GUID certificates (POW)"); diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 5e5bb07d..08be4fec 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -3,6 +3,7 @@ namespace Components { wink::signal> Dedicated::FrameSignal; + wink::signal> Dedicated::FrameOnceSignal; bool Dedicated::IsDedicated() { @@ -143,6 +144,11 @@ namespace Components Network::SendCommand(master, "heartbeat", "IW4"); } + void Dedicated::Once(Dedicated::Callback* callback) + { + Dedicated::FrameOnceSignal.connect(callback); + } + void Dedicated::OnFrame(Dedicated::Callback* callback) { Dedicated::FrameSignal.connect(callback); @@ -151,6 +157,8 @@ namespace Components void Dedicated::FrameStub() { Dedicated::FrameSignal(); + Dedicated::FrameOnceSignal(); + Dedicated::FrameOnceSignal.clear(); Utils::Hook::Call(0x5A8E80)(); } @@ -245,6 +253,7 @@ namespace Components Dedicated::~Dedicated() { + Dedicated::FrameOnceSignal.clear(); Dedicated::FrameSignal.clear(); } } diff --git a/src/Components/Modules/Dedicated.hpp b/src/Components/Modules/Dedicated.hpp index 6c342c49..4b6322a6 100644 --- a/src/Components/Modules/Dedicated.hpp +++ b/src/Components/Modules/Dedicated.hpp @@ -14,9 +14,11 @@ namespace Components static void Heartbeat(); static void OnFrame(Callback* callback); + static void Once(Callback* callback); private: static wink::signal> FrameSignal; + static wink::signal> FrameOnceSignal; static void MapRotate(); static void FrameStub(); diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index 15cd2c39..ec8c47e6 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -393,14 +393,7 @@ namespace Components { #ifdef ENABLE_EXPERIMENTAL_UDP_DOWNLOAD // Frame handlers - if (Dedicated::IsDedicated()) - { - Dedicated::OnFrame(Download::Frame); - } - else - { - Renderer::OnFrame(Download::Frame); - } + QuickPatch::OnFrame(Download::Frame); // Register client handlers Network::Handle("dlAckRequest", Download::AckRequest); diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index 70d89deb..b88a6074 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -133,8 +133,7 @@ namespace Components { Logger::PipeOutput(nullptr); - Renderer::OnFrame(Logger::Frame); // Client - Dedicated::OnFrame(Logger::Frame); // Dedi + QuickPatch::OnFrame(Logger::Frame); Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).Install()->Quick(); } diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 54697374..d9f34114 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -700,8 +700,7 @@ namespace Components }); // Install frame handlers - Dedicated::OnFrame(Node::FrameHandler); - Renderer::OnFrame(Node::FrameHandler); + QuickPatch::OnFrame(Node::FrameHandler); } Node::~Node() diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 53b6eab2..125058f8 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -21,6 +21,30 @@ namespace Components QuickPatch::ShutdownSignal(); } + void QuickPatch::OnFrame(QuickPatch::Callback* callback) + { + if (Dedicated::IsDedicated()) + { + Dedicated::OnFrame(callback); + } + else + { + Renderer::OnFrame(callback); + } + } + + void QuickPatch::Once(QuickPatch::Callback* callback) + { + if (Dedicated::IsDedicated()) + { + Dedicated::Once(callback); + } + else + { + Renderer::Once(callback); + } + } + void QuickPatch::UnlockStats() { Command::Execute("setPlayerData prestige 10"); diff --git a/src/Components/Modules/QuickPatch.hpp b/src/Components/Modules/QuickPatch.hpp index 37b0ae6b..c535f1b0 100644 --- a/src/Components/Modules/QuickPatch.hpp +++ b/src/Components/Modules/QuickPatch.hpp @@ -12,6 +12,9 @@ namespace Components static void UnlockStats(); static void OnShutdown(Callback* callback); + static void OnFrame(Callback* callback); + static void Once(Callback* callback); + private: static wink::signal> ShutdownSignal; diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index 7580ea84..8125ec8c 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -4,6 +4,7 @@ namespace Components { Utils::Hook Renderer::DrawFrameHook; wink::signal> Renderer::FrameSignal; + wink::signal> Renderer::FrameOnceSignal; void __declspec(naked) Renderer::FrameHook() { @@ -17,6 +18,13 @@ namespace Components void Renderer::FrameHandler() { Renderer::FrameSignal(); + Renderer::FrameOnceSignal(); + Renderer::FrameOnceSignal.clear(); + } + + void Renderer::Once(Renderer::Callback* callback) + { + Renderer::FrameOnceSignal.connect(callback); } void Renderer::OnFrame(Renderer::Callback* callback) @@ -43,6 +51,7 @@ namespace Components Renderer::~Renderer() { Renderer::DrawFrameHook.Uninstall(); + Renderer::FrameOnceSignal.clear(); Renderer::FrameSignal.clear(); } } diff --git a/src/Components/Modules/Renderer.hpp b/src/Components/Modules/Renderer.hpp index 777f39a9..4b703cf1 100644 --- a/src/Components/Modules/Renderer.hpp +++ b/src/Components/Modules/Renderer.hpp @@ -12,6 +12,7 @@ namespace Components static int Width(); static int Height(); + static void Once(Callback* callback); static void OnFrame(Callback* callback); private: @@ -19,6 +20,7 @@ namespace Components static void FrameHandler(); static wink::signal> FrameSignal; + static wink::signal> FrameOnceSignal; static Utils::Hook DrawFrameHook; }; } diff --git a/src/Utils/Hooking.hpp b/src/Utils/Hooking.hpp index d7a28930..9695a5a0 100644 --- a/src/Utils/Hooking.hpp +++ b/src/Utils/Hooking.hpp @@ -9,7 +9,10 @@ namespace Utils { public: Hook() : Place(nullptr), Stub(nullptr), Initialized(false), Installed(false), Original(0), UseJump(false), Protection(0) { ZeroMemory(Hook::Buffer, sizeof(Hook::Buffer)); } + Hook(void* place, void* stub, bool useJump = true) : Hook() { Hook::Initialize(place, stub, useJump); } + Hook(void* place, void(*stub)(), bool useJump = true) : Hook(place, reinterpret_cast(stub), useJump) {} + Hook(DWORD place, void* stub, bool useJump = true) : Hook(reinterpret_cast(place), stub, useJump) {} Hook(DWORD place, DWORD stub, bool useJump = true) : Hook(reinterpret_cast(place), reinterpret_cast(stub), useJump) {} Hook(DWORD place, void(*stub)(), bool useJump = true) : Hook(reinterpret_cast(place), reinterpret_cast(stub), useJump) {}