Prevent invalid packet flooding (#885)

* Workaround invalid packet flooding

* formatting or something

---------

Co-authored-by: Will <39478251+VITALISED@users.noreply.github.com>
Co-authored-by: Allusive <154700875+AllusiveWheat@users.noreply.github.com>
This commit is contained in:
Will 2025-12-28 03:08:02 +11:00 committed by GitHub
parent 44755cd2da
commit f8c3371a1e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -11,10 +11,12 @@ AUTOHOOK_INIT()
ConVar* Cvar_ns_exploitfixes_log;
ConVar* Cvar_ns_should_log_all_clientcommands;
ConVar* Cvar_ns_recvfrom_per_frame_limit;
ConVar* Cvar_sv_cheats;
int* g_ExecutionMarkerCount;
int* net_error;
#define BLOCKED_INFO(s) \
( \
@ -32,7 +34,7 @@ int* g_ExecutionMarkerCount;
// block bad netmessages
// Servers can literally request a screenshot from any client, yeah no
// clang-format off
AUTOHOOK(CLC_Screenshot_WriteToBuffer, engine.dll + 0x22AF20,
AUTOHOOK(CLC_Screenshot_WriteToBuffer, engine.dll + 0x22AF20,
bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 57 48 83 EC 20 8B 42 10
// clang-format on
{
@ -42,7 +44,7 @@ bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 57 48 83 EC 20
}
// clang-format off
AUTOHOOK(CLC_Screenshot_ReadFromBuffer, engine.dll + 0x221F00,
AUTOHOOK(CLC_Screenshot_ReadFromBuffer, engine.dll + 0x221F00,
bool, __fastcall, (void* thisptr, void* buffer)) // 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B DA 48 8B 52 38
// clang-format on
{
@ -445,10 +447,35 @@ bool, __fastcall, (void* a1))
return CL_CopyExistingEntity(a1);
}
// Clients can cause NET_ReceiveDatagram to stop listening each frame by sending an invalid LZSS packet. (see engine.dll+0x21B735)
// This doesn't outright solve the problem but you'd basically need to be DDoSing the server to achieve the same effect.
// Pasted from R1Delta: (https://github.com/r1delta/r1delta/blob/f04cc67e6247c5e15633b95f84fc69eca7252dc6/engine/security_fixes.cpp#L811)
// (thanks wanderer)
// clang-format off
AUTOHOOK(NET_ReceiveDatagram, engine.dll + 0x21B520, bool, __fastcall, (int sock, netpacket_t* packet, bool encrypted))
// clang-format on
{
for (int i = Cvar_ns_recvfrom_per_frame_limit->GetInt(); i > 0; i--)
{
if (net_error)
*net_error = 0;
if (NET_ReceiveDatagram(sock, packet, encrypted))
return true;
if (net_error && *net_error)
break;
}
return false;
}
ON_DLL_LOAD("engine.dll", EngineExploitFixes, (CModule module))
{
AUTOHOOK_DISPATCH_MODULE(engine.dll)
g_ExecutionMarkerCount = module.Offset(0x130DE8F0).RCast<int*>();
net_error = module.Offset(0x13FA2DD0).RCast<int*>();
// allow client/ui to run clientcommands despite restricting servercommands
module.Offset(0x4FB65).Patch("EB 11");
module.Offset(0x4FBAC).Patch("EB 16");
@ -498,6 +525,8 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerExploitFixes, ConVar, (CModule module))
new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something");
Cvar_ns_should_log_all_clientcommands =
new ConVar("ns_should_log_all_clientcommands", "0", FCVAR_NONE, "Whether to log all clientcommands");
Cvar_ns_recvfrom_per_frame_limit =
new ConVar("ns_recvfrom_per_frame_limit", "1000", FCVAR_GAMEDLL, "Maximum number of recvfrom calls to process per frame");
Cvar_sv_cheats = g_pCVar->FindVar("sv_cheats");
}