From c479389a77a36a6741beac5f2e0f44068d861dce Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 4 Jun 2012 12:15:24 +0200 Subject: [PATCH] refactor this into common code --- sys.h | 3 ++ sys_linux.c | 112 ------------------------------------------------- sys_sdl.c | 5 ++- sys_shared.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ sys_win.c | 3 ++ 5 files changed, 126 insertions(+), 113 deletions(-) diff --git a/sys.h b/sys.h index e5247d35..c4c8c559 100644 --- a/sys.h +++ b/sys.h @@ -115,5 +115,8 @@ void Sys_InitProcessNice (void); void Sys_MakeProcessNice (void); void Sys_MakeProcessMean (void); +// call this from main(); if it returns false, exit using return +qboolean anticheat_init(char **envp); + #endif diff --git a/sys_linux.c b/sys_linux.c index 70fe819d..bf7cd29b 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -148,118 +148,6 @@ void Sys_InitConsole (void) { } -#ifdef ANTICHEAT -# ifndef WIN32 -# include -# include -# include -# endif -#endif -static qboolean anticheat_init(char **envp) -{ -#ifdef ANTICHEAT -#define FAIL return false - - // anti LD_PRELOAD - // note that we're using envp here, so one doesn't simply hook into getenv() - static char *unsecure_envvars = - // UNSECURE_ENVVARS from glibc - "GCONV_PATH\0" // libraries are loaded from here - //"GETCONF_DIR\0" // harmless, can only fake getconf() output - //"HOSTALIASES\0" // harmless, just messes with DNS - "LD_AUDIT\0" // loads libraries - // "LD_DEBUG\0" // harmless, just shows data - // "LD_DEBUG_OUTPUT\0" // harmless, just shows data - "LD_DYNAMIC_WEAK\0" // changes name resolution - "LD_LIBRARY_PATH\0" // loads libraries - "LD_ORIGIN_PATH\0" // may load libraries - "LD_PRELOAD\0" // loads libraries - // "LD_PROFILE\0" // harmless, just creates profile - // "LD_SHOW_AUXV\0" // harmless, just shows data - // "LD_USE_LOAD_BIAS\0" // harmless - // "LOCALDOMAIN\0" // harmless, just messes with DNS - // "LOCPATH\0" // harmless, just messes with locales - // "MALLOC_TRACE\0" // harmless, just shows data - // "NIS_PATH\0" // harmless, just messes with DNS and user ID data - // "NLSPATH\0" // harmless, just messes with locales - // "RESOLV_HOST_CONF\0" // harmless, can cause private data to be printed from suid, but we're not suid - // "RES_OPTIONS\0" // harmless, just messes with DNS - // "TMPDIR\0" // harmless, we don't use temp files anyway - // "TZDIR\0" // harmless, just enables time travel - // EXTRA_UNSECURE_ENVVARS from glibc - "LD_AOUT_LIBRARY_PATH\0" // loads libraries - "LD_AOUT_PRELOAD\0" // loads libraries - ; - - while(*envp) - { - char *p = unsecure_envvars; - while(*p) - { - char *q = envp[0]; - while(*p && *p == *q) - { - ++p; - ++q; - } - if(*p == 0 && *q == '=') - FAIL; // match! - // next! - while(*p) - ++p; - ++p; - } - ++envp; - } - - // anti ptrace; also, make a forked process copy to detach from debuggers -# ifndef WIN32 - { - pid_t pid = fork(); - if(pid < 0) - FAIL; - if(pid == 0) - { - // nothing to do here - } - else - { - // parent - int status; - if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) - { - kill(pid, SIGKILL); - FAIL; - } - for(;;) - { - if(waitpid(pid, &status, 0) == (pid_t) -1) - { - if(errno == ECHILD) // process no longer exists - FAIL; - } - if(WIFEXITED(status)) - { - exit(WEXITSTATUS(status)); - } - if(WIFSTOPPED(status)) - { - printf("ptrace: continue... (signal: %d)\n", (int) WSTOPSIG(status)); - if(ptrace(PTRACE_CONT, pid, (void *) WSTOPSIG(status), NULL) < 0) - { - perror("okay.png"); - } - } - } - // never gonna get to here - } - } -# endif -#endif - - return true; -} - int main (int argc, char **argv, char **envp) { if(!anticheat_init(envp)) diff --git a/sys_sdl.c b/sys_sdl.c index c00cf408..4863ac76 100644 --- a/sys_sdl.c +++ b/sys_sdl.c @@ -176,8 +176,11 @@ void Sys_InitConsole (void) { } -int main (int argc, char *argv[]) +int main (int argc, char *argv[], char *envp[]) { + if(!anticheat_init(envp)) + return 42; + signal(SIGFPE, SIG_IGN); com_argc = argc; diff --git a/sys_shared.c b/sys_shared.c index 10f5a60e..a2a3852b 100644 --- a/sys_shared.c +++ b/sys_shared.c @@ -640,3 +640,119 @@ void Sys_MakeProcessMean (void) { } #endif + +#ifdef ANTICHEAT +# ifndef WIN32 +# include +# include +# include +# endif +#endif +qboolean anticheat_init(char **envp) +{ +#ifdef ANTICHEAT +# define FAIL return false + + // anti LD_PRELOAD + // note that we're using envp here, so one doesn't simply hook into getenv() + static char *unsecure_envvars = + // UNSECURE_ENVVARS from glibc + "GCONV_PATH\0" // libraries are loaded from here + //"GETCONF_DIR\0" // harmless, can only fake getconf() output + //"HOSTALIASES\0" // harmless, just messes with DNS + "LD_AUDIT\0" // loads libraries + // "LD_DEBUG\0" // harmless, just shows data + // "LD_DEBUG_OUTPUT\0" // harmless, just shows data + "LD_DYNAMIC_WEAK\0" // changes name resolution + "LD_LIBRARY_PATH\0" // loads libraries + "LD_ORIGIN_PATH\0" // may load libraries + "LD_PRELOAD\0" // loads libraries + // "LD_PROFILE\0" // harmless, just creates profile + // "LD_SHOW_AUXV\0" // harmless, just shows data + // "LD_USE_LOAD_BIAS\0" // harmless + // "LOCALDOMAIN\0" // harmless, just messes with DNS + // "LOCPATH\0" // harmless, just messes with locales + // "MALLOC_TRACE\0" // harmless, just shows data + // "NIS_PATH\0" // harmless, just messes with DNS and user ID data + // "NLSPATH\0" // harmless, just messes with locales + // "RESOLV_HOST_CONF\0" // harmless, can cause private data to be printed from suid, but we're not suid + // "RES_OPTIONS\0" // harmless, just messes with DNS + // "TMPDIR\0" // harmless, we don't use temp files anyway + // "TZDIR\0" // harmless, just enables time travel + // EXTRA_UNSECURE_ENVVARS from glibc + "LD_AOUT_LIBRARY_PATH\0" // loads libraries + "LD_AOUT_PRELOAD\0" // loads libraries + ; + + if(envp) + { + while(*envp) + { + char *p = unsecure_envvars; + while(*p) + { + char *q = envp[0]; + while(*p && *p == *q) + { + ++p; + ++q; + } + if(*p == 0 && *q == '=') + FAIL; // match! + // next! + while(*p) + ++p; + ++p; + } + ++envp; + } + } + + // anti ptrace; also, make a forked process copy to detach from debuggers +# ifndef WIN32 + { + pid_t pid = fork(); + if(pid < 0) + FAIL; + if(pid == 0) + { + // nothing to do here + } + else + { + // parent + int status; + if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) + { + kill(pid, SIGKILL); + FAIL; + } + for(;;) + { + if(waitpid(pid, &status, 0) == (pid_t) -1) + { + if(errno == ECHILD) // process no longer exists + FAIL; + } + if(WIFEXITED(status)) + { + exit(WEXITSTATUS(status)); + } + if(WIFSTOPPED(status)) + { + printf("ptrace: continue... (signal: %d)\n", (int) WSTOPSIG(status)); + if(ptrace(PTRACE_CONT, pid, (void *) WSTOPSIG(status), NULL) < 0) + { + perror("okay.png"); + } + } + } + // never gonna get to here + } + } +# endif +#endif + + return true; +} + diff --git a/sys_win.c b/sys_win.c index de1f4718..695a0642 100644 --- a/sys_win.c +++ b/sys_win.c @@ -314,6 +314,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin global_hInstance = hInstance; + if(!anticheat_init(NULL)) + return 42; + lpBuffer.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus (&lpBuffer); -- 2.39.2