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.
This commit is contained in:
Kawe Mazidjatari 2023-04-06 00:28:58 +02:00
parent 596e827352
commit 874faea430
2 changed files with 22 additions and 0 deletions

View File

@ -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);

View File

@ -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<<FRAGMENT_BITS)
@ -33,6 +34,9 @@ inline auto v_NET_ReceiveDatagram = p_NET_ReceiveDatagram.RCast<bool (*)(int iSo
inline CMemory p_NET_SendDatagram;
inline auto v_NET_SendDatagram = p_NET_SendDatagram.RCast<int (*)(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool bEncrypted)>();
inline CMemory p_NET_Decompress;
inline auto v_NET_Decompress = p_NET_Decompress.RCast<int (*)(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)>();
inline CMemory p_NET_PrintFunc;
inline auto v_NET_PrintFunc = p_NET_PrintFunc.RCast<void(*)(const char* fmt)>();
@ -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<uintptr_t>(g_pNetAdr));
LogVarAdr("g_NetKey", reinterpret_cast<uintptr_t>(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<void* (*)(bool)>(); /*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<void (*)(netkey_t*, const char*)>(); /*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<bool (*)(int, netpacket_s*, bool)>(); /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/
v_NET_SendDatagram = p_NET_SendDatagram.RCast<int (*)(SOCKET, void*, int, netadr_t*, bool)>(); /*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<int (*)(CLZSS*, unsigned char*, unsigned char*, unsigned int)>();
v_NET_PrintFunc = p_NET_PrintFunc.RCast<void(*)(const char*)>(); /*48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48*/
}
virtual void GetVar(void) const