Cmd_AddCommand ("pingplreport", Host_PingPLReport_f, "command sent by server containing client ping and packet loss values for scoreboard, triggered by pings command from client (not used by QW servers)");
Cmd_AddCommand ("fixtrans", Image_FixTransparentPixels_f, "change alpha-zero pixels in an image file to sensible values, and write out a new TGA (warning: SLOW)");
+#ifdef ANTICHEAT
+ Cmd_AddCommand ("checkmemory", Sys_AntiCheat_CheckMemory_f, "check memory for patterns");
+#endif
+
Cvar_RegisterVariable (&r_fixtrans_auto);
Cvar_RegisterVariable (&team);
void Sys_MakeProcessMean (void);
// call this from main(); if it returns false, exit using return
-qboolean anticheat_init(char **envp);
+qboolean Sys_AntiCheat_Init(char **envp);
+#ifdef ANTICHEAT
+typedef enum
+{
+ CHECKMEMORY_N_A,
+ CHECKMEMORY_NODLL,
+ CHECKMEMORY_NOMATCH,
+ CHECKMEMORY_MATCHED
+}
+Sys_AntiCheat_CheckMemory_Result_t;
+// dllsubstringmode: false = check only dlls without this substring, true = check only dlls with this substring
+Sys_AntiCheat_CheckMemory_Result_t Sys_AntiCheat_CheckMemory(const char *dllsubstring, qboolean dllsubstringmode, const void *pattern, size_t length);
+void Sys_AntiCheat_CheckMemory_f(void);
+#endif
#endif
# include <errno.h>
# endif
#endif
-qboolean anticheat_init(char **envp)
+
+#ifdef ANTICHEAT
+// whole function only exists if anticheat is enabled
+Sys_AntiCheat_CheckMemory_Result_t Sys_AntiCheat_CheckMemory(const char *dllsubstring, qboolean dllsubstringmode, const void *pattern, size_t length)
+{
+# ifdef __linux__
+ Sys_AntiCheat_CheckMemory_Result_t ret = CHECKMEMORY_NODLL;
+ FILE *f = fopen("/proc/self/maps", "r");
+ if(!f)
+ exit(42);
+ while(!feof(f))
+ {
+ char buf[PATH_MAX+100], perm[5];
+ char mapname[sizeof(buf)];
+ void *begin, *end;
+
+ if(fgets(buf, sizeof(buf), f) == 0)
+ break;
+
+ mapname[0] = 0;
+ sscanf(buf, "%p-%p %4s %*x %*5s %*d %s",
+ &begin, &end, perm, mapname);
+
+ if(mapname[0] == 0)
+ continue;
+ if(perm[0] != 'r')
+ continue;
+ if(mapname[0] == '[')
+ continue;
+
+ if(dllsubstring && *dllsubstring)
+ if(!!strstr(mapname, dllsubstring) ^ dllsubstringmode)
+ continue;
+
+ ret = CHECKMEMORY_NOMATCH;
+
+ if(length)
+ {
+ if(memmem(begin, (unsigned char *) end - (unsigned char *) begin, pattern, length))
+ {
+ ret = CHECKMEMORY_MATCHED;
+ break;
+ }
+ }
+ else
+ {
+ ret = CHECKMEMORY_MATCHED;
+ break;
+ }
+ }
+ fclose(f);
+ return ret;
+# else
+ return CHECKMEMORY_N_A;
+# endif
+}
+void Sys_AntiCheat_CheckMemory_f(void)
+{
+ Sys_AntiCheat_CheckMemory_Result_t r;
+ if(Cmd_Argc() != 4)
+ return;
+ r = Sys_AntiCheat_CheckMemory(Cmd_Argv(1), atoi(Cmd_Argv(2)), Cmd_Argv(3), strlen(Cmd_Argv(3)));
+ switch(r)
+ {
+ case CHECKMEMORY_NOMATCH:
+ Con_Printf("NOMATCH\n");
+ break;
+ case CHECKMEMORY_MATCHED:
+ Con_Printf("MATCHED\n");
+ break;
+ case CHECKMEMORY_NODLL:
+ Con_Printf("NODLL\n");
+ break;
+ case CHECKMEMORY_N_A:
+ Con_Printf("N/A\n");
+ break;
+ }
+}
+#endif
+
+qboolean Sys_AntiCheat_Init(char **envp)
{
#ifdef ANTICHEAT
# define FAIL return false
}
}
- // anti ptrace; also, make a forked process copy to detach from debuggers
# ifndef WIN32
+ // anti ptrace; also, make a forked process copy to detach from debuggers
{
pid_t pid = fork();
if(pid < 0)
return true;
}
-