From 3f726d3d0da50984309a6cb65c48d579ba7aeba8 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 13:47:35 +0200 Subject: [PATCH 1/8] Initial Hooking of functions --- src/Components/Modules/Network.cpp | 15 ++++++++++++++- src/Components/Modules/Network.hpp | 2 ++ src/Game/Structs.hpp | 6 ++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 37ab799d..ae4d00fd 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -14,7 +14,7 @@ namespace Components { Game::SockadrToNetadr(addr, &this->address); } - bool Network::Address::operator==(const Network::Address &obj) const + bool Network::Address::operator==(const Network::Address& obj) const { return Game::NET_CompareAdr(this->address, obj.address); } @@ -342,6 +342,17 @@ namespace Components Game::NET_DeferPacketToClient(from, msg); } + void Network::SVExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) + { + const char* message = Utils::String::VA("ServerID: %d, Sequence: %d, Acknowledge: %d, Sent: %d, Message: %d\n", client->serverID, + client->reliableSequence, client->reliableAcknowledge, + client->reliableSent, client->messageAcknowledge); + + OutputDebugStringA(message); + + Utils::Hook::Call(0x414D40)(client, msg); + } + Network::Network() { AssertSize(Game::netadr_t, 20); @@ -381,6 +392,8 @@ namespace Components // Fix packets causing buffer overflow Utils::Hook(0x6267E3, Network::NET_DeferPacketToClientStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x626996, Network::SVExecuteClientMessageStub, HOOK_CALL).install()->quick(); + Network::Handle("resolveAddress", [](Address address, const std::string& /*data*/) { Network::SendRaw(address, address.getString()); diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index b54b3c0d..a3a30779 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -89,6 +89,8 @@ namespace Components static void PacketErrorCheck(); static void NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg); + + static void SVExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg); }; } diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 51e71428..6ae3e930 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4662,7 +4662,8 @@ namespace Game int reliableSequence; // 134748 int reliableAcknowledge; // 134752 int reliableSent; // 134756 - char __pad4[1084]; // 134760 + int messageAcknowledge; // 134760 + char __pad4[1080]; // 134764 char name[16]; // 135844 char __pad5[12]; // 135860 int snapNum; // 135872 @@ -4670,7 +4671,8 @@ namespace Game short ping; // 135880 char __pad7[133158]; // 135882 int isBot; // 269040 - char __pad8[9228]; // 269044 + int serverID; // 269044 + char __pad8[9224]; // 269048 unsigned __int64 steamID; // 278272 char __pad9[403592]; // 278280 } client_t; From eba1762fd0768c2315a90419b24863f57fc6efeb Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 15:16:41 +0200 Subject: [PATCH 2/8] Add fields to client_t structs, might be useful --- src/Components/Modules/Network.cpp | 16 +++++++++------- src/Components/Modules/Network.hpp | 2 +- src/Game/Functions.hpp | 4 ++-- src/Game/Structs.hpp | 4 +++- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index ae4d00fd..dc429d27 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -342,13 +342,14 @@ namespace Components Game::NET_DeferPacketToClient(from, msg); } - void Network::SVExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) + void Network::SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) { - const char* message = Utils::String::VA("ServerID: %d, Sequence: %d, Acknowledge: %d, Sent: %d, Message: %d\n", client->serverID, - client->reliableSequence, client->reliableAcknowledge, - client->reliableSent, client->messageAcknowledge); - - OutputDebugStringA(message); + if (client->reliableAcknowledge < 0 || client->reliableAcknowledge > 0xFF) + { + client->reliableAcknowledge = 0; + Game::NET_OutOfBandPrint(Game::NS_SERVER, client->netchan.remoteAddress, "disconnect"); + return; + } Utils::Hook::Call(0x414D40)(client, msg); } @@ -392,7 +393,8 @@ namespace Components // Fix packets causing buffer overflow Utils::Hook(0x6267E3, Network::NET_DeferPacketToClientStub, HOOK_CALL).install()->quick(); - Utils::Hook(0x626996, Network::SVExecuteClientMessageStub, HOOK_CALL).install()->quick(); + // Fix server freezer exploit + Utils::Hook(0x626996, Network::SV_ExecuteClientMessageStub, HOOK_CALL).install()->quick(); Network::Handle("resolveAddress", [](Address address, const std::string& /*data*/) { diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp index a3a30779..f3248817 100644 --- a/src/Components/Modules/Network.hpp +++ b/src/Components/Modules/Network.hpp @@ -90,7 +90,7 @@ namespace Components static void PacketErrorCheck(); static void NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg); - static void SVExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg); + static void SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg); }; } diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 3536a4b7..d235a120 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -495,10 +495,10 @@ namespace Game typedef bool(__cdecl * NET_StringToAdr_t)(const char *s, netadr_t *a); extern NET_StringToAdr_t NET_StringToAdr; - typedef void(__cdecl* NET_OutOfBandPrint_t)(netsrc_t sock, netadr_t adr, const char *data); + typedef void(__cdecl * NET_OutOfBandPrint_t)(netsrc_t sock, netadr_t adr, const char *data); extern NET_OutOfBandPrint_t NET_OutOfBandPrint; - typedef void(__cdecl* NET_OutOfBandData_t)(netsrc_t sock, netadr_t adr, const char *format, int len); + typedef void(__cdecl * NET_OutOfBandData_t)(netsrc_t sock, netadr_t adr, const char *format, int len); extern NET_OutOfBandData_t NET_OutOfBandData; typedef void(__cdecl * Live_MPAcceptInvite_t)(_XSESSION_INFO *hostInfo, const int controllerIndex, bool fromGameInvite); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 6ae3e930..a928735e 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4665,7 +4665,9 @@ namespace Game int messageAcknowledge; // 134760 char __pad4[1080]; // 134764 char name[16]; // 135844 - char __pad5[12]; // 135860 + char __pad5[4]; // 135860 + int lastPacketTime; // 135864 + int lastConnectTime; // 135868 int snapNum; // 135872 int __pad6; // 135876 short ping; // 135880 From 414d56adc3d78ad119e0df75941856b31db20d51 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 15:19:04 +0200 Subject: [PATCH 3/8] Replace 0xFF with 255 for consistency --- src/Components/Modules/Network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index dc429d27..7edce178 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -344,7 +344,7 @@ namespace Components void Network::SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) { - if (client->reliableAcknowledge < 0 || client->reliableAcknowledge > 0xFF) + if (client->reliableAcknowledge < 0 || client->reliableAcknowledge > 255) { client->reliableAcknowledge = 0; Game::NET_OutOfBandPrint(Game::NS_SERVER, client->netchan.remoteAddress, "disconnect"); From 07f15acab0855054a38726f9a77fc409b7d896da Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 15:50:58 +0200 Subject: [PATCH 4/8] Properly kick player from the server using net cmd --- src/Components/Modules/Network.cpp | 2 +- src/Game/Structs.hpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 7edce178..ec6c5261 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -347,7 +347,7 @@ namespace Components if (client->reliableAcknowledge < 0 || client->reliableAcknowledge > 255) { client->reliableAcknowledge = 0; - Game::NET_OutOfBandPrint(Game::NS_SERVER, client->netchan.remoteAddress, "disconnect"); + Network::SendCommand(Game::NS_SERVER, client->netchan.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS"); return; } diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index a928735e..6f8911ae 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4671,12 +4671,14 @@ namespace Game int snapNum; // 135872 int __pad6; // 135876 short ping; // 135880 - char __pad7[133158]; // 135882 + char __pad7[14]; // 135882 + int pureAuthentic; // 135896 + char __pad8[133140]; // 135900 int isBot; // 269040 int serverID; // 269044 - char __pad8[9224]; // 269048 + char __pad9[9224]; // 269048 unsigned __int64 steamID; // 278272 - char __pad9[403592]; // 278280 + char __pad10[403592]; // 278280 } client_t; #pragma pack(pop) From 6d50778ee5f5d63822d3e9dd2d44a574548dc261 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 17:37:02 +0200 Subject: [PATCH 5/8] Remove 'greater than 0xFF' check, game already checks --- src/Components/Modules/Network.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index ec6c5261..05eb60db 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -344,9 +344,9 @@ namespace Components void Network::SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg) { - if (client->reliableAcknowledge < 0 || client->reliableAcknowledge > 255) + if (client->reliableAcknowledge < 0) { - client->reliableAcknowledge = 0; + client->reliableAcknowledge = client->reliableSequence; Network::SendCommand(Game::NS_SERVER, client->netchan.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS"); return; } From 791e4129b909af4fe649fca6ea1a0a0250be9a62 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sun, 12 Sep 2021 21:48:45 +0200 Subject: [PATCH 6/8] Reversed more client_t struct for good mesure --- src/Game/Structs.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 6f8911ae..2288861d 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4663,7 +4663,12 @@ namespace Game int reliableAcknowledge; // 134752 int reliableSent; // 134756 int messageAcknowledge; // 134760 - char __pad4[1080]; // 134764 + int gamestateMessageNum; // 134764 + int challenge; // 134768 + usercmd_s lastUsercmd; // 134772 + int lastClientCommand; // 134812 + char lastClientCommandString[1024]; // 134816 + gentity_t* gentity; // 135840 char name[16]; // 135844 char __pad5[4]; // 135860 int lastPacketTime; // 135864 From 5c3ea03ee9abd05d2c86db8920ec884800e6fdf8 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 13 Sep 2021 10:57:06 +0200 Subject: [PATCH 7/8] Added scriptID to client_t (see 0x46108b) --- src/Game/Structs.hpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 2288861d..7aecf51e 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4220,8 +4220,6 @@ namespace Game char __pad0[0x5E0]; }; - static_assert(sizeof(netProfileInfo_t) == 0x5E0); - struct netchan_t { int outgoingSequence; @@ -4670,20 +4668,21 @@ namespace Game char lastClientCommandString[1024]; // 134816 gentity_t* gentity; // 135840 char name[16]; // 135844 - char __pad5[4]; // 135860 + char __pad4[4]; // 135860 int lastPacketTime; // 135864 int lastConnectTime; // 135868 int snapNum; // 135872 - int __pad6; // 135876 + int __pad5; // 135876 short ping; // 135880 - char __pad7[14]; // 135882 + char __pad6[14]; // 135882 int pureAuthentic; // 135896 - char __pad8[133140]; // 135900 + char __pad7[133138]; // 135900 + short scriptID; // 269038 int isBot; // 269040 int serverID; // 269044 - char __pad9[9224]; // 269048 + char __pad8[9224]; // 269048 unsigned __int64 steamID; // 278272 - char __pad10[403592]; // 278280 + char __pad9[403592]; // 278280 } client_t; #pragma pack(pop) From 4f1e68a285e44f1a34ec93e77f1504e6cc4d5fbf Mon Sep 17 00:00:00 2001 From: Diavolo Date: Mon, 13 Sep 2021 21:36:48 +0200 Subject: [PATCH 8/8] Address comments from review #1 --- src/Components/Modules/Network.cpp | 2 ++ src/Game/Structs.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 05eb60db..e4e39390 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -346,6 +346,8 @@ namespace Components { if (client->reliableAcknowledge < 0) { + Logger::Print("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"); return; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 7aecf51e..8f274438 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4220,6 +4220,8 @@ namespace Game char __pad0[0x5E0]; }; + static_assert(sizeof(netProfileInfo_t) == 0x5E0); + struct netchan_t { int outgoingSequence;