1 #include <linux/module.h>
4 #include <dbi_kprobes.h>
5 #include "ks_features.h"
6 #include "syscall_list.h"
7 #include "features_data.c"
17 #define CREATE_JP(name) \
23 #define CREATE_RP(name) \
25 .entry_handler = NULL, \
29 #define X(name, args) #name
30 static const char *const syscall_name[] = {
36 syscall_name_cnt = sizeof(syscall_name) / sizeof(char *)
40 #define X(name, args__) \
42 .jp = CREATE_JP(name), \
43 .rp = CREATE_RP(name), \
48 static struct ks_probe ksp[] = {
54 static char *get_sys_name(size_t id)
56 return syscall_name[id];
59 static int get_counter(size_t id)
61 return ksp[id].counter;
64 static void inc_counter(size_t id)
69 static void dec_counter(size_t id)
74 /* ========================= HEANDLERS ========================= */
80 DEFINE_PER_CPU(void *, gp_priv_arg) = NULL;
82 static unsigned long pre_handler(void *priv_arg, struct pt_regs *regs)
84 __get_cpu_var(gp_priv_arg) = priv_arg;
89 static void j_handler(unsigned long arg0, unsigned long arg1,
90 unsigned long arg2, unsigned long arg3,
91 unsigned long arg4, unsigned long arg5)
93 struct ks_probe *ksp = (struct ks_probe *)__get_cpu_var(gp_priv_arg);
95 pack_event_info(KS_PROBE_ID, RECORD_ENTRY, "psxxxxxx", ksp->jp.kp.addr,
97 arg0, arg1, arg2, arg3, arg4, arg5);
101 static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs, void *priv_arg)
104 struct ks_probe *ksp = (struct ks_probe *)priv_arg;
106 ret_val = regs_return_value(regs);
107 pack_event_info(KS_PROBE_ID, RECORD_RET, "pd", ksp->rp.kp.addr, ret_val);
111 /* ========================= HEANDLERS ========================= */
115 static int register_syscall(size_t id)
118 printk("register_syscall: %s\n", get_sys_name(id));
120 if (ksp[id].jp.kp.addr == NULL)
123 ksp[id].jp.pre_entry = pre_handler;
124 ksp[id].jp.entry = j_handler;
125 ksp[id].jp.priv_arg = &ksp[id];
127 ksp[id].rp.handler = ret_handler;
128 ksp[id].rp.priv_arg = &ksp[id];
130 ret = dbi_register_jprobe(&ksp[id].jp);
134 ret = dbi_register_kretprobe(&ksp[id].rp);
136 dbi_unregister_jprobe(&ksp[id].jp);
141 static int unregister_syscall(size_t id)
143 printk("unregister_syscall: %s\n", get_sys_name(id));
145 if (ksp[id].jp.kp.addr == NULL)
148 dbi_unregister_kretprobe(&ksp[id].rp);
149 dbi_unregister_jprobe(&ksp[id].jp);
154 static int install_features(struct feature *f)
158 for (i = 0; i < f->cnt; ++i) {
159 id = f->feature_list[i];
161 if (get_counter(id) == 0) {
162 int ret = register_syscall(id);
175 static int uninstall_features(struct feature *f)
179 for (i = 0; i < f->cnt; ++i) {
180 id = f->feature_list[i];
182 if (get_counter(id) == 0) {
189 if (get_counter(id) == 0) {
190 int ret = unregister_syscall(id);
201 static struct feature *get_feature(enum feature_id id)
203 if (id < 0 || id >= (int)feature_cnt)
206 return &features[id];
209 int set_feature(enum feature_id id)
211 struct feature *f = get_feature(id);
216 return install_features(f);
218 EXPORT_SYMBOL_GPL(set_feature);
220 int unset_feature(enum feature_id id)
222 struct feature *f = get_feature(id);
227 return uninstall_features(f);
229 EXPORT_SYMBOL_GPL(unset_feature);
231 static int __init init_ks_feature(void)
234 unsigned long addr, ni_syscall;
237 ni_syscall = swap_ksyms("sys_ni_syscall");
239 for (i = 0; i < syscall_name_cnt; ++i) {
240 name = get_sys_name(i);
241 addr = swap_ksyms(name);
243 printk("%s() not found\n", name);
247 if (ni_syscall == addr) {
248 printk("INFO: %s is not install\n", get_sys_name(i));
252 ksp[i].jp.kp.addr = ksp[i].rp.kp.addr = addr;
258 static void __exit exit_ks_feature(void)
262 module_init(init_ks_feature);
263 module_exit(exit_ks_feature);
265 MODULE_LICENSE("GPL");
268 static void print_feature(struct feature *f)
272 for (i = 0; i < f->cnt; ++i) {
273 printk(" feature[%3u]: %s\n", i, get_sys_name(f->feature_list[i]));
277 void print_features(void)
281 printk("print_features:\n");
282 for (i = 0; i < feature_cnt; ++i) {
283 printk("feature: %d\n", i);
284 print_feature(&features[i]);
288 void print_all_syscall(void)
292 printk("SYSCALL:\n");
293 for (i = 0; i < syscall_name_cnt; ++i) {
294 printk(" [%2d] %s\n", get_counter(i), get_sys_name(i));