为什么我在android内核中遍历内核模块中目录的dentry时不能正确提取所有文件名?
Why can't I extract all filenames correctly when I traverse the dentry of a directory in a kernel module in the android kernel?
对于一个 antirootkit 学生项目,我想获取内核模块中给定目录的文件名列表。我知道文件 IO 在内核 space 中通常不是一个好主意,但这是一个特例。
我用 filp_open
得到了目录的 struct file
。有了这个,我有一个 struct dentry
,它有一个列表 d_subdirs
,它应该包含给定目录中的所有文件。
当我遍历列表并打印出 struct dentry
的所有 d_iname
应该是 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");
}
当我在遍历列表时尝试访问 inode 时,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;
哇,这看起来很难看,但是随机符号不见了。我只是看不出这个指针不匹配是从哪里来的。我是否正确使用列表函数?
您使用了包含名称的错误字段:d_iname
只是一个用于保存不能用于大文件名的分配的缓冲区。实际上你在寻找 d_name.name
.
你还错误地遍历了列表(我想知道你是如何从中得到任何结果的)。 d_subdirs
是列表的 head 并用作 list_for_each_entry()
中的第二个参数,但在第三个参数中你应该放置 node ,而不是 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);
我在原版上查看过 Linux 3.12.
对于一个 antirootkit 学生项目,我想获取内核模块中给定目录的文件名列表。我知道文件 IO 在内核 space 中通常不是一个好主意,但这是一个特例。
我用 filp_open
得到了目录的 struct file
。有了这个,我有一个 struct dentry
,它有一个列表 d_subdirs
,它应该包含给定目录中的所有文件。
当我遍历列表并打印出 struct dentry
的所有 d_iname
应该是 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");
}
当我在遍历列表时尝试访问 inode 时,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;
哇,这看起来很难看,但是随机符号不见了。我只是看不出这个指针不匹配是从哪里来的。我是否正确使用列表函数?
您使用了包含名称的错误字段:d_iname
只是一个用于保存不能用于大文件名的分配的缓冲区。实际上你在寻找 d_name.name
.
你还错误地遍历了列表(我想知道你是如何从中得到任何结果的)。 d_subdirs
是列表的 head 并用作 list_for_each_entry()
中的第二个参数,但在第三个参数中你应该放置 node ,而不是 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);
我在原版上查看过 Linux 3.12.