Linux kernel 寄存器_kretprobe失败,返回值为-2

Linux kernel 寄存器_kretprobe失败,返回值为-2,linux-kernel,kernel,kernel-module,kprobe,Linux Kernel,Kernel,Kernel Module,Kprobe,我已经编写了一个kretprobe来钩住fs/binfmt_elf.c文件中提到的randomize_stack_top()函数。在使用insmod加载LKM时,register_kretprobe()调用失败,返回值为-2。为了启动模块,我如何调试/纠正这些问题 #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/kpro

我已经编写了一个kretprobe来钩住fs/binfmt_elf.c文件中提到的randomize_stack_top()函数。在使用insmod加载LKM时,register_kretprobe()调用失败,返回值为-2。为了启动模块,我如何调试/纠正这些问题

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/current.h>
#include <asm/param.h>

/* Global variables */
int randomize_stack_retval;

//  randomize_stack_top() kretprobe specific declarations 
static char stack_name[NAME_MAX] = "randomize_stack_top";

static int randomize_stack_top_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    return 0;
}

static int randomize_stack_top_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    randomize_stack_retval = regs_return_value(regs);   //store in global variable
    printk(KERN_INFO "%d\n",randomize_stack_retval);
    return 0;
}

//randomize_stack_top return probe
static struct kretprobe randomize_kretprobe = {
    .handler = randomize_stack_top_ret_handler,
    .entry_handler = randomize_stack_top_entry_handler,
    .maxactive = NR_CPUS,
};

/* Register kretprobe */
static int __init kretprobe_init(void)
{
    int ret;

    randomize_kretprobe.kp.symbol_name = stack_name;

    ret = register_kretprobe(&randomize_kretprobe);
    if (ret < 0) {
        printk(KERN_INFO "register_kretprobe failed, returned %d\n",
                ret);
        return -1;
    }
    printk(KERN_INFO "Planted return probe at %s: %p\n",
            randomize_kretprobe.kp.symbol_name, randomize_kretprobe.kp.addr);

    return 0;
}

/* Unregister kretprobe */
static void __exit kretprobe_exit(void)
{
    unregister_kretprobe(&randomize_kretprobe);
    printk(KERN_INFO "kretprobe at %p unregistered\n",
            randomize_kretprobe.kp.addr);

    //  nmissed > 0 suggests that maxactive was set too low. 
    printk(KERN_INFO "Missed probing %d instances of %s\n",
  randomize_kretprobe.nmissed, randomize_kretprobe.kp.symbol_name);

}

module_init(kretprobe_init);
module_exit(kretprobe_exit);
MODULE_LICENSE("GPL");
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*全局变量*/
int随机化\u堆栈\u检索;
//随机化_stack_top()kretprobe特定声明
静态字符堆栈\u名称[name\u MAX]=“随机化\u堆栈\u顶部”;
static int randomize_stack_top_entry_handler(struct kretprobe_instance*ri,struct pt_regs*regs)
{
返回0;
}
static int randomize_stack_top_ret_处理程序(struct kretprobe_instance*ri,struct pt_regs*regs)
{
随机化_stack_retval=regs_return_value(regs);//存储在全局变量中
printk(内核信息“%d\n”,随机化堆栈检索);
返回0;
}
//随机化\u堆栈\u顶部返回探头
静态结构kretprobe随机化\u kretprobe={
.handler=随机化\u堆栈\u顶部\u重新\u处理程序,
.entry\u handler=随机化\u stack\u top\u entry\u handler,
.maxactive=NR_CPU,
};
/*寄存器kretprobe*/
静态整数初始化kretprobe初始化(void)
{
int ret;
随机化_kretprobe.kp.symbol_name=堆栈_name;
ret=寄存器(register_kretprobe)(&randomize_kretprobe);
如果(ret<0){
printk(内核信息“register\u kretprobe失败,返回%d\n”,
ret);
返回-1;
}
printk(KERN_INFO“在%s处植入返回探测:%p\n”,
随机化_kretprobe.kp.symbol_名称,随机化_kretprobe.kp.addr);
返回0;
}
/*注销kretprobe*/
静态无效\uuuu退出kretprobe\u退出(无效)
{
取消注册\u kretprobe(&随机化\u kretprobe);
printk(KERN_INFO“kretprobe位于%p未注册\n”,
随机化_kretprobe.kp.addr);
//nmissed>0表示maxactive设置得太低。
printk(KERN_INFO“未探测%s的%d个实例\n”,
随机化_kretprobe.nmissed,随机化_kretprobe.kp.symbol_name);
}
模块初始化(kretprobe初始化);
模块出口(kretprobe出口);
模块许可证(“GPL”);

-2对应于
-enoint
(您可以在
include/uapi/asm generic/errno base.h
中检查)。这可能意味着kprobe找不到具有给定名称的符号


请注意,
randomize\u stack\u top
是一个静态函数,实现时间短,只使用一次。所以它可以被gcc内联。

我需要在可加载的内核模块中使用由
randomize\u stack\u top
返回的值,那么你有什么建议,知道我该怎么做吗?你可以从这个函数的声明中删除
static
modificator,然后重新构建内核,然后再次尝试使用您的模块:新内核的符号表中应该有这个函数,所以kprobe应该能够找到它。