linux内核钩子函数实现监测块设备读写事件

方案:利用linux内核钩子实现,钩子可以捕获到内核事件并做出额外处理。钩子的注册方式主要有两种,kproge和jprobe,jprobe是kprobe上层的封装,使用更加简单。submit_bio为块设备io请求的顶层函数,对其进行监听可实现对块设备io事件的监测。

过程:使用kprobe或者jprobe注册对应的内核符号(内核函数调用)进行监听,每当有对应的内核调用发生时,会优先执行钩子函数。

环境准备:下载uname -r对应的内核开发包(后续Makefile中编译选项-C指向其目录)

代码:

catch_bio.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/bio.h>

static void submit_bio_probe(int rw, struct bio * bio) {
        if(bio && bio->bi_io_vec != NULL) {
        char b[BDEVNAME_SIZE];
        printk(KERN_INFO "device[%s] , type[%s] , offset[%10lld] , length[%d]" , bdevname(bio->bi_bdev, b), rw & WRITE ? "write" : "read" , bio->bi_sector, bio_sectors(bio));
    }
    jprobe_return();
}

static struct jprobe catch_bio_jprobe = {
    .entry = (kprobe_opcode_t *) submit_bio_probe,
    .kp = {
        .addr = NULL,
        .symbol_name = "submit_bio",
    },
};

static int __init mod_init(void) {
    int iRet = 0;
    iRet = register_jprobe(&catch_bio_jprobe);
    if(iRet < 0) {
        printk(KERN_ERR "Module[catch_bio] init failed! Func register_jprobe failed, ret[%d]", iRet);
        return iRet;
    }
    printk(KERN_INFO "Module[catch_bio] init successful.");
    return iRet;
}

static void __exit mod_exit(void) {
    unregister_jprobe(&catch_bio_jprobe);
    printk(KERN_INFO "Module[catch_bio] exit successful.");
}

module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");

Makefile

KERNEL_DIR = /usr/src/kernels/`uname -r`

obj-m   += catch_bio.o

all:
    make -C $(KERNEL_DIR) M=`pwd` modules

clean:
    make -C $(KERNEL_DIR) M=`pwd` modules clean
    rm -rf *o *.mod.c *.order *.symvers

装载驱动:insmod catch_bio.ko

卸载驱动:rmmod catch_bio.ko

驱动监控结果输出:view /var/log/messages  (结果如下图)

补充(其他常用的内核勾子点):

1. 系统调用勾子

  • sys_open
  • sys_read
  • sys_write
  • sys_execve
  • sys_clone
  • sys_fork
  • sys_exit

2. 网络勾子

  • nf_register_hook / nf_unregister_hook(Netfilter 勾子)
  • dev_add_pack / dev_remove_pack(网络包接收勾子)
  • inet_register_protosw / inet_unregister_protosw(协议勾子)

3. 文件系统操作

  • vfs_read
  • vfs_write
  • vfs_open
  • vfs_close

4. 进程管理

  • do_fork
  • do_exit
  • schedule(调度函数)

5. 内存管理

  • __kmalloc
  • kfree
  • vmalloc
  • vfree

6. 驱动操作

  • register_chrdev
  • unregister_chrdev
  • register_blkdev
  • unregister_blkdev

7. 安全勾子(Linux Security Modules)

  • security_inode_create
  • security_file_open
  • security_task_create
  • security_socket_create

8. 其他重要勾子

  • register_filesystem / unregister_filesystem
  • alloc_inode / destroy_inode
  • module_load / module_unload(模块加载和卸载)
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值