From b0537675ccf95ae52ef1e9cf7f9fa8e90ca1fd9d Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 11 May 2022 16:24:19 +0100 Subject: [PATCH 1/2] [Security] Refactor patch (fix mistake?) --- src/Components/Modules/Network.cpp | 11 +---------- src/Components/Modules/Network.hpp | 1 - src/Components/Modules/Security.cpp | 23 +++++++++++++++++++++++ src/Components/Modules/Security.hpp | 2 ++ src/Game/Functions.cpp | 2 ++ src/Game/Functions.hpp | 2 ++ src/Game/Structs.hpp | 21 ++++++++++++++++++++- 7 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index ee44d739..4d9ab118 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -356,17 +356,11 @@ namespace Components } } - void Network::NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg) - { - if (msg->cursize > 0 && msg->cursize <= 1404) - Game::NET_DeferPacketToClient(from, msg); - } - void Network::SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) { if (client->reliableAcknowledge < 0) { - Logger::Print("Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n", + Logger::Print(Game::conChannel_t::CON_CHANNEL_NETWORK, "Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n", client->name, client->reliableSequence, client->reliableAcknowledge); client->reliableAcknowledge = client->reliableSequence; Network::SendCommand(Game::NS_SERVER, client->netchan.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS"); @@ -412,9 +406,6 @@ namespace Components // Install packet deploy hook Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub); - // Fix packets causing buffer overflow - Utils::Hook(0x6267E3, Network::NET_DeferPacketToClientStub, HOOK_CALL).install()->quick(); - // Fix server freezer exploit Utils::Hook(0x626996, Network::SV_ExecuteClientMessageStub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index f3096350..38686e16 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -87,7 +87,6 @@ namespace Components static void NetworkStartStub(); static void PacketErrorCheck(); - static void NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg); static void SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg); }; diff --git a/src/Components/Modules/Security.cpp b/src/Components/Modules/Security.cpp index b2493cf1..86e8192a 100644 --- a/src/Components/Modules/Security.cpp +++ b/src/Components/Modules/Security.cpp @@ -84,6 +84,26 @@ namespace Components Game::G_LogPrintf("%s", fmt); } + void Security::NET_DeferPacketToClientStub(Game::netadr_t* net_from, Game::msg_t* net_message) + { + assert(net_from != nullptr); + assert(net_message != nullptr); + + if (static_cast(net_message->cursize) >= sizeof(Game::DeferredMsg::data)) + { + return; + } + + auto* msg = &Game::deferredQueue->msgs[Game::deferredQueue->send & 0xF]; + std::memcpy(msg->data, net_message->data, net_message->cursize); + + msg->datalen = net_message->cursize; + msg->addr.type = net_from->type; + msg->addr = *net_from; + + InterlockedIncrement(&Game::deferredQueue->send); + } + Security::Security() { // Exploit fixes @@ -108,5 +128,8 @@ namespace Components // Patch unsecure call to G_LogPrint inside GScr_LogPrint // This function is unsafe because IW devs forgot to G_LogPrintf("%s", fmt) Utils::Hook(0x5F70B5, G_LogPrintfStub, HOOK_CALL).install()->quick(); + + // Fix packets causing buffer overflow + Utils::Hook(0x6267E3, NET_DeferPacketToClientStub, HOOK_CALL).install()->quick(); } } diff --git a/src/Components/Modules/Security.hpp b/src/Components/Modules/Security.hpp index 82c605bd..23ceb4d6 100644 --- a/src/Components/Modules/Security.hpp +++ b/src/Components/Modules/Security.hpp @@ -20,5 +20,7 @@ namespace Components static int G_GetClientScore(); static void G_LogPrintfStub(const char* fmt); + + static void NET_DeferPacketToClientStub(Game::netadr_t* net_from, Game::msg_t* net_message); }; } diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index d7d00756..38dc86e1 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -562,6 +562,8 @@ namespace Game int* window_center_x = reinterpret_cast(0x649D638); int* window_center_y = reinterpret_cast(0x649D630); + DeferredQueue* deferredQueue = reinterpret_cast(0x1CC2CE8); + int* g_waitingForKey = reinterpret_cast(0x63A50FC); void Sys_LockRead(FastCriticalSection* critSect) diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 47658d08..672a6cc0 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -1166,6 +1166,8 @@ namespace Game extern int* window_center_x; extern int* window_center_y; + extern DeferredQueue* deferredQueue; + extern int* g_waitingForKey; void Sys_LockRead(FastCriticalSection* critSect); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index f30a607d..ec9595e3 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -5365,12 +5365,13 @@ namespace Game struct netadr_t { netadrtype_t type; - //char ip[4]; netIP_t ip; unsigned __int16 port; char ipx[10]; }; + static_assert(sizeof(netadr_t) == 20); + struct netProfileInfo_t { char __pad0[0x5E0]; @@ -7561,6 +7562,24 @@ namespace Game static_assert(sizeof(WinMouseVars_t) == 0x10); + struct DeferredMsg + { + netadr_t addr; + unsigned char data[1400]; + int datalen; + }; + + static_assert(sizeof(DeferredMsg) == 0x590); + + struct DeferredQueue + { + DeferredMsg msgs[16]; + volatile long get; + volatile long send; + }; + + static_assert(sizeof(DeferredQueue) == 0x5908); + #pragma endregion #ifndef IDA From aedd63f2062f74a462ccd0afcdb8de078d4d55e1 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 11 May 2022 18:27:58 +0100 Subject: [PATCH 2/2] Address review --- src/Components/Modules/Security.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Components/Modules/Security.cpp b/src/Components/Modules/Security.cpp index 86e8192a..aefa116e 100644 --- a/src/Components/Modules/Security.cpp +++ b/src/Components/Modules/Security.cpp @@ -94,11 +94,10 @@ namespace Components return; } - auto* msg = &Game::deferredQueue->msgs[Game::deferredQueue->send & 0xF]; + auto* msg = &Game::deferredQueue->msgs[Game::deferredQueue->send % std::extent_v]; std::memcpy(msg->data, net_message->data, net_message->cursize); msg->datalen = net_message->cursize; - msg->addr.type = net_from->type; msg->addr = *net_from; InterlockedIncrement(&Game::deferredQueue->send);