From 89c3bbea1990d61937ea92237fce5167d67dc3e4 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 4 Jun 2012 10:29:23 +0200 Subject: [PATCH] now also detect LD_PRELOAD and such stuff --- sys_linux.c | 113 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 30 deletions(-) diff --git a/sys_linux.c b/sys_linux.c index 4db3811c..7cb28b6a 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -153,59 +153,112 @@ void Sys_InitConsole (void) # include # endif #endif -static void anticheat_init(void) +static void anticheat_init(char **envp) { #ifdef ANTICHEAT #define FAIL exit(42) - // 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) + // 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) { - // nothing to do here + 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; } - else + + // anti ptrace; also, make a forked process copy to detach from debuggers +# ifndef WIN32 { - // parent - int status; - if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) - { - kill(pid, SIGKILL); + pid_t pid = fork(); + if(pid < 0) FAIL; + if(pid == 0) + { + // nothing to do here } - for(;;) + else { - if(waitpid(pid, &status, 0) == (pid_t) -1) - { - if(errno == ECHILD) // process no longer exists - FAIL; - } - if(WIFEXITED(status)) + // parent + int status; + if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) { - exit(WEXITSTATUS(status)); + kill(pid, SIGKILL); + FAIL; } - if(WIFSTOPPED(status)) + for(;;) { - printf("ptrace: continue... (signal: %d)\n", (int) WSTOPSIG(status)); - if(ptrace(PTRACE_CONT, pid, (void *) WSTOPSIG(status), NULL) < 0) + if(waitpid(pid, &status, 0) == (pid_t) -1) { - perror("okay.png"); + 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 } - // never gonna get to here } # endif - #endif } -int main (int argc, char **argv) +int main (int argc, char **argv, char **envp) { - anticheat_init(); + anticheat_init(envp); signal(SIGFPE, SIG_IGN); -- 2.39.2