kprobe/jprobe使用
当想要实时获取内核模块的信息,或想更改内核模块内的数据,这时就会用到kprobes或jprobes工具。
jprobes更简单,可以轻松在函数调用前注入自己的代码,获取或更改函数的参数。
使用方法示例:
1. 通过cat /proc/kallsyms查看想要注入的函数,如果没有的话,说明函数没有导出,不可用此方法。
2. 示例代码
#include <linux/module.h> #include <linux/kprobes.h> #include <linux/kallsyms.h> #include <linux/blkdev.h> #include <linux/blk_types.h> struct jprobe exec_jp; int jp_bio_clone(struct bio *bio, gfp_t gfp_mask) { struct block_device *bd = bio->bi_bdev; if (bd->bd_disk->major==9 && bd->bd_disk->first_minor==2) printk("%.20s, %s, %d, %d, bi_rw %lu bi_flags %lu \n", current->comm, bd->bd_disk->disk_name, bd->bd_disk->major, bd->bd_disk->first_minor, bio->bi_rw, bio->bi_flags); jprobe_return(); return 0; } static __init int jprobes_exec_init(void) { exec_jp.kp.symbol_name = "bio_clone";
/*有可能出现多个模块内包含相同的函数名字,这时候可以直接写函数的地址。
*exec_jp.kp.addr = (kprobe_opcode_t *)0xffffffffa0733430;
*/
exec_jp.entry = JPROBE_ENTRY(jp_bio_clone); /*注册jprobes*/ register_jprobe(&exec_jp); return 0; } static __exit void jprobes_exec_cleanup(void) { /*撤销jprobes注册*/ unregister_jprobe(&exec_jp); } module_init(jprobes_exec_init); module_exit(jprobes_exec_cleanup); MODULE_LICENSE("GPL");
Makefile
ifneq ($(KERNELRELEASE),) obj-m := hello.o else PWD := $(shell pwd) KVER := $(shell uname -r) KDIR := /lib/modules/$(KVER)/build all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions modules.* Module.* endif
https://www.ibm.com/developerworks/cn/linux/l-cn-systemtap1/
http://blog.sina.com.cn/s/blog_71d4915701011tys.html
更多示例代码
http://pan.baidu.com/disk/home#path=%252Fmy%2520code