Psreal.c for Linux kernel 2.4.x finds processes hidden even if a LKM is used.
907abc05ba6db4ba3e3da65a20995507c4791b01b80ce282d259be8edd58aabc
/*
* ghQst - ElectronicSouls
* tool to find hidden processes
* works on 2.4.x kernels
*
* compile like this:
* gcc -o psreal psreal.c -I/usr/src/linux/include/linux
*/
#define __KERNEL__
#include <linux/sched.h>
#undef __KERNEL__
#include <stdio.h>
#include <errno.h>
#define TASKSYMBOL "init_task_union"
#define MAXPIDS 1024
unsigned long findtasksymbol(char *tasksymbol);
int checkproc(int pid);
int createpidlist(int *pidlist, int len);
int checkpidlist(int pid, int *pidlist, int len);
int main(int argc, char *argv[])
{
int pidlist[MAXPIDS];
struct task_struct task;
char *tasksymb = TASKSYMBOL;
unsigned long inittask, nexttask;
int fd, rt, lstpid;
if (argc > 2) {
fprintf(stderr, "usage:\t%s <tasksymbol>\n", argv[0]); exit(1);
}
if (argc > 1) tasksymb = argv[1];
lstpid = createpidlist(pidlist, MAXPIDS);
if (lstpid == -1) return -1;
if (lstpid >= MAXPIDS) {
fprintf(stderr, "%s:\tpid buffer to small\n", argv[0]); exit(1);
}
inittask = findtasksymbol(tasksymb);
if (inittask == -1) {
fprintf(stderr, "%s:\tcouldnt find task symbol\n", argv[0]); exit(1);
}
printf("symbol %s found: 0x%.8x\n", tasksymb, inittask);
fd = open("/dev/kmem", O_RDONLY);
if (fd == -1) {
perror("open"); exit(1);
}
nexttask = inittask;
while (nexttask) {
rt = lseek(fd, nexttask, SEEK_SET);
if (rt != nexttask) {
perror("lseek"); exit(1);
}
rt = read(fd, &task, sizeof(task));
if (rt < 0) {
perror("read"); exit(1);
}
if (checkproc(task.pid)) {
printf("- process %u (%s) hidden by the kernel\n", task.pid, task.comm);
} else if (checkpidlist(task.pid, pidlist, lstpid)) {
printf("- process %u (%s) hidden by ps\n", task.pid, task.comm);
}
nexttask = (unsigned long)task.next_task;
if (nexttask == inittask) break;
}
close(fd);
return 0;
}
unsigned long findtasksymbol(char *tasksymbol)
{
unsigned long addr;
char buffer[1024];
FILE *ksyms;
char *p;
ksyms = fopen("/proc/ksyms", "r");
if (ksyms == NULL) {
perror("findtasksymbol - fopen"); return -1;
}
bzero(buffer, sizeof(buffer));
while (fgets(buffer, sizeof(buffer) - 1, ksyms)) {
if (!(p = (char *)strchr(buffer, ' '))) continue;
if (strstr(p+1, tasksymbol)) {
*p = 0; addr = strtoul(buffer, NULL, 16);
fclose(ksyms); return addr;
}
}
fclose(ksyms);
return -1;
}
int createpidlist(int *pidlist, int len)
{
char buffer[1024];
int rt, fd[2], lst;
char *arg[3];
FILE *ps;
rt = pipe(fd);
if (rt == -1) {
perror("fork"); return -1;
}
rt = fork();
switch (rt) {
case -1:
perror("fork"); return -1;
case 0:
close(fd[0]); dup2(fd[1], 1);
arg[0] = "ps"; arg[1] = "-A"; arg[2] = NULL;
execvp("/bin/ps", arg); exit(1);
}
close(fd[1]); lst = 0;
if ((ps = fdopen(fd[0], "r")) == NULL) return -1;
while (fgets(buffer, sizeof(buffer) - 1, ps) && lst < len) {
buffer[6] = 0; pidlist[lst++] = atoi(buffer);
}
wait(NULL);
return lst;
}
int checkproc(int pid)
{
char buffer[1024];
int fd;
sprintf(buffer, "/proc/%d", pid);
fd = open(buffer, O_RDONLY);
if (fd == -1 && errno == ENOENT) return 1;
close(fd);
return 0;
}
int checkpidlist(int pid, int *pidlist, int len)
{
int i;
for (i=0; i<len; i++) {
if (pidlist[i] == pid) return 0;
}
return 1;
}