c语言 - 为什么当我遍历 android 内核中内核模块中目录的条目时,我无法正确提取所有文件名?



对于一个反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上检查了它。

最新更新