Protection System For Counter-Strike 1.6
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

465 lines
14 KiB

#include "main.h"
#pragma warning(disable:4996)
int* MSG_ReadCount = nullptr;
#define equali !stricmp
int* MSG_CurrentSize = nullptr;
int* MSG_BadRead = nullptr;
int MSG_SavedReadCount = 0;
sizebuf_t* MSG_Buffer = nullptr;
#define MAX_CMD_LINE 2048
extern int g_blockedCmdCount;
extern char *g_blockedCmds[MAX_CMD_LINE];
extern int g_serverCmdCount;
extern char *g_serverCmds[MAX_CMD_LINE];
char com_token[1024];
extern cvar_t *logsfiles;
HL_MSG_ReadByte MSG_ReadByte = nullptr;
HL_MSG_ReadShort MSG_ReadShort = nullptr;
HL_MSG_ReadLong MSG_ReadLong = nullptr;
HL_MSG_ReadFloat MSG_ReadFloat = nullptr;
HL_MSG_ReadString MSG_ReadString = nullptr;
HL_MSG_ReadCoord MSG_ReadCoord = nullptr;
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() {
MSG_SavedReadCount = *MSG_ReadCount;
}
void MSG_RestoreReadCount() {
*MSG_ReadCount = MSG_SavedReadCount;
}
pfnEngineMessage pSVC_VoiceInit;
pfnEngineMessage pSVC_StuffText;
pfnEngineMessage pSVC_SendCvarValue;
pfnEngineMessage pSVC_SendCvarValue2;
pfnEngineMessage pSVC_Director;
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])) {
return true;
}
}
return false;
}//:D more shit code, in reborn no
bool ParseList2(const char *str) {
for (DWORD i = 0; i < g_serverCmdCount; i++) {
if (!stricmp(str, g_serverCmds[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) {
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;
return true;
}
bool IsCommandGood2(const char *str) {
char *ret = g_Engine.COM_ParseFile((char *)str, com_token);
if (ret == NULL || com_token[0] == 0)return true;
if ((ParseList2(com_token)))return false;
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;
char *text = str;
char command[MAX_CMD_LINE];
int i, quotes;
int len = strlen(str);
while (text[0] != 0) {
quotes = 0;
for (i = 0; i < len; i++) {
if (text[i] == '\"') quotes++;
if (text[i] == '\n')break;
if (!(quotes & 1) && text[i] == ';')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);
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 = command;
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"); }
// 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() {
MSG_SaveReadCount();
char* cvar = MSG_ReadString();
char str[1024];
strncpy(str, cvar, sizeof(str));
str[sizeof(str) - 1] = 0;
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();
}
}
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");
}
MSG_RestoreReadCount();
pSVC_SendCvarValue();
}
}
void SVC_SendCvarValue2() {
MSG_SaveReadCount();
MSG_ReadLong();
char* cvar = MSG_ReadString();
char str[1024];
strncpy(str, cvar, sizeof(str));
str[sizeof(str) - 1] = 0;
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();
}
}
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");
}
MSG_RestoreReadCount();
pSVC_SendCvarValue2();
}
}
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;
}
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();
//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();*/
//ConsolePrintColor(0, 255, 0, "%s", command);
}
void SVC_Director() {
/*MSG_SaveReadCount();
int msglen = MSG_ReadByte();
int msgtype = MSG_ReadByte();
char* DirectCommand = MSG_ReadString();
if (msgtype == 10) {
char str[1024];
strncpy(str, DirectCommand, sizeof(str));
str[sizeof(str) - 1] = 0;
if (BlackList(str))return;
}
MSG_RestoreReadCount();
pSVC_Director();*/
}
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");
ConsolePrintColor(255, 255, 255, buffer);
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);
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);
}
*/