提问人:GeoMldr 提问时间:11/2/2023 最后编辑:GeoMldr 更新时间:11/3/2023 访问量:83
使用 kprobe 挂钩系统调用时空指针取消引用
Null pointer dereference when hooking system call with kprobe
问:
我一直在尝试在 Debian(内核版本 5.10.0-20-amd64)上挂钩 connect() 系统调用。尽管 kprobe 本身成功了,但我无法从 pt_regs 结构中检索 sockaddr。
我的代码如下所示:
static struct kprobe kp = {
.symbol_name = "__x64_sys_connect",
};
static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
struct sockaddr *addr = (struct sockaddr * )(regs->si);
if (addr->sa_family == AF_INET) {
printk("Hurray!");
}
return 0;
}
static int __init my_hook_init(void) {
kp.pre_handler = handler_pre;
int ret = register_kprobe(&kp);
if(ret<0) {
printk(KERN_INFO "Kprobe failed %d\n", ret);
return ret;
}
printk(KERN_INFO "Kprobe at %p\n", kp.addr);
return 0;
}
static void __exit my_hook_exit(void) {
unregister_kprobe(&kp);
printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr);
}
module_init(my_hook_init);
module_exit(my_hook_exit);
我得到的错误是这样的:
错误:内核空指针取消引用,地址:0000000000000002a
我做错了什么?系统调用的第二个参数不是应该存储在 64 位架构的 rsi 上吗?
答:
0赞
GeoMldr
11/3/2023
#1
用 __sys_connect 替换 __x64_sys_connect 并在成功注册后启用 kprobe 后,问题就解决了(至少在系统不再崩溃的意义上)。 像这样的东西:
static struct kprobe kp = {
.symbol_name = "__sys_connect",
.flags = KPROBE_FLAG_DISABLED
};
static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
struct sockaddr *addr = (struct sockaddr * )(regs->si);
if (addr->sa_family == AF_INET) {
printk("Hurray!");
}
return 0;
}
static int __init my_hook_init(void) {
kp.pre_handler = handler_pre;
int ret = register_kprobe(&kp);
if(ret<0) {
printk(KERN_INFO "Kprobe failed %d\n", ret);
return ret;
}
printk(KERN_INFO "Kprobe at %p\n", kp.addr);
enable_kprobe(&kp);
return 0;
}
static void __exit my_hook_exit(void) {
unregister_kprobe(&kp);
printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr);
}
module_init(my_hook_init);
module_exit(my_hook_exit);
评论
NULL
regs
addr