diff options
Diffstat (limited to 'scripts/kprobes_test/kprobe_module.c')
-rw-r--r-- | scripts/kprobes_test/kprobe_module.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/scripts/kprobes_test/kprobe_module.c b/scripts/kprobes_test/kprobe_module.c new file mode 100644 index 00000000..0ba6c1db --- /dev/null +++ b/scripts/kprobes_test/kprobe_module.c @@ -0,0 +1,65 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/kprobes.h> + +struct kp_data { + struct kprobe kp; + atomic_t use_count; +}; + +static int handler_pre(struct kprobe *p, struct pt_regs *regs); + +#include "kprobe_defs.h" + + +/* kprobe pre_handler: called just before the probed instruction is executed */ +static int handler_pre(struct kprobe *p, struct pt_regs *regs) +{ + struct kp_data *k = container_of(p, struct kp_data, kp); + atomic_inc(&k->use_count); + return 0; +} + +static int __init kprobe_init(void) +{ + int ret; + int probes_registered = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(kp_data); i++) { + ret = register_kprobe(&kp_data[i].kp); + if (ret != 0) + atomic_set(&kp_data[i].use_count, -1); + else + probes_registered++; + } + if (probes_registered == 0) { + for (i = 0; i < ARRAY_SIZE(kp_data); i++) { + printk(KERN_INFO "-1 %s\n", kp_data[i].kp.symbol_name); + } + printk(KERN_INFO "kprobe_module unloaded\n"); + return ret; + } + printk(KERN_INFO "Planted kprobes\n"); + return 0; +} + +static void __exit kprobe_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(kp_data); i++) { + if (atomic_read(&kp_data[i].use_count) != -1) + unregister_kprobe(&kp_data[i].kp); + } + printk(KERN_INFO "kprobes unregistered\n"); + for (i = 0; i < ARRAY_SIZE(kp_data); i++) { + printk(KERN_INFO "%d %s\n", atomic_read(&kp_data[i].use_count), + kp_data[i].kp.symbol_name); + } + printk(KERN_INFO "kprobe_module unloaded\n"); +} + +module_init(kprobe_init) +module_exit(kprobe_exit) +MODULE_LICENSE("GPL"); |