2
http://sourceforge.net/projects/unhide/
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>.
20
// Needed for unistd.h to declare getpgid() and others
21
#define _XOPEN_SOURCE 500
23
// Needed for sched.h to declare sched_getaffinity()
31
#include <sys/resource.h>
35
#include <sys/types.h>
38
#include <sys/sysinfo.h>
41
#include <sys/syscall.h>
45
#include "unhide-output.h"
46
#include "unhide-linux.h"
50
* Check all the PID stat() see in /proc.
56
int statusprocbefore, statusprocafter;
60
msgln(unlog, 0, "[*]Searching for Hidden processes through /proc stat scanning\n") ;
62
sprintf(directory,"/proc/");
64
for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 )
67
if (procpids == mypid)
71
sprintf(&directory[6],"%d",procpids);
73
statusprocbefore = stat(directory, &buffer) ;
74
if (statusprocbefore != 0)
79
if(checkps(procpids,PS_PROC | PS_THREAD))
84
statusprocafter = stat(directory, &buffer) ;
85
if (statusprocafter != 0)
90
printbadpid(procpids);
95
* Check all the pid that chdir() see in /proc.
101
int statusdir, backtodir;
102
char curdir[PATH_MAX], *pathpt ;
103
char directory[100] ;
104
// char scratch[PATH_MAX] ; // DEBUG
105
// int count = 0; //DEBUG
107
msgln(unlog, 0, "[*]Searching for Hidden processes through /proc chdir scanning\n") ;
109
// get the path where Unhide is ran from.
110
if (NULL == (pathpt = getcwd(curdir, PATH_MAX)))
112
warnln(verbose, unlog, "Can't get current directory, test aborted") ;
116
sprintf(directory,"/proc/");
118
for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 )
121
if (procpids == mypid)
126
sprintf(&directory[6],"%d",procpids);
127
statusdir = chdir(directory) ;
128
// the directory doesn't exist continue with the next one
133
if (morecheck == TRUE)
135
// find process group ID (the master thread) by reading the status file of the current dir
137
int found_tgid = FALSE;
139
char* tmp_pids = line;
141
char new_directory[100];
143
// printf("directory = '%s'\n", directory); // DEBUG
144
// getcwd(scratch, PATH_MAX); // DEBUG
145
// printf("CWD = '%s'\n", scratch); // DEBUG
147
// we are in the /proc/pid directory
148
fich_tmp=fopen("status", "r") ;
149
if (NULL == fich_tmp)
151
warnln(verbose, unlog, "can't open status file for process: %d", procpids) ;
152
continue ; // next process
154
while ((FALSE == found_tgid) && (NULL != fgets (line, 128, fich_tmp)))
157
if (0 == strncmp (line, "Tgid:", 5))
164
if (TRUE == found_tgid)
167
while( ((*tmp_pids == ' ') || (*tmp_pids == '\t')) && (tmp_pids <= line+127))
171
// printf("tmp_pids2 = '%s'\n", tmp_pids); // DEBUG
173
while( isdigit(*end_pid) && end_pid <= line+127)
177
*end_pid = 0; // remove \n
178
// if the number of threads is < to about 40 % of the number of processes,
179
// the next "optimising" test actually produce a slower executable.
180
// if(procpids != atoi(tmp_pids))
181
{ // if the thread isn't the master thread (process)
183
sprintf(new_directory,"/proc/%s/task/%d", tmp_pids, procpids) ;
184
// printf("new_dir = %s\n", new_directory); // DEBUG
185
statusdir = chdir(new_directory) ;
188
// the thread is not listed in the master thread task directory
190
warnln(1, unlog, "Thread %d said it's in group %s but isn't listed in %s", procpids, tmp_pids, new_directory) ;
197
warnln(1, unlog, "Can't find TGID in status file for process: %d", procpids) ;
201
// unlock the proc directory so it can disappear if it's a transitory process
202
if (-1 == (backtodir = chdir(curdir)))
204
warnln(verbose, unlog, "Can't go back to unhide directory, test aborted") ;
208
if(checkps(procpids, PS_PROC | PS_THREAD))
213
// Avoid false positive on short life process/thread
214
statusdir = chdir(directory) ;
220
printbadpid(procpids);
222
// go back to our path
223
if (-1 == (backtodir = chdir(curdir)))
225
warnln(verbose, unlog, "Can't go back to unhide directory, test aborted") ;
228
// printf("Passages = %d\n", count); // DEBUG
232
* Check all the pid that opendir() see in /proc.
234
void checkopendir(void)
239
// char curdir[PATH_MAX] ;
240
char directory[100] ;
241
// char scratch[PATH_MAX] ; // DEBUG
242
// int count = 0; //DEBUG
244
msgln(unlog, 0, "[*]Searching for Hidden processes through /proc opendir scanning\n") ;
246
sprintf(directory,"/proc/");
248
for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 )
251
if (procpids == mypid)
256
sprintf(&directory[6],"%d",procpids);
257
statusdir = opendir(directory) ;
258
// the directory doesn't exist continue with the next one
259
if (statusdir == NULL)
262
if (morecheck == TRUE)
264
// find process group ID (the master thread) by reading the status file of the current dir
266
int found_tgid = FALSE;
268
char* tmp_pids = line;
270
char new_directory[100] ;
273
// printf("directory = '%s'\n", directory); // DEBUG
274
// getcwd(scratch, PATH_MAX); // DEBUG
275
// printf("CWD = '%s'\n", scratch); // DEBUG
277
snprintf(line, 128, "%s/status", directory);
278
// printf("STATUS_FILE : %s\n", line);
279
fich_tmp=fopen(line, "r") ;
280
if (NULL == fich_tmp)
282
msgln(unlog, 0, "Can't open status file for process: %d", procpids) ;
283
continue ; // next process
285
while ((FALSE == found_tgid) && (NULL != fgets (line, 128, fich_tmp)))
288
if (0 == strncmp (line, "Tgid:", 5))
295
if (TRUE == found_tgid)
298
while( ((*tmp_pids == ' ') || (*tmp_pids == '\t')) && (tmp_pids <= line+127))
302
// printf("tmp_pids2 = '%s'\n", tmp_pids); // DEBUG
304
while( isdigit(*end_pid) && end_pid <= line+127)
308
*end_pid = 0; // remove \n
309
// if the number of threads is < to about 40 % of the number of processes,
310
// the next "optimising" test actually produce a slower executable.
311
// if(procpids != atoi(tmp_pids))
312
{ // if the thread isn't the master thread (process)
314
sprintf(new_directory,"/proc/%s/task/%d", tmp_pids, procpids) ;
315
// printf("new_dir = %s\n", new_directory); // DEBUG
317
statdir = opendir(new_directory) ;
320
// the thread is not listed in the master thread task directory
321
// printf("opendir failed : %s)\n", strerror(errno)) ;
323
warnln(1, unlog, "Thread %d said it's in group %s but isn't listed in %s", procpids, tmp_pids, new_directory) ;
334
warnln(1, unlog, "Can't find TGID in status file for process: %d", procpids) ;
338
// unlock the proc directory so it can disappear if it's a transitory process
341
if(checkps(procpids, PS_PROC | PS_THREAD)) {
345
// Avoid false positive on short life process/thread
346
statusdir = opendir(directory) ;
347
if (statusdir == NULL) {
350
// unlock dir & free descriptor
353
printbadpid(procpids);
355
// printf("Passages = %d\n", count); // DEBUG
359
* Check all the pid that readdir() see in all /proc/pid/task.
361
void checkreaddir(void)
365
DIR *procdir, *taskdir;
366
struct dirent *dir, *dirproc;
369
msgln(unlog, 0, "[*]Searching for Hidden thread through /proc/pid/task readdir scanning\n") ;
371
procdir = opendir("/proc");
374
warnln(verbose, unlog, "Cannot open /proc directory ! Exiting test.") ;
378
sprintf(task, "/proc/") ;
380
while ((dirproc = readdir(procdir)))
382
// As of Linux kernel 2.6 :
383
// readdir directly in /proc only see process, not thread
384
// because procfs voluntary hides threads to readdir
387
directory = dirproc->d_name;
388
if(!isdigit(*directory))
390
// not a process directory of /proc
393
// sprintf(currentproc, "%d", directory);
395
sprintf(&task[6], "%s/task", directory) ;
396
// printf("task : %s", task) ; // DEBUG
397
taskdir = opendir(task);
400
warnln(verbose, unlog, "Cannot open %s directory ! ! Skipping process %s.", task, directory) ;
404
while ((dir = readdir(taskdir)))
407
tmp_d_name = dir->d_name;
408
// printf(" thread : %s\n",tmp_d_name) ; // DEBUG
409
if (!strcmp(tmp_d_name, ".") || !strcmp(tmp_d_name, "..")) // skip parent and current dir
411
if(!isdigit(*tmp_d_name))
414
warnln(verbose, unlog, "Not a thread ID (%s) in %s.", tmp_d_name, task) ;
417
else if (0 != strcmp(tmp_d_name, directory)) { // thread ID is not the process ID
418
// printf("thread : %s\n",tmp_d_name) ; // DEBUG
419
procpids = atoi(tmp_d_name) ;
420
if(checkps(procpids,PS_THREAD)) {
423
printbadpid(atoi(tmp_d_name));
426
// printf("process : %s\n",tmp_d_name) ; // DEBUG
427
procpids = atoi(tmp_d_name) ;
428
if(checkps(procpids,PS_PROC)) {
431
printbadpid(atoi(tmp_d_name));