From f5c5b7b2c84ade9619f631a0e2a68e44fef94053 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 7 Oct 2024 18:46:55 +0300 Subject: [PATCH] engine: common: add buffer munge functions --- engine/common/common.h | 10 +++ engine/common/munge.c | 161 +++++++++++++++++++++++++++++++++++++++++ engine/common/tests.h | 4 +- 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 engine/common/munge.c diff --git a/engine/common/common.h b/engine/common/common.h index 10dea4d1..56723904 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -835,6 +835,16 @@ void NET_MasterClear( void ); void NET_MasterShutdown( void ); qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat ); +// +// munge.c +// +void COM_Munge( byte *data, size_t len, int seq ); +void COM_UnMunge( byte *data, size_t len, int seq ); +void COM_Munge2( byte *data, size_t len, int seq ); +void COM_UnMunge2( byte *data, size_t len, int seq ); +void COM_Munge3( byte *data, size_t len, int seq ); +void COM_UnMunge3( byte *data, size_t len, int seq ); + // // sounds.c // diff --git a/engine/common/munge.c b/engine/common/munge.c new file mode 100644 index 00000000..9dc86f34 --- /dev/null +++ b/engine/common/munge.c @@ -0,0 +1,161 @@ +/* +munge.c - protocol mangling for GoldSrc +Copyright (C) ReHLDS developers +Copyright (C) 2023 Alibek Omarov + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ +#include "common.h" + +static const byte mungify_table[] = +{ + 0x7A, 0x64, 0x05, 0xF1, 0x1B, 0x9B, 0xA0, 0xB5, + 0xCA, 0xED, 0x61, 0x0D, 0x4A, 0xDF, 0x8E, 0xC7, +}; + +static const byte mungify_table2[] = +{ + 0x05, 0x61, 0x7A, 0xED, 0x1B, 0xCA, 0x0D, 0x9B, + 0x4A, 0xF1, 0x64, 0xC7, 0xB5, 0x8E, 0xDF, 0xA0, +}; + +static const byte mungify_table3[] = +{ + 0x20, 0x07, 0x13, 0x61, 0x03, 0x45, 0x17, 0x72, + 0x0A, 0x2D, 0x48, 0x0C, 0x4A, 0x12, 0xA9, 0xB5, +}; + +static int COM_SwapLong( int c ) +{ + return ((( c >> 0 ) & 0xFF) << 24 ) + + ((( c >> 8 ) & 0xFF) << 16 ) + + ((( c >> 16 ) & 0xFF) << 8 ) + + ((( c >> 24 ) & 0xFF) << 0 ); +} + +static void COM_GenericMunge( byte *data, const size_t len, const int seq, const byte *table, const qboolean reverse ) +{ + const size_t mungelen = len / 4; + int i; + + for( i = 0; i < mungelen; i++ ) + { + uint *pc, c; + byte *p; + int j; + + pc = (uint *)&data[i * 4]; + c = *pc; + c ^= seq; + if( !reverse ) + c = COM_SwapLong( c ); + + p = (byte *)&c; + for( j = 0; j < 4; j++ ) + *p++ ^= (0xa5 | (j << j) | j | table[(i + j) & 0x0f]); + + if( reverse ) + c = COM_SwapLong( c ); + c ^= ~seq; + *pc = c; + } +} + +// Anti-proxy/aimbot obfuscation code +// COM_UnMunge should reversably fixup the data +void COM_Munge( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table, false ); +} + +void COM_UnMunge( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table, true ); +} + +void COM_Munge2( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table2, false ); +} + +void COM_UnMunge2( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table2, true ); +} + +void COM_Munge3( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table3, false ); +} + +void COM_UnMunge3( byte *data, size_t len, int seq ) +{ + COM_GenericMunge( data, len, seq, mungify_table3, true ); +} + +#if XASH_ENGINE_TESTS +#include "tests.h" + +void Test_RunMunge( void ) +{ + const char *msg = "0123456789qwertyuiopasdfghjklzxcvbnmaa"; + const char *expected[][3] = + { + { + "\x33\x2a\x61\x30\x2d\x6e\x35\x74\x2d\x79\x79\x78\x73\x34\x32\x25\x30\x2f\x39\x35\x26\x3c\x33\x61\x31\x22\x78\x67\x29\x68\x6a\x6c\x7d\x7e\x72\x36\x61\x61", + "\x69\x2a\x31\x30\x2d\x36\x25\x74\x77\x61\x79\x38\x6b\x34\x62\x25\x30\x7f\x39\x35\x76\x34\x33\x61\x39\x2a\x78\x67\x23\x68\x7a\x6c\x7d\x66\x72\x76\x61\x61", + "\x69\x6a\x71\x30\x6f\x7e\x25\x74\x3f\x69\x69\x38\x63\x2c\x62\x25\x28\x77\x29\x75\x7c\x2c\x73\x21\x23\x62\x38\x27\x6b\x28\x2a\x6c\x3d\x3e\x72\x36\x61\x61", + }, { + "\x32\x2a\x61\x31\x2c\x6e\x35\x75\x2c\x79\x79\x79\x72\x34\x32\x24\x31\x2f\x39\x34\x27\x3c\x33\x60\x30\x22\x78\x66\x28\x68\x6a\x6d\x7c\x7e\x72\x37\x61\x61", + "\x68\x2a\x31\x31\x2c\x36\x25\x75\x76\x61\x79\x39\x6a\x34\x62\x24\x31\x7f\x39\x34\x77\x34\x33\x60\x38\x2a\x78\x66\x22\x68\x7a\x6d\x7c\x66\x72\x77\x61\x61", + "\x68\x6a\x71\x31\x6e\x7e\x25\x75\x3e\x69\x69\x39\x62\x2c\x62\x24\x29\x77\x29\x74\x7d\x2c\x73\x20\x22\x62\x38\x26\x6a\x28\x2a\x6d\x3c\x3e\x72\x37\x61\x61", + } + }; + string buf; + size_t msglen = Q_strlen( msg ) + 1; + int i; + + Q_strncpy( buf, msg, msglen ); + + for( i = 0; i < 0xFF; i++ ) + { + COM_Munge( buf, msglen, i ); + if( i < sizeof( expected ) / sizeof( expected[0] )) + { + //for( int j = 0; j < msglen; j++ ) + // printf( "\\x%02x", buf[j] ); + //printf( "\n" ); + TASSERT( !memcmp( buf, expected[i][0], msglen )); + } + COM_UnMunge( buf, msglen, i ); + + TASSERT( !Q_strcmp( buf, msg )); + + COM_Munge2( buf, msglen, i ); + if( i < sizeof( expected ) / sizeof( expected[0] )) + { + TASSERT( !memcmp( buf, expected[i][1], msglen )); + } + COM_UnMunge2( buf, msglen, i ); + + TASSERT( !Q_strcmp( buf, msg )); + + COM_Munge3( buf, msglen, i ); + if( i < sizeof( expected ) / sizeof( expected[0] )) + { + TASSERT( !memcmp( buf, expected[i][2], msglen )); + } + COM_UnMunge3( buf, msglen, i ); + + TASSERT( !Q_strcmp( buf, msg )); + } +} +#endif diff --git a/engine/common/tests.h b/engine/common/tests.h index 1cc5d39c..c80e8858 100644 --- a/engine/common/tests.h +++ b/engine/common/tests.h @@ -41,6 +41,7 @@ void Test_RunIPFilter( void ); void Test_RunGamma( void ); void Test_RunDelta( void ); void Test_RunBuffer( void ); +void Test_RunMunge( void ); #define TEST_LIST_0 \ Test_RunLibCommon(); \ @@ -49,7 +50,8 @@ void Test_RunBuffer( void ); Test_RunCvar(); \ Test_RunIPFilter(); \ Test_RunBuffer(); \ - Test_RunDelta(); + Test_RunDelta(); \ + Test_RunMunge(); #define TEST_LIST_0_CLIENT \ Test_RunCon(); \