echo pth1nk_test sys_enter_splice source_fd=+44di target_fd=si len=dx flags=cx syskerneldebugtracingkprobe_events 想通过这条语句过滤出di 寄存器的f_mode 是否为文件flag si寄存器的文件结构体指针是否为 pipe flag通过偏移识别。
要实现这个功能,需要编写一个内核探针(kprobe)处理程序,在处理程序中读取%di和%si寄存器的值,并根据它们的偏移量判断它们的值是否符合特定的标志。
以下是一个可能的处理程序的示例:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/fs.h>
#include <linux/pipe_fs_i.h>
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
struct file *file = (struct file *)(((unsigned long)regs->si) + PIPEFS_INODE_OFFSET);
struct file *source_file = (struct file *)(((unsigned long)regs->di) + FILE_OFFSET);
if (file->f_mode & FMODE_PIPE) {
printk(KERN_INFO "Target file is a pipe\n");
}
if (source_file->f_mode & FMODE_READ) {
printk(KERN_INFO "Source file is a regular file\n");
}
return 0;
}
static struct kprobe kp = {
.symbol_name = "sys_enter_splice",
.pre_handler = handler_pre,
};
static int __init kprobe_init(void)
{
int ret;
ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_ERR "Failed to register kprobe\n");
return ret;
}
printk(KERN_INFO "Kprobe registered\n");
return 0;
}
static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
printk(KERN_INFO "Kprobe unregistered\n");
}
module_init(kprobe_init);
module_exit(kprobe_exit);
MODULE_LICENSE("GPL");
该处理程序首先将%si和%di寄存器的值转换为文件指针,然后检查它们的标志是否匹配所需的标志。
要编译和加载此模块,可以使用以下命令:
make -C /lib/modules/$(uname -r)/build M=$PWD modules
sudo insmod kprobe_example.ko
要查看内核日志,请使用以下命令:
dmesg
您应该能够看到类似以下内容的输出:
[ 711.112072] Kprobe registered
[ 711.112079] Target file is a pipe
[ 711.112083] Source file is a regular file
这表明处理程序已成功检测到pipe标志和文件标志。
原文地址: https://www.cveoy.top/t/topic/bLrx 著作权归作者所有。请勿转载和采集!