]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
also add a facility to read and scan DLL memory
authorRudolf Polzer <divverent@alientrap.org>
Mon, 4 Jun 2012 11:00:12 +0000 (13:00 +0200)
committerRudolf Polzer <divverent@alientrap.org>
Mon, 4 Jun 2012 11:00:12 +0000 (13:00 +0200)
host_cmd.c
quakedef.h
sys.h
sys_linux.c
sys_sdl.c
sys_shared.c
sys_win.c

index 4d2b93b6eb76617231bf405b14151e017e68a1fa..d25f61e5b2f713496863cfb28d1d234e6917e1a3 100644 (file)
@@ -2983,6 +2983,10 @@ void Host_InitCommands (void)
        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);
index 6bd5ddfaee6bd78214cc9b56c70c2daf6072f759..3b594916b7645951511eafe7c9e7460cb047b23b 100644 (file)
@@ -32,6 +32,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define DP_FUNC_NORETURN
 #endif
 
+#ifdef ANTICHEAT
+#define _GNU_SOURCE // for memmem
+#endif
+
 #include <sys/types.h>
 #include <ctype.h>
 #include <math.h>
diff --git a/sys.h b/sys.h
index c4c8c55958dc160d3d9855384cb1a97b90ab9964..acce3acf016148fcb0461622db3c616276a78b45 100644 (file)
--- a/sys.h
+++ b/sys.h
@@ -116,7 +116,20 @@ void Sys_MakeProcessNice (void);
 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
 
index bf7cd29b1e5ab6aedb1fb9d5de255d8af5d5ce89..50982ffb719e7a825ac3e44c7ffe59669e4b04cd 100644 (file)
@@ -150,7 +150,7 @@ void Sys_InitConsole (void)
 
 int main (int argc, char **argv, char **envp)
 {
-       if(!anticheat_init(envp))
+       if(!Sys_AntiCheat_Init(envp))
                return 42;
 
        signal(SIGFPE, SIG_IGN);
index 4863ac76e8caca2392fed93d5280c0650fa2e4c1..aadbe83d50f1d198cc01d41bfd38a232a9546e60 100644 (file)
--- a/sys_sdl.c
+++ b/sys_sdl.c
@@ -178,7 +178,7 @@ void Sys_InitConsole (void)
 
 int main (int argc, char *argv[], char *envp[])
 {
-       if(!anticheat_init(envp))
+       if(!Sys_AntiCheat_Init(envp))
                return 42;
 
        signal(SIGFPE, SIG_IGN);
index a2a3852b1750db29c7323689985d53c567decdce..8297a87a4821a242647fe8d57bb510932d47c035 100644 (file)
@@ -648,7 +648,87 @@ void Sys_MakeProcessMean (void)
 #  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
@@ -708,8 +788,8 @@ qboolean anticheat_init(char **envp)
                }
        }
 
-       // 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)
@@ -755,4 +835,3 @@ qboolean anticheat_init(char **envp)
 
        return true;
 }
-
index 695a06428deae3c3837eb6cecb6efb805a89780f..7462aa498609750eee50ef7fd65e4c3c02dc8660 100644 (file)
--- a/sys_win.c
+++ b/sys_win.c
@@ -314,7 +314,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
 
        global_hInstance = hInstance;
 
-       if(!anticheat_init(NULL))
+       if(!Sys_AntiCheat_Init(NULL))
                return 42;
 
        lpBuffer.dwLength = sizeof(MEMORYSTATUS);