网络对krpobe的实现机制及扩展都不是特别详细
由于工作需要及个人爱好,正好有这个机会好好学习此模块及应用到实际中
并将整个应用扩展及当时的分析情况,详细记录下来,希望对感兴趣的人有些许帮助
最开始还是先给个具体的栗子:
参考: kernel/samples 下面有不少的例子
/* For each probe you need to allocate a kprobe structure */ static struct kprobe kp = { //.symbol_name = "do_fork", .symbol_name = "testAddadd5", };
当运行到监控的某个点的时候,会调用此函数
static int handler_pre(struct kprobe *p, struct pt_regs *regs) { printk(" kprobes name is %s pt_regs size is %d \n",p->symbol_name,sizeof(regs->uregs)); return 0; }
初始话,注册一个kprobe,可以传入函数名或者在内存的绝对地址(system.map)
static int __init kprobe_init(void) { int ret; kp.pre_handler = handler_pre; ret = register_kprobe(&kp); printk(KERN_INFO " Planted kprobe at %p\n", kp.addr); if (ret < 0) { printk(KERN_INFO " register_kprobe failed, returned %d\n", ret); return ret; } return 0; }
注销kprobe探测点
static void __exit kprobe_exit(void) { unregister_kprobe(&kp); printk(KERN_INFO " kprobe at %p unregistered\n", kp.addr); } module_init(kprobe_init) module_exit(kprobe_exit) MODULE_LICENSE("GPL");
system.map
//现在我们只关心 do_fork testAddadd5 这两个函数
它们在内存的地址如下:
c0052368 T testAddadd5
c00523c0 T do_fork
static struct kprobe kp = {
//.symbol_name = "do_fork",
.symbol_name = "testAddadd5",
};
register_kprobe(&kp)
printk(KERN_INFO " Planted kprobe at %p\n", kp.addr);
insmod
<6>[ 9749.442971] (0)[5251:insmod] Planted kprobe at c0052368
发现这里打印的地址与system.map是一致的。