我正在尝试创建一个简单的linux rootkit,可以用来隐藏进程。我选择尝试的方法是将指向“/ proc”的迭代函数的指针替换为指向自定义的指针,该指针将隐藏我需要的进程。要做到这一点,我必须首先保存一个指向它的原始迭代函数的指针,以便以后可以替换它。可以通过访问'iterate'函数指针来访问'/ proc'文件系统的迭代函数,该函数指针是'file_operations'结构的成员。
我已经尝试了以下两种方法来访问它,可以在代码段中看到label_1和label_2,每个方法都用另一个注释掉了。
static struct file *proc_filp;
static struct proc_dir_entry *test_proc;
static struct proc_dir_entry *proc_root;
static struct file_operations *fs_ops;
int (*proc_iterate) (struct file *, struct dir_context *);
static int __init module_init(void)
{
label_1:
proc_filp = filp_open("/proc", O_RDONLY | O_DIRECTORY, 0);
fs_ops = (struct file_operations *) proc_filp->f_op;
printk(KERN_INFO "file_operations is %p", fs_ops);
proc_iterate = fs_ops->iterate;
printk(KERN_INFO "proc_iterate is %p", proc_iterate);
filp_close(proc_filp, NULL);
label_2:
test_proc = proc_create("test_proc", 0, NULL, &proc_fops);
proc_root = test_proc->parent;
printk(KERN_INFO "proc_root is %p", proc_root);
fs_ops = (struct file_operations *) proc_root->proc_fops;
printk(KERN_INFO "file_operations is %p", fs_ops);
proc_iterate = fs_ops->iterate;
printk(KERN_INFO "proc_iterate is %p", proc_iterate);
remove_proc_entry("test_proc", NULL);
return 0;
}
按照方法1,我打开'/ proc'作为文件,然后按照文件指针访问它的'struct file_operations'(f_op),然后按照这个指针尝试找到'iterate'。但是,虽然我能够成功访问'f_op'结构,但不知怎的,'iterate'似乎指向NULL。以下dmesg日志显示了此输出。
[ 47.707558] file_operations is 00000000b8d10f59
[ 47.707564] proc_iterate is (null)
根据方法2,我创建一个新的proc目录条目,然后尝试访问它的父目录(应该指向'/ proc'本身),然后尝试访问它的'struct file_operations'(proc_fops),并且然后尝试继续'迭代'。但是,使用这种方法,我甚至无法访问'/ proc'目录,因为'proc_root = test_proc-> parent;'似乎返回NULL。这会导致后面的代码中出现“内核空指针取消引用”错误。以下dmesg日志显示了此输出。
[ 212.078552] proc_root is (null)
[ 212.078567] BUG: unable to handle kernel NULL pointer dereference at 000000000000003
现在,我知道linux内核中的内容发生了变化,我们不允许在各种地址写入(比如将迭代指针更改为指向自定义函数),这可以通过制作这些来解决在内核中可写的页面,但稍后我将尝试创建此rootkit。目前我甚至无法弄清楚如何读取原始的'iterate'指针。
所以,我有这些问题: [1]以下代码有问题吗?怎么解决? [2]有没有其他方法可以访问指向/ proc的迭代函数的指针?
在运行linux 4.15.7的Arch Linux上测试