diff --git a/MiniBase/MiniBase.vcxproj b/MiniBase/MiniBase.vcxproj
index e8fd6d9..bb62ef1 100644
--- a/MiniBase/MiniBase.vcxproj
+++ b/MiniBase/MiniBase.vcxproj
@@ -30,7 +30,7 @@
DynamicLibrary
true
v140_xp
- Unicode
+ MultiByte
DynamicLibrary
@@ -70,6 +70,7 @@
true
+ .mix
true
@@ -190,6 +191,5 @@
-
-
+
\ No newline at end of file
diff --git a/MiniBase/client.cpp b/MiniBase/client.cpp
index 0368c62..131c41c 100644
--- a/MiniBase/client.cpp
+++ b/MiniBase/client.cpp
@@ -18,9 +18,11 @@ cvar_t *random;
map g_modelsHashMap;
cvar_t *logsfiles;
cvar_t *events_block;
-
cvar_t *ex_thud;
cvar_t *motd_block;
+
+vector Cvars;
+
void HookEngineMessages(){
pEngineMsgBase = (PEngineMsg)offset.FindSVCMessages();
pSVC_StuffText = HookEngineMsg("svc_stufftext", SVC_StuffText);
@@ -31,8 +33,14 @@ void HookEngineMessages(){
// pSVC_Resourcelist = HookEngineMsg("svc_resourcelist", SVC_Resourcelist);
}
-void ConsolePrintColor(BYTE R, BYTE G, BYTE B, char* string){
- TColor24 DefaultColor;PColor24 Ptr;Ptr = Console_TextColor;DefaultColor = *Ptr;Ptr->R = R;Ptr->G = G;Ptr->B = B;g_Engine.Con_Printf("%s", string);*Ptr = DefaultColor;
+
+void ConsolePrintColor(BYTE R, BYTE G, BYTE B, const char *fmt, ...){
+ va_list va_alist;
+ char buf[256];
+ va_start(va_alist, fmt);
+ _vsnprintf(buf, sizeof(buf), fmt, va_alist);
+ va_end(va_alist);
+ TColor24 DefaultColor; PColor24 Ptr; Ptr = Console_TextColor; DefaultColor = *Ptr; Ptr->R = R; Ptr->G = G; Ptr->B = B; g_Engine.Con_Printf(buf); *Ptr = DefaultColor;
}
void models(){
@@ -47,7 +55,10 @@ void models(){
}
void Credits(){
ConsolePrintColor(255, 255, 255, "-- Thank's to");ConsolePrintColor(0, 255, 0, " [2010] Team\n");ConsolePrintColor(255, 255, 255, "-- Thank's to");
- ConsolePrintColor(0, 255, 0, " madotsuki-team < *\n");ConsolePrintColor(255, 255, 255, "-- Thank's to ");ConsolePrintColor(0, 255, 0, "or_75\n"); ConsolePrintColor(255, 255, 255, "-- Thank's to"); ConsolePrintColor(0, 255, 0, "Juice\n");
+ ConsolePrintColor(0, 255, 0, " madotsuki-team < *\n");ConsolePrintColor(255, 255, 255, "-- Thank's to ");ConsolePrintColor(0, 255, 0, "or_75\n");
+ ConsolePrintColor(255, 255, 255, "-- Thank's to "); ConsolePrintColor(0, 255, 0, "Juice\n");
+ ConsolePrintColor(255, 255, 255, "-- Thank's to "); ConsolePrintColor(0, 255, 0, "Admrfsh\n");
+ ConsolePrintColor(255, 255, 255, "-- Thank's to "); ConsolePrintColor(0, 255, 0, "Garey\n");
}
int g_blockedCmdCount, g_serverCmdCount,g_anticheckfiles;
char *g_blockedCmds[1024], *g_serverCmds[2048], *g_anticheckfiles2[2048];
@@ -61,15 +72,26 @@ int Callback(const char *section, const char *key, const char *value, const void
return 1;
}
void Inject(){LoadLibraryA(g_Engine.Cmd_Argv(1)); }
-int g_blockedCvarCount;
-char *g_blockedCvars[512];
+/*int g_blockedCvarCount;
+char *g_blockedCvars[512];*/
+
+void DumpCmd()
+{
+ cmd_s *pCmd = g_Engine.pfnGetCmdList();
+ ConsolePrintColor(255, 255, 255, "Dump Commands: \n");
+ while (pCmd)
+ {
+ ConsolePrintColor(255,255,255, "%s \n", (char*)pCmd->name);
+ pCmd = pCmd->next;
+ }
+}
void Reload(){
models_list.clear();
ini_browse(Callback,NULL,g_settingsFileName);
- memset(g_blockedCmds,0,sizeof(g_blockedCmds));memset(g_blockedCvars, 0, sizeof(g_blockedCvars));
+ memset(g_blockedCmds,0,sizeof(g_blockedCmds));//memset(g_blockedCvars, 0, sizeof(g_blockedCvars));
memset(g_serverCmds, 0, sizeof(g_serverCmds)); memset(g_anticheckfiles2, 0, sizeof(g_anticheckfiles2));
- g_blockedCvarCount = 0; g_blockedCmdCount = 0; g_serverCmdCount = 0; g_anticheckfiles = 0;
+ g_blockedCmdCount = 0; g_serverCmdCount = 0; g_anticheckfiles = 0;
static TCHAR sKeyNames[4096*3];
GetPrivateProfileSection(TEXT("ADetect"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
@@ -84,9 +106,17 @@ void Reload(){
char *psKeyName3 = sKeyNames;
while (psKeyName3[0] != '\0') { g_serverCmds[g_serverCmdCount++] = strdup(psKeyName3); psKeyName3 += strlen(psKeyName3) + 1; }
- GetPrivateProfileSection(TEXT("Blocked cvars"),sKeyNames,ARRAYSIZE(sKeyNames),g_settingsFileName);
+ /*GetPrivateProfileSection(TEXT("Blocked cvars"),sKeyNames,ARRAYSIZE(sKeyNames),g_settingsFileName);
char *psKeyName2=sKeyNames;
- while (psKeyName2[0]!='\0'){g_blockedCvars[g_blockedCvarCount++]=strdup(psKeyName2);psKeyName2+=strlen(psKeyName2)+1;}
+ while (psKeyName2[0]!='\0'){g_blockedCvars[g_blockedCvarCount++]=strdup(psKeyName2);psKeyName2+=strlen(psKeyName2)+1;}*/
+ GetPrivateProfileSection(TEXT("Cvars"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
+ char *psKeyName2 = sKeyNames;
+ // Clear vector
+ Cvars.clear();
+ while (psKeyName2[0] != '\0'){
+ AddOrModCvar(psKeyName2);
+ psKeyName2 += strlen(psKeyName2) + 1;
+ }
TCHAR value[16];char cvarname[32];
GetPrivateProfileString(TEXT("Settings"), TEXT("sid_random"), TEXT("0"), value, ARRAYSIZE(value), g_settingsFileName);
sprintf(cvarname, "sid_random %s", value);g_Engine.pfnClientCmd(cvarname); memset(value, 0, sizeof(value)); memset(cvarname, 0, sizeof(cvarname));
@@ -100,6 +130,13 @@ void Reload(){
sprintf(cvarname, "events_block %s", value); g_Engine.pfnClientCmd(cvarname); memset(value, 0, sizeof(value)); memset(cvarname, 0, sizeof(cvarname));
}
+
+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 InitHack(){
static TCHAR sKeyNames[4096 * 3];
GetPrivateProfileSection(TEXT("Commands"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
@@ -132,24 +169,16 @@ void InitHack(){
while (psKeyName[0] != '\0') {
LoadLibraryA(psKeyName);
psKeyName += strlen(psKeyName) + 1;
- }
- GetPrivateProfileSection(TEXT("Custom Commands"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
- psKeyName = sKeyNames;
- while (psKeyName[0] != '\0') {
- g_pEngine->pfnAddCommand(strdup(psKeyName), DRC_CMD_NONE);
- psKeyName += strlen(psKeyName) + 1;
- }
- ini_browse(Callback, NULL, g_settingsFileName);
- GetPrivateProfileSection(TEXT("Blocked cvars"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
+ }
+ GetPrivateProfileSection(TEXT("Cvars"), sKeyNames, ARRAYSIZE(sKeyNames), g_settingsFileName);
char *psKeyName2 = sKeyNames;
- g_blockedCvarCount = 0;
- while (psKeyName2[0] != '\0') {
- g_blockedCvars[g_blockedCvarCount++] = strdup(psKeyName2);
+ while (psKeyName2[0] != '\0')
+ {
+ AddOrModCvar(psKeyName2);
psKeyName2 += strlen(psKeyName2) + 1;
}
-
if (!(g_Engine.Con_IsVisible() != 0))g_Engine.pfnClientCmd("toggleconsole");
- ConsolePrintColor(0, 255, 11, "-- Extra Mirror v2.3\n");
+ ConsolePrintColor(0, 255, 11, "-- Extra Mirror v2.6\n");
ConsolePrintColor(255, 255, 255, "-- Use 'credits' for more information\n");
ConsolePrintColor(255, 255, 255, "-- Thank's to Realwar for title\n");
ConsolePrintColor(255, 255, 255, "-- Thank's to FightMagister for functions\n");
@@ -164,7 +193,8 @@ void InitHack(){
GetPrivateProfileString(TEXT("Settings"), TEXT("events_block"), TEXT("0"), value, ARRAYSIZE(value), g_settingsFileName);
events_block = g_pEngine->pfnRegisterVariable("events_block", value, 0); memset(value, 0, sizeof(value));
GetPrivateProfileString(TEXT("Settings"), TEXT("motd_block"), TEXT("0"), value, ARRAYSIZE(value), g_settingsFileName);
- motd_block = g_pEngine->pfnRegisterVariable("motd_block", value, 0);memset(value, 0, sizeof(value));
+ motd_block = g_pEngine->pfnRegisterVariable("motd_block", value, 0); memset(value, 0, sizeof(value));
+ g_pEngine->pfnAddCommand("dump_cmd", DumpCmd);
}
void HookEventMessages(){
@@ -257,3 +287,100 @@ void HookFunction(){
g_pEngine->pfnDrawUnicodeCharacter = pfnDrawUnicodeCharacter;
// g_pStudio->SetRenderModel = SetRenderModel;
}
+
+// Parsing string into vector
+void AddOrModCvar(const string line){
+ m_Cvar temp;
+ // Set non-valid mode for future checks
+ temp.mode = -1;
+ // Search first occurance of space char
+ size_t start = line.find(' ');
+ // Set name
+ temp.name = line.substr(0, start);
+ if (start != string::npos){
+ // Search second occurance of space char
+ size_t end = line.find(' ', start+1);
+ string Tag;
+ if (end != string::npos)Tag = line.substr(start + 1, end - start - 1);
+ else Tag = line.substr(start + 1);
+
+ if (Tag == "BAD") { temp.mode = cvar_bad; }
+ else if (Tag == "FAKE") { temp.mode = cvar_fake; }
+ else if (Tag == "SERVERSIDE") { temp.mode = cvar_open; }
+ else { /* UNKNOWN MODE WE SHOULD NOTIFY */ };
+
+ // ˆùåì value
+ if (end != string::npos){
+ size_t q_start = line.find("\"", end);
+ if (q_start != string::npos)
+ {
+ size_t q_end = line.find("\"", q_start + 1);
+ if (q_end != string::npos)
+ {
+ string Value = line.substr(q_start + 1, q_end - q_start - 1);
+ temp.value = Value;
+ temp.default = Value;
+ }
+ else
+ {
+ // Not closed quote :facepalm: notify?
+ }
+ }
+ else{
+ // Value not in quotes or not appear at all?
+ // Check for spaces
+ size_t s_start = line.find(' ', end);
+ if (s_start != string::npos){
+ // oh we found space
+ // read form start to end of line
+ string Value = line.substr(s_start + 1);
+ temp.value = Value;
+ temp.default = Value;
+ }
+ else{
+ // nope there no delimiter
+ // Should we notify?
+ }
+ }
+ }
+
+ }
+ else{
+ // No delimiter??? wtf? Should we notify? possible todo
+ }
+ if (temp.mode == -1)temp.mode = cvar_fake; // todo: cvar for default mode
+ if (temp.value.length() == 0){
+ // todo: cvar for default value
+ temp.value = "0";
+ temp.default = temp.value;
+ }
+ auto pos = FindCvar(temp.name, Cvars);
+ if (pos != -1)Cvars[pos] = temp;
+ else Cvars.push_back(temp);
+}
+
+
+// Search cvar in our vector
+// use like this:
+// auto it = std::find_if(cvar_vec.begin(), cvar_vec.end(), finder_cvar(cvar_name));
+struct finder_cvar : std::unary_function {
+ string name;
+ finder_cvar(string name) :name(name) { }
+ bool operator()(m_Cvar const& m) const {
+ return m.name == name;
+ }
+};
+
+// Search cvar by name in given vector
+ptrdiff_t FindCvar(string name, vector vec_cvar)
+{
+ ptrdiff_t pos;
+ pos = std::find_if(vec_cvar.begin(), vec_cvar.end(), finder_cvar(name)) - vec_cvar.begin();
+ if (pos >= vec_cvar.size())
+ {
+ return -1;
+ }
+
+ return pos;
+}
+
diff --git a/MiniBase/client.h b/MiniBase/client.h
index 10db9d8..db5c100 100644
--- a/MiniBase/client.h
+++ b/MiniBase/client.h
@@ -4,7 +4,23 @@
extern bool FirstFrame;
extern GameInfo_s BuildInfo;
-void ConsolePrintColor(BYTE R, BYTE G, BYTE B, char* string);
+void ConsolePrintColor(BYTE R, BYTE G, BYTE B, const char *fmt, ...);
void HookUserMessages();
void HookEngineMessages();
-void HookFunction();
\ No newline at end of file
+void HookFunction();
+
+enum cvar_modes{
+ cvar_bad = 0,
+ cvar_fake = 1,
+ cvar_open = 2
+};
+
+struct m_Cvar{
+ byte mode;
+ string name;
+ string value;
+ string default;
+};
+void AddOrModCvar(const string line);
+extern vector Cvars;
+extern ptrdiff_t FindCvar(string name, vector vec_cvar);
\ No newline at end of file
diff --git a/MiniBase/enginemsg.cpp b/MiniBase/enginemsg.cpp
index 999e9db..110f000 100644
--- a/MiniBase/enginemsg.cpp
+++ b/MiniBase/enginemsg.cpp
@@ -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];
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;
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;
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) {
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) {
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) {
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) {
}
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);
- }
+}
*/
diff --git a/MiniBase/enginemsg.h b/MiniBase/enginemsg.h
index 8d3933a..46a7470 100644
--- a/MiniBase/enginemsg.h
+++ b/MiniBase/enginemsg.h
@@ -82,8 +82,19 @@ void SVC_Director();
void SVC_Resourcelist();
void SVC_VoiceInit();
+extern DWORD Cbuf_Addtext_call;
+extern DWORD Cbuf_Addtext_jump;
+extern DWORD Cbuf_Execute_call;
+extern DWORD Cbuf_Execute_jump;
+extern DWORD ExecuteString_call;
+extern DWORD ExecuteString_jump;
+extern void Cbuf_AddText_CallHook_Ext(char *text);
+extern void Cbuf_Execute_CallHook_Ext();
+
extern pfnEngineMessage pSVC_VoiceInit;
extern pfnEngineMessage pSVC_StuffText;
extern pfnEngineMessage pSVC_SendCvarValue;
extern pfnEngineMessage pSVC_SendCvarValue2;
extern pfnEngineMessage pSVC_Director;
+extern bool CheckIsFake(string FullCmd);
+extern bool CheckAndSetCvar(string FullCmd);
\ No newline at end of file
diff --git a/MiniBase/main.cpp b/MiniBase/main.cpp
index 14e692a..41259b2 100644
--- a/MiniBase/main.cpp
+++ b/MiniBase/main.cpp
@@ -8,7 +8,9 @@
#include
#include
#include
+#include
#include
+
extern cvar_t *random;
extern cvar_t *logsfiles;
TCHAR g_settingsFileName[MAX_PATH];
@@ -17,7 +19,7 @@ void(*g_pfnCL_ParseConsistencyInfo)();
FILE *g_pFile;
extern int g_anticheckfiles;
extern char *g_anticheckfiles2[2048];
-
+DWORD Original_ExecuteString;
bool ParseListx(const char *str) {
for (DWORD i = 0; i < g_anticheckfiles; i++) {
@@ -288,10 +290,24 @@ public:
return true;
}
};
+
+class JmpOpcode {
+public:
+ static void Setup(uintptr_t jmpPtr, uintptr_t destPtr) {
+ DWORD oldProt;
+ VirtualProtect(LPVOID(jmpPtr), sizeof(uint8_t) + sizeof(intptr_t), PAGE_EXECUTE_READWRITE, &oldProt);
+
+ *(uint8_t *)jmpPtr = 0xE9;
+ *(intptr_t *)(jmpPtr + sizeof(uint8_t)) = (intptr_t)destPtr - ((intptr_t)jmpPtr + 5);
+
+ VirtualProtect(LPVOID(jmpPtr), sizeof(uint8_t) + sizeof(intptr_t), oldProt, &oldProt);
+ }
+};
class CallOpcode {
public:
static uintptr_t GetDestination(uintptr_t callPtr) {
- return (callPtr + 5) + *(intptr_t *)(callPtr + 1);
+ return (intptr_t)(callPtr + 5) + *(intptr_t *)(callPtr + 1);
+ //return (callPtr + 5) + *(intptr_t *)(callPtr + 1);
}
static void SetDestination(uintptr_t callPtr, uintptr_t destPtr) {
DWORD oldProt;
@@ -446,16 +462,132 @@ int Steam_GSInitiateGameConnection_CallHook(void *pData, int maxDataBytes, uint6
memcpy(pData, &revEmuTicket, sizeof(revEmuTicket));
return sizeof(revEmuTicket);
}
+
+
+__declspec(naked) void Cbuf_Execute_CallHook()
+{
+ __asm PUSH EBP
+ __asm MOV EBP, ESP
+ __asm SUB ESP, 400h
+ __asm JMP[Cbuf_Execute_jump]
+}
+
+void Cbuf_Execute_CallHook_Ext()
+{
+ Cbuf_Execute_CallHook();
+}
+
+
+__declspec(naked) void Cbuf_AddText_CallHook(char *text)
+{
+ //MessageBox(NULL, text, NULL, MB_OK);
+ __asm PUSH EBP
+ __asm MOV EBP, ESP
+ __asm PUSH ESI
+ __asm MOV ESI, [EBP + 0x8]
+ __asm JMP[Cbuf_Addtext_jump]
+ /*MessageBox(NULL, text, NULL, MB_OK);*/
+}
+
+void Cbuf_AddText_CallHook_Ext(char *text)
+{
+ Cbuf_AddText_CallHook(text);
+}
+
void CL_ReadDemoMessage_OLD_Cbuf_AddText_CallHook(const char *str){
// Add your filters there
//MessagePrintf("Demo tried to execute: %s", str);
}
+//void (*Original_ExecuteString)(char *text, cmd_source_t src);
+/*
+void __cdecl Cmd_ExecuteString_CallHook(char *text, cmd_source_t src)
+{
+ __asm PUSH EBP
+ __asm MOV EBP, ESP
+ __asm MOV ECX, [EBP + 8]
+ __asm MOV EAX, [EBP + 0Ch]
+ __asm PUSH ESI
+ __asm JMP [Original_ExecuteString]
+}
+*/
+/*
+void Cmd_ExecuteString_CallHook(char *text, cmd_source_t src)
+{
+ char * lox;
+ __asm PUSH EBP
+ __asm MOV EBP, ESP
+ //__asm MOV ECX, DWORD PTR SS : [EBP + 0x8]
+ __asm MOV ECX, [EBP + 0x8]
+ __asm MOV EAX, [EBP + 0xC]
+ __asm { MOV ECX, lox }
+ {
+ std::stringstream stream;
+ stream << "1 " << lox;
+ MessageBox(0, stream.str().c_str(), 0, MB_OK);
+ }
+ __asm PUSH ESI
+ __asm JMP[Original_ExecuteString]
+}
+*/
+//void Cmd_ExecuteString_CallHook(char *text, cmd_source_t src)
+//__declspec(naked) void WINAPI Cmd_ExecuteString_CallHook()
+/*__declspec(naked) void Cmd_ExecuteString_CallHook()
+{
+ __asm PUSH EBP
+ __asm call ExecuteString
+ __asm MOV EBP, ESP
+ __asm MOV ECX, [EBP + 0x8]
+ __asm MOV EAX, [EBP + 0xC]
+ __asm JMP[Original_ExecuteString]
+}*/
+/*
+__declspec(naked) void Cmd_ExecuteString_CallHook()
+{
+ static char *text; cmd_source_t src;
+ __asm MOV text, ECX
+ __asm MOV src, EAX
+ ExecuteString(text, src);
+ __asm PUSH EBP
+ __asm MOV EBP, ESP
+ __asm MOV ECX, [EBP + 0x8]
+ __asm MOV EAX, [EBP + 0xC]
+ __asm JMP[Original_ExecuteString]
+}
+*/
+/*
+// good func #2
+__declspec(naked) void Cmd_ExecuteString_CallHook()
+{
+ __asm {
+ PUSH EBP
+ MOV EBP, ESP
+ MOV ECX, [EBP + 0x8]
+ MOV EAX, [EBP + 0xC]
+ PUSH EAX
+ PUSH ECX
+ call ExecuteString
+ POP ECX
+ POP EAX
+ POP EBP
+ }
+ __asm {
+ PUSH EBP
+ MOV EBP, ESP
+ MOV ECX, [EBP + 0x8]
+ MOV EAX, [EBP + 0xC]
+ jmp[Original_ExecuteString]
+ }
+}*/
+
+
void CL_ConnectionlessPacket_Cbuf_AddText_CallHook(const char *str){
// Add your filters there
- //MessagePrintf("Server tried to execute via connectionless: %s", str);
+ //ConsolePrintColor(0, 255, 0, "Server tried to execute via connectionless: %s", str);
}
+
+
void ModuleLoaded() {
Module *pModule;
if (Module::IsLoaded("hw.dll")) {
@@ -477,7 +609,33 @@ void ModuleLoaded() {
ptr = pModule->FindFirstUseOfString("Error, bad server command %s\n");
ptr = pModule->SearchUpForBinaryPattern(ptr, BinaryPattern("E8 ?? ?? ?? ?? 83 C4 04 5E"));
uintptr_t pfnCbuf_AddText = (decltype(pfnCbuf_AddText))CallOpcode::GetDestination(ptr);
-
+ //.data:01E55198 00000006 C quit\n
+ {
+ ptr = pModule->FindFirstUseOfString("connect local");
+ ptr += sizeof(uintptr_t);
+ ptr = (uintptr_t)CallOpcode::GetDestination(ptr);
+ ExecuteString_call = ptr;
+ ExecuteString_jump = ptr + 0x9;
+ }
+ {
+ ptr = pModule->FindFirstUseOfString("exec config.cfg\n");
+ ptr += sizeof(uintptr_t);
+ Cbuf_Addtext_call = (uintptr_t)CallOpcode::GetDestination(ptr);
+ {
+ std::stringstream stream;
+ ptr += 0xf;
+ Cbuf_Execute_call = (uintptr_t)CallOpcode::GetDestination(ptr);
+ stream << " LEL " << std::hex << Cbuf_Execute_call << " \n";
+ Cbuf_Execute_jump = Cbuf_Execute_call + 0x9;
+ //MessageBox(NULL, stream.str().c_str(), NULL, MB_OK);
+ JmpOpcode::Setup(Cbuf_Execute_call, (DWORD)&Cbuf_Execute_CallHook);
+ }
+ Cbuf_Addtext_jump = Cbuf_Addtext_call + 0x7;
+ JmpOpcode::Setup(Cbuf_Addtext_call, (DWORD)&Cbuf_AddText_CallHook);
+ }
+ //CallOpcode::SetDestination(ptr, &Cmd_ExecuteString_CallHook);
+ //PlaceJMP((BYTE*)ptr, (DWORD)&Cmd_ExecuteString_CallHook, 0x9);
+ //JmpOpcode::Setup(ptr, (DWORD)&Cmd_ExecuteString_CallHook);
ptr = pModule->FindFirstUseOfString("Tried to read a demo message with no demo file\n");
ptr = pModule->SearchDownForFirstCallToFunction(ptr, pfnCbuf_AddText);
CallOpcode::SetDestination(ptr, &CL_ReadDemoMessage_OLD_Cbuf_AddText_CallHook);
@@ -501,7 +659,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved){
TCHAR sFileName[MAX_PATH];
StringCchCopyN(sFileName, ARRAYSIZE(sFileName), lpFileName, lpExtension - lpFileName);
- bool fPrefixDetected = false;
+ bool fPrefixDetected = true;
for (PTCHAR pch = sFileName; *pch != '\0'; pch++) {
if (*pch == 'm') {
fPrefixDetected = true;
diff --git a/MiniBase/main.h b/MiniBase/main.h
index 9afdf38..21c057d 100644
--- a/MiniBase/main.h
+++ b/MiniBase/main.h
@@ -4,7 +4,7 @@
#include
#include
#include