对于一个反rootkit学生项目,我想在内核模块中获取给定目录的文件名列表。我知道文件 IO 在内核空间中通常是一个坏主意,但这是一个特例。
我使用filp_open
来获取目录的struct file
。有了这个,我有一个struct dentry
它包含列表d_subdirs
,该列表应包含给定目录中的所有文件。
当我遍历列表并打印所有d_iname
struct dentry
(应该是struct dentry
的短名称)时,有非ASCII符号,目录中的某些文件丢失。没有运行可以隐藏这些的rootkit。dmesg 输出如下所示:
<6>Filename: �đ�@�Y�android_module17.ko
<6>Filename: <���
<6>Filename: <�
<6>Filename: <���
<6>Filename: <�����android_module15.ko
<6>Filename: <��ŋ�android_module14.ko
<6>Filename: <���@Nj�android_module13.ko
<6>Filename: <���
<6>Filename: <����ʋ�k
<6>Filename: <��̋�android_module11.ko
<6>Filename: <���@�android_module10.ko
<6>Filename: <���@���android_module9.ko
<6>Filename: <���
<6>Filename: <�����android_module7.ko
<6>Filename: <���android_module6.ko
<6>Filename: <Ċ�@���android_module5.ko
<6>Filename: <Ŋ�
<6>Filename: <Ɗ�����10-__rttest
<6>Filename: <NJ���__rttest
<6>Filename: <Ȋ�@���proctest.ko
<6>Filename: <ʊ�
<6>Filename: <ˊ�����rt.ko
<6>Filename: <̊���android_module4.ko
<6>Filename: <͊�@���anmo.ko
<6>Filename: <���
<6>Filename: ������Z�LOST.DIR
<6>Filename: �҉�@�Z�Android
例如,缺少文件夹DCIM或名为android_module1.ko的文件。我没有看到这些文件有什么特别之处。
这是我的内核模块的代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <asm/uaccess.h>
//replace the "" with angular brackets
int init_module(void)
{
struct file * fi;
printk(KERN_INFO "Hello android kernel...n");
fi = filp_open("/sdcard/", O_RDONLY, 0);
//struct path testpath = fi->f_path;
struct dentry * thedentry;
thedentry = fi->f_dentry;
struct dentry * curdentry;
unsigned char * curname = NULL;
list_for_each_entry(curdentry, &thedentry->d_subdirs, d_subdirs) {
curname = curdentry->d_iname;
printk(KERN_INFO "Filename: %s n", curname);
}
filp_close(fi, NULL);
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye android kernel...n");
}
当我在遍历列表时尝试访问索引节点时,android 崩溃了。 我可以以某种方式以这种方式列出所有文件吗?
编辑:
有趣的是,如果我尝试在循环中像这样手动更正凝乳指针:
testchar = (char *)curdentry;
testchar = testchar + 8;
curdentry = (struct dentry *)testchar;
curname = curdentry->d_iname;
testchar = (char *)curdentry;
testchar = testchar - 8;
curdentry = (struct dentry *)testchar;
哇,这看起来很丑,但随之而来的是随机符号消失了。我只是看不出这种指针不匹配是从哪里来的。我是否正确使用了列表功能?
您使用了包含 name: 的错误字段:d_iname
只是一个缓冲区,用于保存不能用于大文件名的分配。其实你找的是d_name.name
.
此外,您错误地遍历列表(我想知道您如何从中获得任何结果)。 d_subdirs
是列表的头部,在 list_for_each_entry()
中用作第二个参数,但在第三个参数中,您应该放置节点,而不是 head,在d_entry
的情况下d_child
字段(在旧内核中d_u.d_child
)。
以下是经过一些润色后的代码:
struct file * fi;
struct dentry * thedentry;
struct dentry * curdentry;
const char * curname = NULL;
printk(KERN_INFO "Hello android kernel...n");
fi = filp_open("/root/", O_RDONLY, 0);
thedentry = fi->f_dentry;
list_for_each_entry(curdentry, &thedentry->d_subdirs, d_u.d_child) {
curname = curdentry->d_name.name;
printk(KERN_INFO "Filename: %s n", curname);
}
filp_close(fi, NULL);
我在vanilla Linux 3.12上检查了它。