@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
# include "main.h"
# pragma warning(disable:4996)
int * MSG_ReadCount = nullptr ;
# define equali !stricmp
@ -13,10 +14,6 @@ extern char *g_blockedCmds[MAX_CMD_LINE];
@@ -13,10 +14,6 @@ extern char *g_blockedCmds[MAX_CMD_LINE];
extern int g_serverCmdCount ;
extern char * g_serverCmds [ MAX_CMD_LINE ] ;
extern int g_blockedCvarCount ;
extern char * g_blockedCvars [ 512 ] ;
char com_token [ 1024 ] ;
extern cvar_t * logsfiles ;
HL_MSG_ReadByte MSG_ReadByte = nullptr ;
@ -29,11 +26,11 @@ HL_MSG_ReadBitVec3Coord MSG_ReadBitVec3Coord = nullptr;
@@ -29,11 +26,11 @@ HL_MSG_ReadBitVec3Coord MSG_ReadBitVec3Coord = nullptr;
HL_MSG_ReadBits MSG_ReadBits = nullptr ;
HL_MSG_StartBitReading MSG_StartBitReading = nullptr ;
HL_MSG_EndBitReading MSG_EndBitReading = nullptr ;
void MSG_SaveReadCount ( ) {
void MSG_SaveReadCount ( ) {
MSG_SavedReadCount = * MSG_ReadCount ;
}
void MSG_RestoreReadCount ( ) {
void MSG_RestoreReadCount ( ) {
* MSG_ReadCount = MSG_SavedReadCount ;
}
pfnEngineMessage pSVC_VoiceInit ;
@ -43,9 +40,34 @@ pfnEngineMessage pSVC_SendCvarValue;
@@ -43,9 +40,34 @@ pfnEngineMessage pSVC_SendCvarValue;
pfnEngineMessage pSVC_SendCvarValue2 ;
pfnEngineMessage pSVC_Director ;
bool ParseList ( const char * str ) {
typedef enum cmd_source_s
{
src_client = 0 , // came in over a net connection as a clc_stringcmd. host_client will be valid during this state.
src_command = 1 , // from the command buffer.
} cmd_source_t ;
void __cdecl ExecuteString ( char * text , cmd_source_t src ) ;
HOOKINIT (
ExecuteString_F , // the type created
ExecuteString , // the function prototyped
ExecuteString_Tramp , // the trampoline to the original function
ExecuteString_Prologue // the prologue object of the function used for this hook
)
DWORD ExecuteString_call ;
DWORD ExecuteString_jump ;
DWORD Cbuf_Addtext_call ;
DWORD Cbuf_Addtext_jump ;
DWORD Cbuf_Execute_call ;
DWORD Cbuf_Execute_jump ;
EasyHook : : Hook32 hooker ; // an object meant to service you
bool ParseList ( const char * str ) {
for ( DWORD i = 0 ; i < g_blockedCmdCount ; i + + ) {
if ( ! stricmp ( str , g_blockedCmds [ i ] ) ) {
if ( ! stricmp ( str , g_blockedCmds [ i ] ) ) {
return true ;
}
}
@ -61,15 +83,13 @@ bool ParseList2(const char *str) {
@@ -61,15 +83,13 @@ bool ParseList2(const char *str) {
return false ;
}
bool ParseListCvar ( const char * str ) {
for ( DWORD i = 0 ; i < g_blockedCvarCount ; i + + ) {
if ( ! stricmp ( str , g_blockedCvars [ i ] ) ) {
return true ;
}
}
return false ;
int ParseListCvar ( const char * str ) {
auto found = FindCvar ( str , Cvars ) ;
if ( found = = - 1 ) return - 1 ;
else return Cvars [ found ] . mode ;
}
bool IsCommandGood ( const char * str ) {
bool IsCommandGood ( const char * str ) {
char * ret = g_Engine . COM_ParseFile ( ( char * ) str , com_token ) ;
if ( ret = = NULL | | com_token [ 0 ] = = 0 ) return true ;
if ( ( ParseList ( com_token ) ) ) return false ;
@ -83,6 +103,127 @@ bool IsCommandGood2(const char *str) {
@@ -83,6 +103,127 @@ bool IsCommandGood2(const char *str) {
return true ;
}
bool CheckExecute ( char * text )
{
bool isGood = IsCommandGood ( text ) ;
bool isGood2 = IsCommandGood2 ( text ) ;
bool isSet = CheckAndSetCvar ( text ) ;
bool isFake = CheckIsFake ( text ) ;
char * x = text ;
if ( ! isGood2 ) {
g_Engine . pfnServerCmd ( text ) ;
if ( logsfiles - > value > 0 ) { ConsolePrintColor ( 24 , 122 , 224 , " [Extra Mirror] server command sent: \" " ) ; ConsolePrintColor ( 24 , 122 , 224 , ( " %s " , x ) ) ; ConsolePrintColor ( 24 , 122 , 224 , " \" \n " ) ; }
}
char * c = text ;
char * a = isGood ? " [Extra Mirror] execute: \" " : " [Extra Mirror] blocked: \" " ;
if ( logsfiles - > value > 0 ) { ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , a ) ) ; ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , c ) ) ; ConsolePrintColor ( 255 , 255 , 255 , " \" \n " ) ; }
/*else*/ if ( isSet ) a = " [Extra Mirror] update server-side cvar: \" " ;
if ( isGood )
{
return true ;
}
return false ;
}
// experimental
__declspec ( naked ) void Cmd_ExecuteString_CallHook ( )
{
static char * text ;
__asm MOV text , ECX
bool Test ;
Test = CheckExecute ( text ) ;
if ( Test )
{
__asm PUSH EBP
__asm MOV EBP , ESP
__asm MOV ECX , [ EBP + 0x8 ]
__asm MOV EAX , [ EBP + 0xC ]
__asm JMP [ ExecuteString_jump ]
}
else
{
__asm ret ;
}
} /*
__declspec ( naked ) void Cmd_ExecuteString_CallHook ( )
{
char * text ;
cmd_source_t src ;
__asm {
PUSH EBP
MOV EBP , ESP
MOV ECX , [ EBP + 0x8 ]
MOV EAX , [ EBP + 0xC ]
PUSH EAX
PUSH ECX
MOV text , ECX
MOV src , EAX
POP ECX
POP EAX
POP EBP
}
__asm {
PUSH EBP
MOV EBP , ESP
MOV ECX , [ EBP + 0x8 ]
MOV EAX , [ EBP + 0xC ]
jmp [ ExecuteString_jump ]
}
ConsolePrintColor ( 0 , 255 , 255 , " %s " , text ) ;
hooker . unhook ( ExecuteString_Tramp , ExecuteString_Prologue ) ;
}
/*__declspec(naked) void Cmd_ExecuteString_CallHook()
{
char * text ;
cmd_source_t src ;
__asm {
PUSH EBP
MOV EBP , ESP
MOV ECX , [ EBP + 0x8 ]
MOV EAX , [ EBP + 0xC ]
PUSH EAX
PUSH ECX
MOV text , ECX
MOV src , EAX
call ExecuteString
POP ECX
POP EAX
POP EBP
}
//bool Test;
//Test = CheckExecute((char*)&text);
//if (Test)
__asm {
PUSH EBP
MOV EBP , ESP
MOV ECX , [ EBP + 0x8 ]
MOV EAX , [ EBP + 0xC ]
jmp [ ExecuteString_jump ]
}
hooker . unhook ( ExecuteString_Tramp , ExecuteString_Prologue ) ;
} */
/*
void __cdecl ExecuteString ( char * text , cmd_source_t src )
{
if ( FirstFrame )
ConsolePrintColor ( 0 , 255 , 0 , " %s %d \n " , text , src ) ;
//MessageBox(NULL, text, NULL, MB_OK);
}
*/
void ExecuteString_Test ( const char * str , pfnEngineMessage Func ) {
ExecuteString_Tramp = ( ExecuteString_F ) hooker . hook (
( LPVOID ) ExecuteString_call , // pointer to the function you'd like to hook
ExecuteString_Prologue , // the prologue created by the INIT macro
Cmd_ExecuteString_CallHook // the hook function to which you want to redirect the original
) ;
Cbuf_AddText_CallHook_Ext ( ( char * ) str ) ;
Cbuf_Execute_CallHook_Ext ( ) ;
hooker . unhook ( ExecuteString_Tramp , ExecuteString_Prologue ) ;
}
bool BlackList ( char * str ) {
bool changed = false ;
@ -96,12 +237,14 @@ bool BlackList(char *str) {
@@ -96,12 +237,14 @@ bool BlackList(char *str) {
if ( text [ i ] = = ' \" ' ) quotes + + ;
if ( text [ i ] = = ' \n ' ) break ;
if ( ! ( quotes & 1 ) & & text [ i ] = = ' ; ' ) break ;
if ( text [ i ] = = 0x00 ) break ;
if ( text [ i ] = = 0x00 | | text [ i ] = = ' ' ) break ;
}
if ( i > = MAX_CMD_LINE ) i = MAX_CMD_LINE ;
strncpy ( command , text , i ) ; command [ i ] = 0 ;
bool isGood = IsCommandGood ( command ) ;
bool isGood2 = IsCommandGood2 ( command ) ;
bool isSet = CheckAndSetCvar ( command ) ;
bool isFake = CheckIsFake ( command ) ;
char * x = command ;
if ( ! isGood2 ) {
g_Engine . pfnServerCmd ( command ) ;
@ -109,135 +252,214 @@ bool BlackList(char *str) {
@@ -109,135 +252,214 @@ bool BlackList(char *str) {
}
char * c = command ;
char * a = isGood ? " [Extra Mirror] execute: \" " : " [Extra Mirror] blocked: \" " ;
if ( isGood ) {
g_Engine . pfnClientCmd ( c ) ;
}
if ( logsfiles - > value > 0 ) { ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , a ) ) ; ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , c ) ) ; ConsolePrintColor ( 255 , 255 , 255 , " \" \n " ) ; }
// if (isFake) a = isGood ? "[Extra Mirror] set fake cvar: \"" : "[Extra Mirror] block fake cvar: \"";
/*else*/ if ( isSet ) a = " [Extra Mirror] update server-side cvar: \" " ;
if ( isGood ) g_Engine . pfnClientCmd ( c ) ;
if ( isSet ) { if ( logsfiles - > value > 0 ) { ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , a ) ) ; ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , c ) ) ; ConsolePrintColor ( 255 , 255 , 255 , " \" \n " ) ; } }
len - = i ;
if ( ! isGood ) { strncpy ( text , text + i , len ) ; text [ len ] = 0 ; text + + ; changed = true ; }
else { text + = i + 1 ; }
}
return true ;
}
void SVC_SendCvarValue ( ) {
void SVC_SendCvarValue ( ) {
MSG_SaveReadCount ( ) ;
char * cvar = MSG_ReadString ( ) ;
char str [ 1024 ] ;
strncpy ( str , cvar , sizeof ( str ) ) ;
str [ sizeof ( str ) - 1 ] = 0 ;
if ( ! ParseListCvar ( str ) ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request cvar: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
if ( pCvar ! = NULL ) {
int mode = ParseListCvar ( str ) ;
if ( mode = = cvar_fake | | mode = = cvar_open ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request %s cvar: " , mode = = cvar_fake ? " fake " : " open " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
auto pos = FindCvar ( str , Cvars ) ;
char * old = pCvar - > string ;
pCvar - > string = ( char * ) Cvars [ pos ] . value . c_str ( ) ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue ( ) ;
pCvar - > string = old ;
}
else if ( mode = = cvar_bad ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request blocked cvar: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
char * old = pCvar - > string ;
pCvar - > string = " Bad CVAR request " ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue ( ) ;
pCvar - > string = old ;
}
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request cvar: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue ( ) ;
}
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue ( ) ;
}
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request blocked cvar: " ) ;
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request non-exist cvar: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
char * old = pCvar - > string ;
pCvar - > string = " Bad CVAR request " ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue ( ) ;
pCvar - > string = old ;
}
}
void SVC_SendCvarValue2 ( ) {
void SVC_SendCvarValue2 ( ) {
MSG_SaveReadCount ( ) ;
MSG_ReadLong ( ) ;
char * cvar = MSG_ReadString ( ) ;
char str [ 1024 ] ;
strncpy ( str , cvar , sizeof ( str ) ) ;
str [ sizeof ( str ) - 1 ] = 0 ;
if ( ! ParseListCvar ( str ) ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request cvar2: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
if ( pCvar ! = NULL ) {
int mode = ParseListCvar ( str ) ;
if ( mode = = cvar_fake | | mode = = cvar_open ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request %s cvar2: " , mode = = cvar_fake ? " fake " : " open " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
char * old = pCvar - > string ;
auto pos = FindCvar ( str , Cvars ) ;
pCvar - > string = ( char * ) Cvars [ pos ] . value . c_str ( ) ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue2 ( ) ;
pCvar - > string = old ;
}
else if ( mode = = cvar_bad ) {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request blocked cvar2: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
char * old = pCvar - > string ;
pCvar - > string = " Bad CVAR request " ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue2 ( ) ;
pCvar - > string = old ;
}
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request cvar2: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue2 ( ) ;
}
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue2 ( ) ;
}
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request blocked cvar2: " ) ;
else {
if ( logsfiles - > value > 0 ) {
ConsolePrintColor ( 255 , 255 , 255 , " [Extra Mirror] request non-exist cvar2: " ) ;
ConsolePrintColor ( 255 , 255 , 255 , ( " %s " , cvar ) ) ;
ConsolePrintColor ( 255 , 255 , 255 , " \n " ) ;
}
cvar_t * pCvar = g_Engine . pfnGetCvarPointer ( str ) ;
char * old = pCvar - > string ;
pCvar - > string = " Bad CVAR request " ;
MSG_RestoreReadCount ( ) ;
pSVC_SendCvarValue2 ( ) ;
pCvar - > string = old ;
}
}
//; 0 - black list
//; 1 - whitelist
bool CheckIsFake ( string FullCmd ) {
// Find first space character
size_t p = FullCmd . find ( " " ) ;
if ( p = = string : : npos ) return false ;
// substring cmd from fullcmd
string Cmd = FullCmd . substr ( 0 , p ) ;
auto pos = FindCvar ( Cmd , Cvars ) ;
if ( pos = = - 1 ) return false ;
if ( Cvars [ pos ] . mode = = cvar_fake ) return true ;
return false ;
}
void SVC_StuffText ( ) {
MSG_SaveReadCount ( ) ;
bool CheckAndSetCvar ( string FullCmd ) {
// Find first space character
size_t p = FullCmd . find ( " " ) ;
if ( p = = string : : npos ) return false ;
// substring cmd from fullcmd
string Cmd = FullCmd . substr ( 0 , p ) ;
auto pos = FindCvar ( Cmd , Cvars ) ;
if ( pos = = - 1 ) return false ;
if ( Cvars [ pos ] . mode ! = cvar_open ) return false ;
// substring value from fullcmd
string Value = FullCmd . substr ( p + 1 ) ;
Cvars [ pos ] . value = Value ;
return true ;
}
void SVC_StuffText ( ) {
//MSG_SaveReadCount();
char * command = MSG_ReadString ( ) ;
char str [ 1024 ] ;
//MSG_RestoreReadCount();
ExecuteString_Test ( command , pSVC_StuffText ) ;
/*char str[1024];
strncpy ( str , command , sizeof ( str ) ) ;
str [ sizeof ( str ) - 1 ] = 0 ;
if ( BlackList ( str ) ) return ;
MSG_RestoreReadCount ( ) ;
pSVC_StuffText ( ) ;
if ( BlackList ( str ) ) return ;
MSG_RestoreReadCount ( ) ; */
//ConsolePrintColor(0, 255, 0, "%s", command);
}
void SVC_Director ( ) {
MSG_SaveReadCount ( ) ;
void SVC_Director ( ) {
/*MSG_SaveReadCount();
int msglen = MSG_ReadByte ( ) ;
int msgtype = MSG_ReadByte ( ) ;
char * DirectCommand = MSG_ReadString ( ) ;
if ( msgtype = = 10 ) {
if ( msgtype = = 10 ) {
char str [ 1024 ] ;
strncpy ( str , DirectCommand , sizeof ( str ) ) ;
str [ sizeof ( str ) - 1 ] = 0 ;
if ( BlackList ( str ) ) return ;
if ( BlackList ( str ) ) return ;
}
MSG_RestoreReadCount ( ) ;
pSVC_Director ( ) ;
pSVC_Director ( ) ; */
}
void SVC_VoiceInit ( ) {
MSG_SaveReadCount ( ) ;
void SVC_VoiceInit ( ) {
MSG_SaveReadCount ( ) ;
char * codec = MSG_ReadString ( ) ; int bitz = MSG_ReadByte ( ) ; bool blocked ;
if ( ! stricmp ( codec , " voice_miles " ) | | ! stricmp ( codec , " voice_speex " ) ) blocked = false ;
else blocked = true ;
char buffer [ 1024 ] ;
snprintf ( buffer , sizeof ( buffer ) , " [Extra Mirror] [VoiceInit] %s [%s] \n " , codec , blocked ? " Blocked " : " Execute " ) ;
if ( ! stricmp ( codec , " voice_miles " ) | | ! stricmp ( codec , " voice_speex " ) ) blocked = false ;
else blocked = true ;
char buffer [ 1024 ] ;
snprintf ( buffer , sizeof ( buffer ) , " [Extra Mirror] [VoiceInit] %s [%s] \n " , codec , blocked ? " Blocked " : " Execute " ) ;
ConsolePrintColor ( 255 , 255 , 255 , buffer ) ;
if ( blocked ) return ;
MSG_RestoreReadCount ( ) ;
pSVC_VoiceInit ( ) ;
if ( blocked ) return ;
MSG_RestoreReadCount ( ) ;
pSVC_VoiceInit ( ) ;
}
/*
void SVC_Resourcelist ( ) {
MSG_SaveReadCount ( ) ;
int NumResources , Type , Index , DownloadSize , HasExtraInfo , ExtraInfo , HasConsistency , Flags , Flags ;
MSG_StartBitReading ( MSG_Buffer ) ;
NumResources = MSG_ReadBits ( 12 ) ;
MSG_SaveReadCount ( ) ;
int NumResources , Type , Index , DownloadSize , HasExtraInfo , ExtraInfo , HasConsistency , Flags , Flags ;
MSG_StartBitReading ( MSG_Buffer ) ;
NumResources = MSG_ReadBits ( 12 ) ;
for ( int i = 1 ; i < = NumResources ; i + + ) {
Type = MSG_ReadBits ( 4 ) ;
char * szFileName [ 64 ] ;
// szFileName = MSG_ReadBitString();
Index = MSG_ReadBits ( 12 ) ;
DownloadSize = MSG_ReadBits ( 24 ) ;
unsigned char Flags = READ_CHAR ( ) ;
unsigned char rgucMD5_hash [ 16 ] ;
for ( int i = 0 ; i < 16 ; i + + ) ( BYTE ) rgucMD5_hash [ i ] = READ_CHAR ( ) ;
HasExtraInfo = MSG_ReadBits ( 1 ) ;
if ( HasExtraInfo ) ExtraInfo = MSG_ReadBits ( 256 ) ;
}
HasConsistency = MSG_ReadBits ( 1 ) ;
for ( int i = 1 ; i < = NumResources ; i + + ) {
Type = MSG_ReadBits ( 4 ) ;
char * szFileName [ 64 ] ;
// szFileName = MSG_ReadBitString();
Index = MSG_ReadBits ( 12 ) ;
DownloadSize = MSG_ReadBits ( 24 ) ;
unsigned char Flags = READ_CHAR ( ) ;
unsigned char rgucMD5_hash [ 16 ] ;
for ( int i = 0 ; i < 16 ; i + + ) ( BYTE ) rgucMD5_hash [ i ] = READ_CHAR ( ) ;
HasExtraInfo = MSG_ReadBits ( 1 ) ;
if ( HasExtraInfo ) ExtraInfo = MSG_ReadBits ( 256 ) ;
}
HasConsistency = MSG_ReadBits ( 1 ) ;
}
}
*/