![无法注册 kprobe](https://linux22.com/image/14940/%E6%97%A0%E6%B3%95%E6%B3%A8%E5%86%8C%20kprobe.png)
我正在尝试注册一个 kprobe 来检索系统调用的地址。但我所有的尝试似乎都返回 -22 作为错误代码。下面的示例代码(不完整但包含相关函数)尝试为调用注册内核探测器sys_mkdir
。
如果我指定前置或后处理程序似乎并不重要,仅仅注册探针是行不通的。
注意:我尝试使用 kprobes 作为未导出的替代品kallsyms_lookup_name
,在内核 5.7 及更高版本中不再导出。
unsigned long lookup_name(const char *name)
{
int ret;
struct kprobe kp;
unsigned long retval;
kp.symbol_name = name;
ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_DEBUG "register_kprobe failed for symbol %s, returned %d\n", name,
ret);
return 0;
}
retval = (unsigned long)kp.addr;
unregister_kprobe(&kp);
return retval;
}
static int __init mod_init(void)
{
int (*fn)(unsigned long param);
fn = (void*)lookup_name("__x64_sys_mkdir");
}
答案1
您没有kprobe
完全初始化该结构,因此您无法满足symbol_name
和之间的互斥或要求addr
(表中的第 3 点)文档register_kprobe
):addr
包含函数入口处堆栈上的所有内容,很可能为非零,因此 和symbol_name
均为addr
非零,并以(22)register_kprobe
失败。EINVAL
您可以按如下方式修复此问题:
int ret;
struct kprobe kp = {
.symbol_name = name
};
unsigned long retval;
这将确保结构的其他成员初始化为其默认值。