要实现这个功能,需要编写一个内核探针(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标志和文件标志。

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通过偏移识别。

原文地址: https://www.cveoy.top/t/topic/bLrx 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录