为什么kprobe不能探测内核中的某些函数?

时间:2017-05-15 19:07:05

标签: linux linux-kernel kernel-module kprobe

我试图探测一个简单的函数(例如myfunc),我在内核中添加了如下函数:

  1. 我在~/source/kernel/下创建了一个文件(myfile.c),即~/source/kernel/myfile.c
  2. 我在此文件中添加了一个简单的系统调用mysyscall和一个本地函数myfuncmysyscall函数调用myfunc函数。
  3. 我可以使用

    获取函数的地址
    cat /proc/kallsyms | grep myfunc
    

    但是当我调用myfunc时,kprobe处理程序不会被调用。

    我可以探测系统调用' mysyscall'。但是当我尝试探测myfunc'时,处理程序无法被调用。

    任何人都可以解释为什么这是行为?感谢。

    正如Eugene所说,下面是kprobe的代码,mysyscall& MYFUNC。 在以下代码中不会调用kprobe处理程序。但是,如果我在下面给出的kprobe代码中取消注释B行并注释A,则会调用kprobe处理程序。

    我使用的是内核版本4.8。 我添加了〜/ source / kernel / myfile.c来编写mysyscall和myfunc,如下所示:

    #include <linux/linkage.h>
    #include <linux/export.h>
    #include <linux/time.h>
    #include <asm/uaccess.h>
    #include <linux/printk.h>
    #include <linux/slab.h>
    
    extern int myfunc(int ax)
    {
            int x = 6;
    
            return x;
    }
    asmlinkage int* sys_mysyscall(int bx){
            int *retval;
            int ret = 0;
            printk(KERN_ALERT "Hello World!\n");
            ret =  myfunc(10);
    
            retval = kmalloc(sizeof(int), GFP_KERNEL);
            *retval = 55;
            printk("sum: %d\n", *retval);
    
    
            printk("myfunc return value: %d\n", ret);
    
        return retval;
    }
    EXPORT_SYMBOL(sys_mysyscall);
    

    kprobe模块代码如下:

    #include<linux/module.h>
    #include<linux/version.h>
    #include<linux/kernel.h>
    #include<linux/init.h>
    #include<linux/kprobes.h>
    
    //Line A
    static const char *probed_func = "myfunc";
    
    //Line B
    //static const char *probed_func = "sys_mysyscall";
    
    
    static unsigned int counter = 0;
    
    int Pre_Handler(struct kprobe *p, struct pt_regs *regs){
        printk("Pre_Handler: counter=%u\n",counter++);
        return 0;
    }
    
    void Post_Handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags){
        printk("Post_Handler: counter=%u\n",counter++);
    }
    
    static struct kprobe kp;
    
    int myinit(void)
    {
        int error;
        printk("module inserted\n ");
        kp.pre_handler = Pre_Handler;
        kp.post_handler = Post_Handler;
        kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name(probed_func);
        error = register_kprobe(&kp);
        if(error)
        {
            pr_err("can't register_kprobe :(\n");
            return error;
        }
        else
        {
            printk("probe registration successful\n");
        }
        return 0;
    }
    
    void myexit(void)
    {
        unregister_kprobe(&kp);
        printk("module removed\n ");
    }
    
    module_init(myinit);
    module_exit(myexit);
    MODULE_AUTHOR("psin");
    MODULE_DESCRIPTION("KPROBE MODULE");
    MODULE_LICENSE("GPL");
    

    我使用内核模块调用mysyscall,如下所示:

    sys_mysyscall(12);//12 is some random integer as parameter
    

0 个答案:

没有答案