Linux kernel 寄存器_kretprobe失败,返回值为-2
我已经编写了一个kretprobe来钩住fs/binfmt_elf.c文件中提到的randomize_stack_top()函数。在使用insmod加载LKM时,register_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
#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应该能够找到它。