Logo Search packages:      
Sourcecode: unhide version File versions  Download package

unhide-linux26.c

/* 
          http://sourceforge.net/projects/unhide/
*/

/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

// Needed for unistd.h to declare getpgid() and others
#define _XOPEN_SOURCE 500

// Needed for sched.h to declare sched_getaffinity()
#define _GNU_SOURCE

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wait.h>
#include <sys/resource.h>
#include <errno.h>
#include <dirent.h>
#include <sched.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <ctype.h>
#include <time.h>


// we are looking only for real process not thread and only one by one
#define COMMAND "ps --no-header -p %i o pid"
// we are looking for session ID one by one
#define SESSION "ps --no-header -s %i o sess"
// We are looking for group ID one by one
// but ps can't select by pgid
#define PGID "ps --no-header -eL o pgid"
// We are looking for all processes even threads
#define THREADS "ps --no-header -eL o lwp"
// for sysinfo scanning, fall back to old command, as --no-header seems to create
// an extra process/thread
// #define SYS_COMMAND "ps -eL o lwp"
#define SYS_COMMAND "ps --no-header -eL o lwp"
// an extra process/thread
#define REVERSE "ps --no-header -eL o lwp,cmd"

// Define mask for the checks to do in checkps
#define PS_PROC               0x00000001
#define PS_THREAD             0x00000002
#define PS_MORE               0x00000004

// Tests numbers
// note that checkps can't be call alone.
enum test_num {
      // Individual test
      TST_NONE     = 0,
      TST_VERSION,
      TST_PROC,
      TST_CHDIR,
      TST_OPENDIR,
      TST_READDIR,
      TST_GETPRIO,
      TST_GETPGID,
      TST_GETSID,
      TST_GETAFF,
      TST_GETPARM,
      TST_GETSCHED,
      TST_RR_INT,
      TST_KILL,
      TST_NOPROCPS,
      TST_BRUTE,
      TST_REVERSE,
      TST_QUICKONLY,
      TST_SYS_INFO,
      TST_SYS_INFO2,
      // meta test
      TST_DIR,
      TST_SYS,
      TST_QUICK,
      TST_PROCALL,
      // MAX number, should be the last of enum.
      MAX_TESTNUM
};

00100 struct tab_test_t {
      int todo;
      void (*func)(void);
} ;
// boolean value
#define FALSE                 0
#define TRUE                  1


// sysctl kernel.pid_max
int maxpid = 32768;

// For Threads sync
int tid ;

// our own PID
pid_t mypid ;

// options
int verbose = 0;
int morecheck = FALSE;
int RTsys = FALSE;

// Found hidden proccess flag
int found_HP = 0;

// For logging to file
int logtofile;
FILE *unlog;

// Temporary string for output
char scratch[1000];

void *funcionThread (void *parametro) {

      tid = (pid_t) syscall (SYS_gettid);
      return(&tid) ;
};


void get_max_pid(int* newmaxpid) {
      char path[]= "/proc/sys/kernel/pid_max";
      pid_t tmppid = 0;
      FILE* fd= fopen(path,"r");
      if(!fd) {
            snprintf(scratch, 1000, "[*] Error: cannot get current maximum PID: %s\n", strerror(errno));
            fputs(scratch, stdout);
            if (logtofile == 1) {
                  fputs(scratch, unlog);
            }

            return;
      }


      if((fscanf(fd, "%d", &tmppid) != 1) || tmppid < 1) {
            snprintf(scratch, 1000, "[*] cannot get current maximum PID: Error parsing %s format\n", path);
            fputs(scratch, stdout);
            if (logtofile == 1) {
                  fputs(scratch, unlog);
            }
            return;
      } else {
            *newmaxpid = tmppid;
      }
      fclose(fd) ;
}


int checkps(int tmppid, int checks) {

      int ok = 0;
      char pids[30];

      char compare[100];
      char command[60];


      FILE *fich_tmp ;

//    printf("in --> checkps\n");   // DEBUG

// The compare string is the same for all test
      sprintf(compare,"%i\n",tmppid);

      if (PS_PROC == (checks & PS_PROC)) {
            sprintf(command,COMMAND,tmppid) ;

            fich_tmp=popen (command, "r") ;
            if (fich_tmp == NULL) {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : popen failed while ps checking pid %d (memory, or something set errno: %s)\n", tmppid, strerror(errno));
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
                  return(0);
            }

//          while (!feof(fich_tmp) && ok == 0) {
            {
                  char* tmp_pids = pids;

                  fgets(pids, 30, fich_tmp);
                  pids[29] = 0;

//                printf("pids = %s\n", pids);   // DEBUG
                  while( *tmp_pids == ' ' && tmp_pids <= pids+29) {
                        tmp_pids++;
                  }

                  if (strncmp(tmp_pids, compare, 30) == 0) {ok = 1;}

            }

            if (fich_tmp != NULL)
                  pclose(fich_tmp);

            if (1 == ok) return(ok) ;      // pid is found, no need to go further
      }

      if (PS_THREAD == (checks & PS_THREAD)) {
            FILE *fich_thread ;

            fich_thread=popen (THREADS, "r") ;
            if (fich_thread == NULL) {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : popen failed while thread checking pid %d (memory, or something set errno: %s)\n", tmppid, strerror(errno));
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
                  return(0);
            }

            while (!feof(fich_thread) && ok == 0) {
                  char* tmp_pids = pids;

                  fgets(pids, 30, fich_thread);
                  pids[29] = 0;

//                printf("   threads = %s\n", pids);   // DEBUG
                  while( *tmp_pids == ' ' && tmp_pids <= pids+29) {
                        tmp_pids++;
                  }

                  if (strncmp(tmp_pids, compare, 30) == 0) {ok = 1;}


            }
            if (fich_thread != NULL)
                  pclose(fich_thread);

            if (1 == ok) return(ok) ;      // thread is found, no need to go further
      }

      if (PS_MORE == (checks & PS_MORE)) {

            FILE *fich_session ;

            sprintf(command,SESSION,tmppid) ;

            fich_session=popen (command, "r") ;
            if (fich_session == NULL) {
                  snprintf(scratch, 1000, "Warning : popen failed while session checking pid %d (memory, or something set errno: %s)\n", tmppid, strerror(errno));
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
                  return(0);
            }


            while (!feof(fich_session) && ok == 0) {
                  char* tmp_pids = pids;

                  fgets(pids, 30, fich_session);
                  pids[29] = 0;

                  while( *tmp_pids == ' ' && tmp_pids <= pids+29) {
                        tmp_pids++;
                  }

                  if (strncmp(tmp_pids, compare, 30) == 0) {ok = 1;}

            }

            pclose(fich_session);

            if (1 == ok) return(ok) ;      // session is found, no need to go further

            FILE *fich_pgid ;

            fich_pgid=popen (PGID, "r") ;
            if (fich_pgid == NULL) {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : popen failed while pgid checking pid %d (memory, or something set errno: %s)\n", tmppid, strerror(errno));
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
                  return(0);
            }

            while (!feof(fich_pgid) && ok == 0) {
                  char* tmp_pids = pids;

                  fgets(pids, 30, fich_pgid);
                  pids[29] = 0;

                  while( *tmp_pids == ' ' && tmp_pids <= pids+29) {
                        tmp_pids++;
                  }

                  if (strncmp(tmp_pids, compare, 30) == 0) {ok = 1;}

            }

            pclose(fich_pgid);

      }
      return ok;
}

void printbadpid (int tmppid) {

      int statuscmd ;
      char cmd[100] ;
      struct stat buffer;
      FILE *cmdfile ;
      char cmdcont[1000];
      int cmdok = 0;

      found_HP = 1;
//    printf ("Found HIDDEN PID: %i", tmppid) ;

      sprintf(cmd,"/proc/%i/cmdline",tmppid);

      statuscmd = stat(cmd, &buffer);
//    statuscmd = 0 ;  // DEBUG

      if (statuscmd == 0) {
            cmdfile=fopen (cmd, "r") ;

            if (cmdfile != NULL) {

//                printf("\tCmdFile : %s\n",cmd) ; //DEBUG
                  while (!feof (cmdfile)) {

                        if (NULL != fgets (cmdcont, 1000, cmdfile)) {
                              cmdok = 1;
                              snprintf (scratch, 1000, "Found HIDDEN PID: %i\tCommand: \"%s\"\n\n", tmppid, cmdcont);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                  }
                  fclose(cmdfile);
            }
      }
      if (0 == cmdok) {             // fallback : try to readlink the exe
            ssize_t length ;

            sprintf(cmd,"/proc/%i/exe",tmppid);
            statuscmd = stat(cmd, &buffer);
//          printf("%s",cmd) ; //DEBUG
            if (statuscmd == 0) {
                  length = readlink(cmd, cmdcont, 1000) ;
//                printf("\t%0d\n",(int)length) ; //DEBUG
                  if (-1 != length) {
                        cmdcont[length] = 0;   // terminate the string
                        cmdok = 1;
                        snprintf (scratch, 1000, "Found HIDDEN PID: %i\tExe: \"%s\"\n\n", tmppid, cmdcont);
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
            }
      }
      if (0 == cmdok) {             // fallback : is it a sleeping kernel process
            sprintf(cmd,"/proc/%i/wchan",tmppid);
            statuscmd = stat(cmd, &buffer);
            if (statuscmd == 0) {
                  cmdfile=fopen (cmd, "r") ;

                  if (cmdfile != NULL) {

//                printf("\tCmdFile : %s\n",cmd) ; //DEBUG
                        while (!feof (cmdfile)) {

                              if (NULL != fgets (cmdcont, 1000, cmdfile)) {
                                    cmdok = 1;
                                    snprintf (scratch, 1000, "Found HIDDEN PID: %i\tWchan: \"[%s]\"\n\n", tmppid, cmdcont);
                                    fputs(scratch, stdout);
                                    if (logtofile == 1) {
                                          fputs(scratch, unlog);
                                    }
                              }
                        }
                        fclose(cmdfile);
                  }
            }
            else {
                  snprintf(scratch, 1000, "Found HIDDEN PID: %i\t\"  ... maybe a transitory process\"\n", tmppid);
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
      }
}

void checkproc(void) {

      int procpids ;
      int statusprocbefore, statusprocafter;
      struct stat buffer;
      char directory[100] ;

      snprintf (scratch, 1000,"[*]Searching for Hidden processes through /proc stat scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      sprintf(directory,"/proc/");

      for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 ) {


            // avoid ourselves
            if (procpids == mypid) {
                  continue;
            }
            sprintf(&directory[6],"%d",procpids);

            statusprocbefore = stat(directory, &buffer) ;
            if (statusprocbefore != 0) {
                  continue;
            }

            if(checkps(procpids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            statusprocafter = stat(directory, &buffer) ;
            if (statusprocafter != 0) {
                  continue;
            }

            printbadpid(procpids);
      }
}

void checkchdir(void) {

      int procpids ;
      int statusdir;
      char curdir[PATH_MAX] ;
      char directory[100] ;
//    char scratch[PATH_MAX] ;      // DEBUG
//    int count = 0;          //DEBUG

      snprintf (scratch, 1000, "[*]Searching for Hidden processes through /proc chdir scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      // get the path where Unhide is ran from.
      getcwd(curdir, PATH_MAX);

            sprintf(directory,"/proc/");

      for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 ) {


            // avoid ourselves
            if (procpids == mypid) {
                  continue;
            }

            sprintf(&directory[6],"%d",procpids);

            statusdir = chdir(directory) ;
            // the directory doesn't exist continue with the next one
            if (statusdir != 0) {
                  continue;
            }
            if (morecheck == TRUE) {
                  // find process group ID (the master thread) by reading the status file of the current dir
                  FILE* fich_tmp ;
                  int   found_tgid = FALSE;
                  char  line[128] ;
                  char* tmp_pids = line;
                  char* end_pid;
                  char  new_directory[100];

//                printf("directory = '%s'\n", directory);  // DEBUG
//                getcwd(scratch, PATH_MAX);                                  // DEBUG
//                printf("CWD = '%s'\n", scratch);                      // DEBUG

                  // we are in the /proc/pid directory
                  fich_tmp=fopen("status", "r") ;
                  if (fich_tmp == NULL) {
                        if(verbose) {
                              snprintf(scratch, 1000, "Warning : can't open status file for process: %d)\n", procpids);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                        continue ; // next process
                  }
                  while ((FALSE == found_tgid) && (!feof (fich_tmp))) {

                        if (NULL != fgets (line, 128, fich_tmp)) {
                              line[127] = 0;
                              if (0 == strncmp (line, "Tgid:", 5)) {
                                    found_tgid = TRUE;
                              }
                        }
                  }
                  fclose(fich_tmp);

                  if (TRUE == found_tgid) {
                        tmp_pids = line + 5;
                        while( ((*tmp_pids == ' ') || (*tmp_pids == '\t'))  && (tmp_pids <= line+127)) {
                              tmp_pids++;
                        }
//                      printf("tmp_pids2 = '%s'\n", tmp_pids);   // DEBUG
                        end_pid = tmp_pids;
                        while( isdigit(*end_pid) && end_pid <= line+127) {
                              end_pid++;
                        }
                        *end_pid = 0;  // remove \n
//                      if the number of threads is < to about 40 % of the number of processes,
//                      the next "optimising" test actually produce a slower executable.
//                      if(procpids != atoi(tmp_pids))
                        {   // if the thread isn't the master thread (process)
//                            count++;          // DEBUG
                              sprintf(new_directory,"/proc/%s/task/%d", tmp_pids, procpids) ;
//                            printf("new_dir = %s\n", new_directory);   // DEBUG
                              statusdir = chdir(new_directory) ;
                              if (statusdir != 0) {
                              // the thread is not listed in the master thread task directory
                                    if(verbose) {
                                          snprintf(scratch, 1000, "Warning : Thread %d said it's in group %s but isn't listed in %s\n", procpids, tmp_pids, new_directory);
                                          fputs(scratch, stdout);
                                          if (logtofile == 1) {
                                                fputs(scratch, unlog);
                                          }
                                    }
                              }
                        }
                  }
                  else {
                        if(verbose) {
                              snprintf(scratch, 1000, "Warning : Can't find TGID in status file for process': %d)\n", procpids);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                  }
            }

            // unlock the proc directory so it can disappear if it's a transitory process
            chdir(curdir);

            if(checkps(procpids, PS_PROC | PS_THREAD)) {
                  continue;
            }

            // Avoid false positive on short life process/thread
            statusdir = chdir(directory) ;
            if (statusdir != 0) {
                  continue;
            }

            printbadpid(procpids);
      }
      // go back to our path
      chdir(curdir);
//    printf("Passages = %d\n", count);   // DEBUG
}

void checkopendir(void) {

      int procpids ;
      DIR *statusdir;
      char curdir[PATH_MAX] ;
      char directory[100] ;
//    char scratch[PATH_MAX] ;      // DEBUG
//    int count = 0;          //DEBUG

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through /proc opendir scanning\n\n");
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      // get the path where Unhide is ran from.
      getcwd(curdir, PATH_MAX);

      sprintf(directory,"/proc/");

      for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 ) {


            // avoid ourselves
            if (procpids == mypid) {
                  continue;
            }

            sprintf(&directory[6],"%d",procpids);

            statusdir = opendir(directory) ;
            // the directory doesn't exist continue with the next one
            if (statusdir == NULL)
                  continue;


            if (morecheck == TRUE) {
                  // find process group ID (the master thread) by reading the status file of the current dir
                  FILE* fich_tmp ;
                  int   found_tgid = FALSE;
                  char  line[128] ;
                  char* tmp_pids = line;
                  char* end_pid;
                  char  new_directory[100] ;
                  DIR*  statdir;

//                printf("directory = '%s'\n", directory);  // DEBUG
//                getcwd(scratch, PATH_MAX);                                  // DEBUG
//                printf("CWD = '%s'\n", scratch);                      // DEBUG

                  snprintf(line, 128, "%s/status", directory);
//                printf("STATUS_FILE : %s\n", line);
                  fich_tmp=fopen(line, "r") ;
                  if (fich_tmp == NULL) {
                        if(TRUE == verbose) {
                              snprintf(scratch, 1000, "Warning : can't open status file for process: %d)\n", procpids);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                        continue ; // next process
                  }
                  while ((FALSE == found_tgid) && (!feof (fich_tmp))) {

                        if (NULL != fgets (line, 128, fich_tmp)) {
                              line[127] = 0;
                              if (0 == strncmp (line, "Tgid:", 5)) {
                                    found_tgid = TRUE;
                              }
                        }
                  }
                  fclose(fich_tmp);

                  if (TRUE == found_tgid) {
                        tmp_pids = line + 5;
                        while( ((*tmp_pids == ' ') || (*tmp_pids == '\t'))  && (tmp_pids <= line+127)) {
                              tmp_pids++;
                        }
//                      printf("tmp_pids2 = '%s'\n", tmp_pids);   // DEBUG
                        end_pid = tmp_pids;
                        while( isdigit(*end_pid) && end_pid <= line+127) {
                              end_pid++;
                        }
                        *end_pid = 0;  // remove \n
//                      if the number of threads is < to about 40 % of the number of processes,
//                      the next "optimising" test actually produce a slower executable.
//                      if(procpids != atoi(tmp_pids))
                        {   // if the thread isn't the master thread (process)
//                            count++;          // DEBUG
                              sprintf(new_directory,"/proc/%s/task/%d", tmp_pids, procpids) ;
//                            printf("new_dir = %s\n", new_directory);   // DEBUG
                              errno = 0;
                              statdir = opendir(new_directory) ;
                              if (NULL == statdir) {
                              // the thread is not listed in the master thread task directory
//                                  printf("opendir failed : %s)\n", strerror(errno)) ;

                                    if(TRUE == verbose) {
                                          snprintf(scratch, 1000, "Warning : Thread %d said it's in group %s but isn't listed in %s\n", procpids, tmp_pids, new_directory);
                                          fputs(scratch, stdout);
                                          if (logtofile == 1) {
                                                fputs(scratch, unlog);
                                          }
                                    }
                              }
                              else {
                                    closedir(statdir);
                              }
                        }
                  }
                  else {
                        if(TRUE == verbose) {
                              snprintf(scratch, 1000, "Warning : Can't find TGID in status file for process': %d)\n", procpids);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                  }
            }

            // unlock the proc directory so it can disappear if it's a transitory process
            closedir(statusdir);

            if(checkps(procpids, PS_PROC | PS_THREAD)) {
                  continue;
            }

            // Avoid false positive on short life process/thread
            statusdir = opendir(directory) ;
            if (statusdir == NULL) {
                  continue;
            }
            // unlock dir & free descriptor
            closedir(statusdir);

            printbadpid(procpids);
      }
//    printf("Passages = %d\n", count);   // DEBUG
}


void checkreaddir(void) {

      int procpids ;
   DIR *procdir, *taskdir;
   struct dirent *dir, *dirproc;
      char task[100] ;

      snprintf(scratch, 1000, "[*]Searching for Hidden thread through /proc/pid/task readdir scanning\n\n");
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      procdir = opendir("/proc");
      if (NULL == procdir) {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : Cannot open /proc directory !\n");
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
            return ;
      }

      sprintf(task, "/proc/") ;

      while ((dirproc = readdir(procdir))) {
      // As of Linux kernel 2.6 :
      // readdir directly in /proc only see process, not thread
      // because procfs voluntary hides threads to readdir
            char *directory ;

            directory = dirproc->d_name;
            if(!isdigit(*directory)) {
                  // not a process directory of /proc
                  continue;
            }
//          sprintf(currentproc, "%d", directory);

            sprintf(&task[6], "%s/task", directory) ;
//          printf("task : %s", task) ; // DEBUG
            taskdir = opendir(task);
            if (NULL == taskdir) {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : Cannot open %s directory !\n", task);
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
                  return ;
            }

            while ((dir = readdir(taskdir)))
            {
                  char *tmp_d_name ;
                  tmp_d_name = dir->d_name;
//                printf(" thread : %s\n",tmp_d_name) ;  // DEBUG
                  if (!strcmp(tmp_d_name, ".") || !strcmp(tmp_d_name, "..")) // skip parent and current dir
                        continue;
                  if(!isdigit(*tmp_d_name)) {
                        if(verbose) {
                              snprintf(scratch, 1000, "Warning : Not a thread ID (%s) in %s\n", tmp_d_name, task);
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                        continue;
                  }
                  else if (0 != strcmp(tmp_d_name, directory)) { // thread ID is not the process ID
//                      printf("thread : %s\n",tmp_d_name) ;  // DEBUG
                        procpids = atoi(tmp_d_name) ;
                        if(checkps(procpids,PS_THREAD)) {
                              continue;
                        }
                        printbadpid(atoi(tmp_d_name));
                  }
                  else {
//                      printf("process : %s\n",tmp_d_name) ;  // DEBUG
                        procpids = atoi(tmp_d_name) ;
                        if(checkps(procpids,PS_PROC)) {
                              continue;
                        }
                        printbadpid(atoi(tmp_d_name));
                  }
            }
            closedir(taskdir);
      }
      closedir(procdir) ;
}

void checkgetpriority(void) {

      int syspids ;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through getpriority() scanning\n\n");
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int which = PRIO_PROCESS;

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = getpriority(which, syspids);
            if ( errno != 0) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno=0;
            ret = getpriority(which, syspids);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);
      }
}

void checkgetpgid(void) {

      int syspids ;


      snprintf(scratch, 1000, "[*]Searching for Hidden processes through getpgid() scanning\n\n");
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = getpgid(syspids);
            if ( errno != 0 ) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno=0;
            ret = getpgid(syspids);
            if ( errno != 0 ) {
                  continue;
            }

            printbadpid(syspids);
      }
}


void checkgetsid(void) {

      int syspids ;


      snprintf(scratch, 1000, "[*]Searching for Hidden processes through getsid() scanning\n\n");
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = getsid(syspids);
            if ( errno != 0) {
                  continue;
            }
            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }
            errno=0;
            ret = getsid(syspids);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);

      }
}


void checksched_getaffinity(void) {

      int syspids;
      cpu_set_t mask;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sched_getaffinity() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = sched_getaffinity(syspids, sizeof(cpu_set_t), &mask);
            if (errno != 0) {
                  continue;
            }
            if (checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }
            errno=0;
            ret = sched_getaffinity(syspids, sizeof(cpu_set_t), &mask);
            if (errno != 0) {
                  continue;
            }

            printbadpid(syspids);
      }
}


void checksched_getparam(void) {

      int syspids;
      struct sched_param param;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sched_getparam() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }


      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = sched_getparam(syspids, &param);
            if ( errno != 0) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno=0;
            ret = sched_getparam(syspids, &param);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);

      }
}

void checksched_getscheduler(void) {

      int syspids ;


      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sched_getscheduler() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = sched_getscheduler(syspids);
            if ( errno != 0) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno=0;
            ret = sched_getscheduler(syspids);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);

      }
}

void checksched_rr_get_interval(void) {

      int syspids;
      struct timespec tp;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sched_rr_get_interval() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = sched_rr_get_interval(syspids, &tp);
            if ( errno != 0) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno=0;
            ret = sched_rr_get_interval(syspids, &tp);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);
      }
}

void checkkill(void) {

      int syspids;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through kill(..,0) scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

            int ret;

            errno= 0 ;

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            ret = kill(syspids, 0);
            if ( errno != 0) {
                  continue;
            }

            if(checkps(syspids,PS_PROC | PS_THREAD)) {
                  continue;
            }

            errno= 0 ;
            ret = kill(syspids, 0);
            if ( errno != 0) {
                  continue;
            }

            printbadpid(syspids);
      }
}

void checkallnoprocps(void) {

      /* compare the various system calls against each other,
       * without invoking 'ps' or looking at /proc */

      int ret;
      int syspids;
      struct timespec tp;
      struct sched_param param;
      cpu_set_t mask;
      int found=0;
      int found_killbefore=0;
      int found_killafter=0;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through  comparison of results of system calls\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      for ( syspids = 1; syspids <= maxpid; syspids++ ) {

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            found=0;
            found_killbefore=0;
            found_killafter=0;

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killbefore=1;

            errno= 0 ;
            ret = getpriority(PRIO_PROCESS, syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = getpgid(syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = getsid(syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = sched_getaffinity(syspids, sizeof(cpu_set_t), &mask);
            if (ret == 0) found++;

            errno= 0 ;
            ret = sched_getparam(syspids, &param);
            if (errno == 0) found++;

            errno= 0 ;
            ret = sched_getscheduler(syspids);
            if (errno == 0) found++;

            errno=0;
            ret = sched_rr_get_interval(syspids, &tp);
            if (errno == 0) found++;

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killafter=1;


            /* these should all agree, except if a process went or came in the middle */
            if (found_killbefore == found_killafter) {
                  if ( ! ((found_killbefore == 0 && found == 0) ||
                                (found_killbefore == 1 && found == 7)) ) {
                        printbadpid(syspids);
                  }
            } /* else: unreliable */
            else {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : syscall comparison test skipped for PID %d\n", syspids) ;
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
            }
      }
}

void checkallquick(void) {

      /* compare the various system calls against each other,
       * without invoking 'ps' or looking at /proc */

      int ret;
      int syspids;
      struct timespec tp;
      struct sched_param param;
      cpu_set_t mask;
      int found=0;
      int found_killbefore=0;
      int found_killafter=0;
      char directory[100];
      struct stat buffer;
      int statusproc, statusdir;
      char curdir[PATH_MAX] ;
      DIR *dir_fd;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through  comparison of results of system calls, proc, dir and ps\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      // get the path where Unhide is ran from.
      getcwd(curdir, PATH_MAX);

      sprintf(directory,"/proc/");

      for ( syspids = 1; syspids <= maxpid; syspids++ ) {

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            // printf("syspid = %d\n", syspids); //DEBUG

            found=0;
            found_killbefore=0;
            found_killafter=0;

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killbefore=1;

            errno= 0 ;
            ret = getpriority(PRIO_PROCESS, syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = getpgid(syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = getsid(syspids);
            if (errno == 0) found++;

            errno= 0 ;
            ret = sched_getaffinity(syspids, sizeof(cpu_set_t), &mask);
            if (ret == 0) found++;

            errno= 0 ;
            ret = sched_getparam(syspids, &param);
            if (errno == 0) found++;

            errno= 0 ;
            ret = sched_getscheduler(syspids);
            if (errno == 0) found++;

            errno=0;
            ret = sched_rr_get_interval(syspids, &tp);
            if (errno == 0) found++;

            sprintf(&directory[6],"%d",syspids);

            statusproc = stat(directory, &buffer) ;
            if (statusproc == 0) {
                  found++;
            }

            statusdir = chdir(directory) ;
            if (statusdir == 0) {
                  found++;
                  chdir(curdir);
            }

            dir_fd = opendir(directory) ;
            if (NULL != dir_fd) {
                  found++;
                  closedir(dir_fd);
            }

            // Avoid checkps call if nobody sees anything
            if ((0 != found) || (0 != found_killbefore)) {
                  if(checkps(syspids,PS_PROC | PS_THREAD)) {
                        found++;
                  }
            }

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killafter=1;


            /* these should all agree, except if a process went or came in the middle */
            if (found_killbefore == found_killafter) {
                  if ( ! ((found_killbefore == 0 && found == 0) ||
                                (found_killbefore == 1 && found == 11)) ) {
                        printbadpid(syspids);
                  }
            } /* else: unreliable */
            else {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : syscall comparison test skipped for PID %d\n", syspids) ;
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
            }
      }
}

void checkallreverse(void) {

      /* verify if all thread showed by ps are also seen by others */

      int ret;
      int syspids;
      struct timespec tp;
      struct sched_param param;
      cpu_set_t mask;
      int not_seen=0;
      int found_killbefore=0;
      int found_killafter=0;
      FILE *fich_tmp;
      char command[50];
      char read_line[1024];
      char lwp[7];
      int  index;
      char directory[100];
      struct stat buffer;
      int statusproc, statusdir;
      char curdir[PATH_MAX] ;
      DIR *dir_fd;

      snprintf(scratch, 1000, "[*]Searching for Fake processes by verifying that all threads seen by ps are also seen by others\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      sprintf(command,REVERSE) ;

      fich_tmp=popen (command, "r") ;
      if (fich_tmp == NULL) {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : popen failed while running ps (memory, or something set errno: %s)\n", strerror(errno)) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
            return;
      }
      // get the path where Unhide is ran from.
      getcwd(curdir, PATH_MAX);

      strcpy(directory,"/proc/");

      while (!feof(fich_tmp)) {
            char* curline = read_line;

            if (NULL == fgets(read_line, 1024, fich_tmp))
                  continue;;
            read_line[1023] = 0;
            read_line[strlen(read_line)-1] = 0;

//          printf("read_line = %s\n", read_line);   // DEBUG
            while( *curline == ' ' && curline <= read_line+1023) {
                  curline++;
            }

            // get LWP
            index=0;
            while( isdigit(*curline) && curline <= read_line+1023) {
                  lwp[index++] = *curline;
                  curline++;
            }
            lwp[index] = 0; // terminate string

            syspids = -1;
            syspids = atol(lwp);
            if (-1 == syspids) continue ; // something went wrong

            // avoid ourselves
            if (syspids == mypid) {
                  continue;
            }

            not_seen=0;
            found_killbefore=0;
            found_killafter=0;

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killbefore=1;

            strcpy(&directory[6],lwp);

            statusproc = stat(directory, &buffer) ;
            if (statusproc != 0) {
                  not_seen++;
            }

            statusdir = chdir(directory) ;
            if (statusdir != 0) {
                  not_seen++;
            }
            else {
                  chdir(curdir);
            }

            dir_fd = opendir(directory) ;
            if (NULL == dir_fd) {
                  not_seen++;
            }
            else {
                  closedir(dir_fd);
            }

            errno= 0 ;
            ret = getpriority(PRIO_PROCESS, syspids);
            if (errno != 0) not_seen++;

            errno= 0 ;
            ret = getpgid(syspids);
            if (errno != 0) not_seen++;

            errno= 0 ;
            ret = getsid(syspids);
            if (errno != 0) not_seen++;

            errno= 0 ;
            ret = sched_getaffinity(syspids, sizeof(cpu_set_t), &mask);
            if (ret != 0) not_seen++;

            errno= 0 ;
            ret = sched_getparam(syspids, &param);
            if (errno != 0) not_seen++;

            errno= 0 ;
            ret = sched_getscheduler(syspids);
            if (errno != 0) not_seen++;

            errno=0;
            ret = sched_rr_get_interval(syspids, &tp);
            if (errno != 0) not_seen++;

            errno=0;
            ret = kill(syspids, 0);
            if (errno == 0) found_killafter=1;

//          printf("FK_bef = %d FK_aft = %d not_seen = %d\n",found_killbefore, found_killafter, not_seen);  //DEBUG
            /* these should all agree, except if a process went or came in the middle */
            if (found_killbefore == found_killafter) {
                  if (found_killafter == 1) {
                        if (0 != not_seen) {
                              if (NULL == strstr(curline, REVERSE)) {  // avoid our spawn ps
                                    // printbadpid should NOT be used here : we are looking for faked process
                                    snprintf(scratch, 1000, "Found FAKE PID: %i\tCommand = %s not seen by %d sys func\n", syspids, curline, not_seen) ;
                                    fputs(scratch, stdout);
                                    if (logtofile == 1) {
                                          fputs(scratch, unlog);
                                    }

                                    found_HP = 1;
                              }
                        }
                  }
                  else {
                        if (NULL == strstr(curline, REVERSE)) {  // avoid our spawned ps
                              // printbadpid should NOT be used here : we are looking for faked process
                              snprintf(scratch, 1000, "Found FAKE PID: %i\tCommand = %s not seen by %d sys fonc\n", syspids, curline, not_seen + 2) ;
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }

                              found_HP = 1;
                        }
                  }
            } /* else: unreliable */
            else {
                  if(verbose) {
                        snprintf(scratch, 1000, "Warning : reverse test skipped for PID %d\n", syspids) ;
                        fputs(scratch, stdout);
                        if (logtofile == 1) {
                              fputs(scratch, unlog);
                        }
                  }
            }
      }

      if (fich_tmp != NULL)
            pclose(fich_tmp);

}

void checksysinfo(void) {

      struct sysinfo info;
      int contador=0;
      int resultado_antes=0;
      int resultado_despues=0;
      int resultado = 0;
      int ocultos=0;
      char buffer[500];

      FILE *fich_proceso ;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sysinfo() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      buffer[499] = '\0';

      sysinfo(&info);
      resultado = resultado_antes=info.procs;

      fich_proceso=popen (SYS_COMMAND, "r") ;
      if (fich_proceso == NULL) {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : popen failed while checking sysinfo (memory, or something set errno: %s)\n", strerror(errno)) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
            return;
      }

      while (!feof(fich_proceso)) {

            if (NULL != fgets(buffer, 499, fich_proceso)) {
                  contador++;
                  if(verbose) {
                        sysinfo(&info);
                        if (resultado != info.procs) {
                              snprintf(scratch, 1000, "\t\tWARNING : info.procs changed during test : %d (was %d)\n",info.procs,resultado) ;
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                              resultado = info.procs;
                        }
                        if (verbose >=2) {
                              buffer[strlen(buffer)-1] = 0;  // get rid of \n
                              snprintf(scratch, 1000, "\"%s\"\n",buffer) ;
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                  }
            }
      }
      pclose(fich_proceso);

      sysinfo(&info);
      resultado_despues=info.procs;
      if(verbose >= 1) {
            if (resultado != resultado_despues) {
                  snprintf(scratch, 1000, "\t\tWARNING : info.procs changed during test : %d (was %d)\n",resultado_despues,resultado) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
      }


      if (resultado_antes == resultado_despues) {  /* otherwise intermittent activity.. */

            //    We add one as ps sees itself and not sysinfo.
            ocultos=resultado_despues  + 1 - contador ;

            if (ocultos != 0) {
                  snprintf(scratch, 1000, "HIDDEN Processes Found: %i\tsysinfo.procs = %d   ps_count = %d\n",abs(ocultos), resultado_despues,contador) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
                  found_HP = 1;
            }
      }
      else {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : sysinfo test skipped due to intermittent activity\n") ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
      }

}


void checksysinfo2() {

      struct sysinfo info;
      int contador=0;
      int resultado_antes=0;
      int resultado_despues=0;
      int resultado = 0;
      int ocultos=0;
      char buffer[500];

      FILE *fich_proceso ;

      snprintf(scratch, 1000, "[*]Searching for Hidden processes through sysinfo() scanning\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      buffer[499] = '\0';

      fich_proceso=popen (SYS_COMMAND, "r") ;
      if (fich_proceso == NULL) {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : popen failed while checking sysinfo (memory, or something set errno: %s)\n", strerror(errno)) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
            return;
      }

      sysinfo(&info);
      resultado = resultado_antes = info.procs;

      while (!feof(fich_proceso)) {

            if (NULL != fgets(buffer, 499, fich_proceso)) {
                  contador++;
                  if(verbose) {
                        sysinfo(&info);                                       // DEBUG
                        if (resultado != info.procs) {            // DEBUG
                              snprintf(scratch, 1000, "\t\tWARNING : info.procs changed during test : %d (was %d)\n",info.procs,resultado) ;
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                              resultado = info.procs;                   // DEBUG
                        }
                        if (verbose >=2) {
                              buffer[strlen(buffer)-1] = 0;  // get rid of \n
                              snprintf(scratch, 1000, "\"%s\"\n",buffer) ;
                              fputs(scratch, stdout);
                              if (logtofile == 1) {
                                    fputs(scratch, unlog);
                              }
                        }
                  }
            }
      }

      sysinfo(&info);
      resultado_despues=info.procs;
      if(verbose >= 1) {
            if (resultado != resultado_despues) {
                  snprintf(scratch, 1000, "\t\tWARNING : info.procs changed during test : %d (was %d)\n",resultado_despues,resultado) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
      }

      pclose(fich_proceso);

      if (resultado_antes == resultado_despues) {  /* otherwise intermittent activity.. */

            ocultos=resultado_despues - contador;

            if (ocultos != 0) {
                  snprintf(scratch, 1000, "HIDDEN Processes Found: %i\tsysinfo.procs = %d   ps_count = %d\n",abs(ocultos), resultado_despues,contador) ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }

                  found_HP = 1;
            }
      }
      else {
            if(verbose) {
                  snprintf(scratch, 1000, "Warning : sysinfo test skipped due to intermittent activity\n") ;
                  fputs(scratch, stdout);
                  if (logtofile == 1) {
                        fputs(scratch, unlog);
                  }
            }
      }

}




void brute(void) {

      int i=0;
      int allpids[maxpid] ;
      int x;
      int y;
      int z;

      snprintf(scratch, 1000, "[*]Starting scanning using brute force against PIDS with fork()\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      // PID under 300 are reserved for kernel
      for(x=0; x < 300; x++) {

            allpids[x] = 0 ;
      }


      for(z=300; z < maxpid; z++) {

            allpids[z] = z ;
      }


      for (i=300; i < maxpid; i++) {
            int vpid;
            int status;

            errno= 0 ;

            if ((vpid = vfork()) == 0) {

//           allpids[getpid()] =  0;

             _exit(0);
            }

            if (0 == errno) {
                  allpids[vpid] =  0;
                  waitpid(vpid, &status, 0);
            }
      }

      /* processes that quit at this point in time create false positives */

      for(y=0; y < maxpid; y++) {

            if (allpids[y] != 0) {

                  if(!checkps(allpids[y],PS_PROC | PS_THREAD | PS_MORE) ) {

                        printbadpid(allpids[y]);

                  }
            }

      }


      snprintf(scratch, 1000, "[*]Starting scanning using brute force against PIDS with pthread functions\n\n") ;
      fputs(scratch, stdout);
      if (logtofile == 1) {
            fputs(scratch, unlog);
      }

      // PID under 300 are reserved for kernel
      for(x=0; x < 300; x++) {

            allpids[x] = 0 ;
      }


      for(z=300; z < maxpid; z++) {

            allpids[z] = z ;
      }


      for (i=300; i < maxpid ; i++) {
            void *status;

            errno= 0 ;

            pthread_t idHilo;

            int error;

            error = pthread_create (&idHilo, NULL, funcionThread, NULL);

            if (error != 0)
            {
                  perror ("Warning : Cannot create thread !\n");
                  exit (-1);
            }

            error = pthread_join(idHilo, &status);

            if (error != 0)
            {
                  perror ("Warning : Cannot join thread !\n");
                  exit (-1);
            }

            allpids[tid] =  0;

      }

      /* processes that quit at this point in time create false positives */

      for(y=0; y < maxpid; y++) {

            if (allpids[y] != 0) {

                  if(!checkps(allpids[y],PS_PROC | PS_THREAD | PS_MORE) ) {

                        printbadpid(allpids[y]);

                  }
            }

      }

}

void usage(char * command) {

      printf("Usage: %s [options] test_list\n\n", command);
      printf("Option :\n");
      printf("   -V          Show version and exit\n");
      printf("   -v          verbose\n");
      printf("   -h          display this help\n");
      printf("   -m          more checks (available only with procfs command)\n");
      printf("   -r          use alternate sysinfo test in meta-test\n");
      printf("   -f          log result into unhide.log file\n");
      printf("Test_list :\n");
      printf("   Test_list is one or more of the following\n");
      printf("   Standard tests :\n");
      printf("      brute\n");
      printf("      proc\n");
      printf("      procall\n");
      printf("      procfs\n");
      printf("      quick\n");
      printf("      reverse\n");
      printf("      sys\n");
      printf("   Elementary tests :\n");
      printf("      checkbrute\n");
      printf("      checkchdir\n");
      printf("      checkgetaffinity\n");
      printf("      checkgetparam\n");
      printf("      checkgetpgid\n");
      printf("      checkgetprio\n");
      printf("      checkRRgetinterval\n");
      printf("      checkgetsched\n");
      printf("      checkgetsid\n");
      printf("      checkkill\n");
      printf("      checknoprocps\n");
      printf("      checkopendir\n");
      printf("      checkproc\n");
      printf("      checkquick\n");
      printf("      checkreaddir\n");
      printf("      checkreverse\n");
      printf("      checksysinfo\n");
      printf("      checksysinfo2\n");
}


int main (int argc, char *argv[]) {

int i;
struct tab_test_t tab_test[MAX_TESTNUM];

      strncpy(scratch,"Unhide 20110113\n", 1000) ;
      strncat(scratch, "http://www.unhide-forensics.info\n", 1000);
      fputs(scratch, stdout);

      // Initialize the table of test to do.
      // ----------------------------------
      for (i=0 ; i<MAX_TESTNUM ; i++) {
            tab_test[i].todo = FALSE;
            tab_test[i].func = NULL;
      }
      tab_test[TST_PROC].func = checkproc;
      tab_test[TST_CHDIR].func = checkchdir;
      tab_test[TST_OPENDIR].func = checkopendir;
      tab_test[TST_READDIR].func = checkreaddir;
      tab_test[TST_GETPRIO].func = checkgetpriority;
      tab_test[TST_GETPGID].func = checkgetpgid;
      tab_test[TST_GETSID].func = checkgetsid;
      tab_test[TST_GETAFF].func = checksched_getaffinity;
      tab_test[TST_GETPARM].func = checksched_getparam;
      tab_test[TST_GETSCHED].func = checksched_getscheduler;
      tab_test[TST_RR_INT].func = checksched_rr_get_interval;
      tab_test[TST_KILL].func = checkkill;
      tab_test[TST_NOPROCPS].func = checkallnoprocps;
      tab_test[TST_BRUTE].func = brute;
      tab_test[TST_REVERSE].func = checkallreverse;
      tab_test[TST_QUICKONLY].func = checkallquick;
      tab_test[TST_SYS_INFO].func = checksysinfo;
      tab_test[TST_SYS_INFO2].func = checksysinfo2;


      //    get the number max of processes on the system.
      // ---------------------------------------------
      get_max_pid(&maxpid);

      // analyse argument
      // ----------------
      if(argc < 2) {
            usage(argv[0]);
            exit (1);
      }

      for (i=1 ; i<argc ; i++) {
            if (strcmp(argv[i], "-V") == 0) {
                  return 0;
            }
            else if (strcmp(argv[i], "-v") == 0) {
                  verbose++;
            }
            else if (strcmp(argv[i], "-h") == 0) {
                  usage(argv[0]);
                  return 0;
            }
            else if (strcmp(argv[i], "-m") == 0) {
                  morecheck = TRUE;
                  verbose = TRUE;
            }
            else if (strcmp(argv[i], "-r") == 0) {
                  RTsys = TRUE;
            }
            else if (strcmp(argv[i], "-f") == 0) {
                  logtofile = 1;
            }
            else if ((strcmp(argv[i], "proc") == 0) ||
                              (strcmp(argv[i], "checkproc") == 0)) {
                  tab_test[TST_PROC].todo = TRUE;
            }
            else if (strcmp(argv[i], "procfs") == 0) {
                  tab_test[TST_CHDIR].todo = TRUE;
                  tab_test[TST_OPENDIR].todo = TRUE;
                  tab_test[TST_READDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "procall") == 0) {
                  tab_test[TST_PROC].todo = TRUE;
                  tab_test[TST_CHDIR].todo = TRUE;
                  tab_test[TST_OPENDIR].todo = TRUE;
                  tab_test[TST_READDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "sys") == 0) {
                  tab_test[TST_KILL].todo = TRUE;
                  tab_test[TST_NOPROCPS].todo = TRUE;
                  tab_test[TST_GETPRIO].todo = TRUE;
                  tab_test[TST_GETPGID].todo = TRUE;
                  tab_test[TST_GETSID].todo = TRUE;
                  tab_test[TST_GETAFF].todo = TRUE;
                  tab_test[TST_GETPARM].todo = TRUE;
                  tab_test[TST_GETSCHED].todo = TRUE;
                  tab_test[TST_RR_INT].todo = TRUE;
                  if (TRUE == RTsys) {
                        tab_test[TST_SYS_INFO2].todo = TRUE;
                  }
                  else {
                        tab_test[TST_SYS_INFO].todo = TRUE;
                  }
            }
            else if (strcmp(argv[i], "quick") == 0) {
                  tab_test[TST_QUICKONLY].todo = TRUE;
                  if (TRUE == RTsys) {
                        tab_test[TST_SYS_INFO2].todo = TRUE;
                  }
                  else {
                        tab_test[TST_SYS_INFO].todo = TRUE;
                  }
            }
            else if ((strcmp(argv[i], "brute") == 0) ||
                              (strcmp(argv[i], "checkbrute") == 0)) {
                  tab_test[TST_BRUTE].todo = TRUE;
            }
            else if ((strcmp(argv[i], "reverse") == 0) ||
                              (strcmp(argv[i], "checkreverse") == 0)) {
                  tab_test[TST_REVERSE].todo = TRUE;
            }
            else if (strcmp(argv[i], "opendir") == 0) {
                  tab_test[TST_OPENDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkquick") == 0) {
                  tab_test[TST_QUICKONLY].todo = TRUE;
            }
            else if (strcmp(argv[i], "checksysinfo") == 0) {
                  tab_test[TST_SYS_INFO].todo = TRUE;
            }
            else if (strcmp(argv[i], "checksysinfo2") == 0) {
                  tab_test[TST_SYS_INFO2].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkchdir") == 0) {
                  tab_test[TST_CHDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkreaddir") == 0) {
                  tab_test[TST_READDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkopendir") == 0) {
                  tab_test[TST_OPENDIR].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkkill") == 0) {
                  tab_test[TST_KILL].todo = TRUE;
            }
            else if (strcmp(argv[i], "checknoprocps") == 0) {
                  tab_test[TST_NOPROCPS].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetprio") == 0) {
                  tab_test[TST_GETPRIO].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetpgid") == 0) {
                  tab_test[TST_GETPGID].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetsid") == 0) {
                  tab_test[TST_GETSID].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetaffinity") == 0) {
                  tab_test[TST_GETAFF].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetparam") == 0) {
                  tab_test[TST_GETPARM].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkgetsched") == 0) {
                  tab_test[TST_GETSCHED].todo = TRUE;
            }
            else if (strcmp(argv[i], "checkRRgetinterval") == 0) {
                  tab_test[TST_RR_INT].todo = TRUE;
            }
            else { printf("Unknown argument\n") ; usage(argv[0]); exit(0);}
      }


      if (logtofile == 1) {

            unlog = fopen("unhide.log", "w");

      if (NULL != unlog) {
                  fputs(scratch, unlog); // Scratch contains the start header here.

                  time_t scantime;
                  char cad[80];
                  struct tm *tmPtr;

                  scantime = time(NULL);
                  tmPtr = localtime(&scantime);
                  strftime( cad, 80, "%H:%M.%S, %F", tmPtr );

                  fprintf(unlog, "Unhide Scan starting at: %s\n", cad );
            }
            else
            {
                  logtofile = 0; // inhibit write to log file
                  printf("WARNING : Unable to open log file !");
            }

      }

      setpriority(PRIO_PROCESS,0,-20);  /* reduce risk from intermittent processes - may fail, dont care */

      mypid = getpid();

      // Execute required tests.
      // ----------------------
      for (i=0 ; i<MAX_TESTNUM ; i++) {
            if ((tab_test[i].todo == TRUE) && (tab_test[i].func != NULL))
                  tab_test[i].func();
      }

      if (logtofile == 1) {
            time_t scantime;
            char cad[80];
            struct tm *tmPtr;

            scantime = time(NULL);
            tmPtr = localtime(&scantime);
            strftime( cad, 80, "%H:%M.%S, %F", tmPtr );

            fprintf(unlog, "Unhide Scan ending at: %s\n", cad );
            fclose(unlog);
      }

      return found_HP;
}

Generated by  Doxygen 1.6.0   Back to index