zoukankan      html  css  js  c++  java
  • Kprobe的使用方法

    Kprobe的使用方法

    //kprobe_example.c
    #include<linux/init.h>
    #include<linux/module.h>
    #include<linux/kernel.h>
    #include <linux/kprobes.h>
    
    //统计do_fork()总共执行了几次
    static int total_count = 0;
    
    //前置方法,这里可以拿到方法入参和栈,每次执行do_fork() total_count++
    static int handler_pre(struct kprobe *p, struct pt_regs *regs)
    {
            total_count++;
            //printk 打印的日志 可以通过dmesg 命令查看
            printk(KERN_INFO "累计调用do_fork[%d]次
    ",total_count);
            return 0;
    }
    
    
    //后置方法,这里可以拿到方法返回值
    static void handler_post(struct kprobe *p, struct pt_regs *regs,
                                    unsigned long 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;
    }
    //通过kprobe这个数据结构,定义要hook的内核方法名称
    static struct kprobe kp = {
            .symbol_name    = "do_fork",
    };
    //通过register_kprobe 方法更改内核对应方法的指令
    static int 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
    ", ret);
                    return ret;
            }
            printk(KERN_INFO "Planted kprobe at %p
    ", kp.addr);
            return 0;
    }
    //通过unregister_kprobe卸载hook
    static void kprobe_exit(void){
            unregister_kprobe(&kp);
            printk(KERN_INFO "kprobe at %p unregistered
    ", kp.addr);
    }
    
    //构造内核模块
    module_init(kprobe_init);
    module_exit(kprobe_exit);
    MODULE_LICENSE("GPL");
    // Makefile
    obj-m +=kprobe_example.o
    CURRENT_PATH:=$(shell pwd)
    LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build
    all:
            make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
    clean:
            make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

    [root@apple kprobes]# cat /proc/kallsyms | grep do_fork
    c0439cc0 T do_fork

    来源:

    https://blog.csdn.net/luckyapple1028/article/details/52972315

    https://zhuanlan.zhihu.com/p/71437161

    https://github.com/iovisor/bcc

    https://elixir.bootlin.com/linux/v4.19.170/source/samples/kprobes/kprobe_example.c

  • 相关阅读:
    SpringMVC文件上传
    JavaSE——链表集合
    java 线程Thread 技术--1.5Lock 与condition 演示生产者与消费模式
    XML 解析技术
    java 线程Thread 技术--方法演示生产与消费模式
    java 线程Thread 技术--线程状态与同步问题
    java 线程Thread 技术--创建线程的方式
    java 线程Thread 技术--线程创建源码解释
    JDK1.5 Excutor 与ThreadFactory
    springboot学习记录
  • 原文地址:https://www.cnblogs.com/smilingsusu/p/14155602.html
Copyright © 2011-2022 走看看