-
Notifications
You must be signed in to change notification settings - Fork 6
/
probe.c
124 lines (103 loc) · 2.83 KB
/
probe.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#define FILE_NAME 64
static struct kprobe kp = {
.symbol_name = "vfs_write",
};
static char file_name[FILE_NAME] = {0};
static struct ctl_table_header *cth = NULL;
static struct ctl_path path = {
.procname = "kernel",
};
static struct ctl_table table[] = {
{
.procname = "who_touch_my_file",
.data = file_name,
.maxlen = FILE_NAME,
.mode = 0644,
.proc_handler = proc_dostring,
},
{
}
};
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
struct file *file = (struct file *)regs->di;
char *buf = NULL;
size_t size = 0;
#if 0
printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx," " flags = 0x%lx\n", p->addr, regs->ip, regs->flags);
if (file->f_path.dentry && file->f_path.dentry->d_name.name)
printk(KERN_INFO "name = %s" , file->f_dentry->d_name.name);
#endif
if (unlikely(strlen(file_name) && file && file->f_path.dentry && file->f_path.dentry->d_name.name && (strncmp(file->f_path.dentry->d_name.name, file_name, FILE_NAME) == 0)))
printk(KERN_INFO "bingo : %s\n" , file->f_path.dentry->d_name.name);
else
return 0;
size = regs->dx + 1;
printk(KERN_INFO "process = %s , pid = %ld, file = %s, size = %ld\n" , current->comm, current->pid, file->f_path.dentry->d_name.name, size);
/*
* should be careful ! if size is too big, maybe over flow.
buf = (char*)kmalloc(size, 0);
if (buf == NULL)
return 0;
memset(buf, 0x00, size);
if(copy_from_user(buf, regs->si, size))
goto out;
printk(KERN_INFO "%s\n" , buf);
*/
out :
if (buf)
kfree(buf);
return 0;
}
static void handler_post(struct kprobe *p, struct pt_regs *regs,
unsigned long flags)
{
//printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\n", p->addr, regs->flags);
}
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn",
p->addr, trapnr);
return 0;
}
static int __init kprobe_init(void)
{
int ret;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;
ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_INFO "register_kprobe failed, returned %d\n", ret);
goto out;
}
printk(KERN_INFO "register kprobe at %p\n", kp.addr);
cth = register_sysctl_paths(&path, &table);
if (cth == NULL) {
printk(KERN_INFO "register_sysctl_paths failed\n");
ret = -EFAULT;
goto error;
}
return 0;
error:
unregister_kprobe(&kp);
out:
return ret;
}
static void __exit kprobe_exit(void)
{
if (cth)
unregister_sysctl_table(cth);
unregister_kprobe(&kp);
printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr);
}
module_init(kprobe_init);
module_exit(kprobe_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PiZhenwei [email protected]");