From 874faea430dec848902462c4dabe27df590e96cc Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:28:58 +0200 Subject: [PATCH] Add hook to CLZSS::SafeUncompress Added hook to use the SDK implementation of 'CLZSS::SafeUncompress' instead, since the one in the game executable does not check bounds on the iterator pointer. This fixes the problem of people crashing servers with malicious packets. --- r5dev/engine/net.cpp | 15 +++++++++++++++ r5dev/engine/net.h | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/r5dev/engine/net.cpp b/r5dev/engine/net.cpp index 5dc9114f..913cf6c8 100644 --- a/r5dev/engine/net.cpp +++ b/r5dev/engine/net.cpp @@ -62,6 +62,19 @@ int NET_SendDatagram(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool return result; } +//----------------------------------------------------------------------------- +// Purpose: safely decompresses the input buffer into the output buffer +// Input : *lzss - +// *pInput - +// *pOutput - +// unBufSize - +// Output : total decompressed bytes +//----------------------------------------------------------------------------- +unsigned int NET_Decompress(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize) +{ + return lzss->SafeUncompress(pInput, pOutput, unBufSize); +} + //----------------------------------------------------------------------------- // Purpose: sets the user specified encryption key // Input : svNetKey - @@ -289,6 +302,7 @@ void VNet::Attach() const { DetourAttach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram); DetourAttach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram); + DetourAttach((LPVOID*)&v_NET_Decompress, &NET_Decompress); DetourAttach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc); #ifndef DEDICATED DetourAttach((LPVOID*)&v_NET_Shutdown, &NET_Shutdown); @@ -299,6 +313,7 @@ void VNet::Detach() const { DetourDetach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram); DetourDetach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram); + DetourDetach((LPVOID*)&v_NET_Decompress, &NET_Decompress); DetourDetach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc); #ifndef DEDICATED DetourDetach((LPVOID*)&v_NET_Shutdown, &NET_Shutdown); diff --git a/r5dev/engine/net.h b/r5dev/engine/net.h index 03f736e7..0ba153b2 100644 --- a/r5dev/engine/net.h +++ b/r5dev/engine/net.h @@ -2,6 +2,7 @@ #ifndef NETCONSOLE #include "engine/net_chan.h" +#include "tier1/lzss.h" #define MAX_STREAMS 2 #define FRAGMENT_BITS 8 #define FRAGMENT_SIZE (1<(); +inline CMemory p_NET_Decompress; +inline auto v_NET_Decompress = p_NET_Decompress.RCast(); + inline CMemory p_NET_PrintFunc; inline auto v_NET_PrintFunc = p_NET_PrintFunc.RCast(); @@ -61,6 +65,7 @@ class VNet : public IDetour LogFunAdr("NET_SetKey", p_NET_SetKey.GetPtr()); LogFunAdr("NET_ReceiveDatagram", p_NET_ReceiveDatagram.GetPtr()); LogFunAdr("NET_SendDatagram", p_NET_SendDatagram.GetPtr()); + LogFunAdr("NET_Decompress", p_NET_Decompress.GetPtr()); LogFunAdr("NET_PrintFunc", p_NET_PrintFunc.GetPtr()); LogVarAdr("g_NetAdr", reinterpret_cast(g_pNetAdr)); LogVarAdr("g_NetKey", reinterpret_cast(g_pNetKey)); @@ -78,6 +83,7 @@ class VNet : public IDetour p_NET_SetKey = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8"); p_NET_ReceiveDatagram = g_GameDll.FindPatternSIMD("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB"); p_NET_SendDatagram = g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 ?? ??"); + p_NET_Decompress = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 45 33 F6"); p_NET_PrintFunc = g_GameDll.FindPatternSIMD("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48"); v_NET_Init = p_NET_Init.RCast(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC F0 01 00*/ @@ -85,6 +91,7 @@ class VNet : public IDetour v_NET_SetKey = p_NET_SetKey.RCast(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8*/ v_NET_ReceiveDatagram = p_NET_ReceiveDatagram.RCast(); /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/ v_NET_SendDatagram = p_NET_SendDatagram.RCast(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/ + v_NET_Decompress = p_NET_Decompress.RCast(); v_NET_PrintFunc = p_NET_PrintFunc.RCast(); /*48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48*/ } virtual void GetVar(void) const