Chinaunix

标题: 截获读u盘的系统调用问题? [打印本页]

作者: petsatan    时间: 2007-12-05 09:41
标题: 截获读u盘的系统调用问题?
环境Redhat9.0 kernel2.4.20-8 VM虚拟机
源码如下:
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/file.h>

char *aim = "/mnt/usb/a"; ---------->这里一定a要是一个文件,是不是缺乏通用性 ???

MODULE_AUTHOR("petsatan@sohu");
MODULE_DESCRIPTION("Get the kernel function address ");
MODULE_LICENSE("GPL");

typedef ssize_t (*read_t)(struct file *, char *, size_t, loff_t *);
read_t orig_aim_read = NULL;

ssize_t encry_read(struct file *fp , char *buf , size_t count , loff_t *ppos)
{
ssize_t encryfile;

printk("<0> Congratulation! \n");
encryfile = orig_aim_read(fp ,buf ,count ,ppos);

return encryfile;
}

int switch_read(const char *p , read_t *orig_read , read_t new_read)
{
struct file *filep;
filep = filp_open(p , O_RDONLY , 0);
if(IS_ERR(filep))
return -1;
if(orig_read)
*orig_read = filep->f_op->read;
printk("read operation address:------- %p ------\n", filep->f_op->read);

filep->f_op->read = new_read;
filp_close(filep,0);
return 0;
}

int unswitch_read(const char *p, read_t orig_read)
{
struct file *filep;
filep = filp_open(p , O_RDONLY , 0);
if(IS_ERR(filep))
return -1;
filep->f_op->read = orig_read;
filp_close(filep,0);
return 0;
}

static int encryfile_init(void)
{
switch_read(aim , &orig_aim_read , encry_read);
printk(" <1>read() has switch!\n");
return 0;
}

static void encryfile_cleanup(void)
{
unswitch_read(aim, orig_aim_read);
printk("<2>read() has unswitch! \n");
}

module_init(encryfile_init);
module_exit(encryfile_cleanup);

输出如下:
Dec 4 21:19:36 localhost kernel: --------cc95fc68--------
Dec 4 21:19:36 localhost kernel: read() has switch!
Dec 4 21:19:47 localhost kernel: Congratulation! Get the function address !

看程序中标出的  :
      现在的问题是一定要 vi /mnt/usb/a 才会执行 printk("<0> Congratulation! \n")
那是不是对/mnt/usb/中其他文件的读写没有截获到呢? 那怎么才能截获到呢?

是不是因为对ext3系统的读写是通过 generic_file_read操作的,而此函数是被导出的,是固定的地址 所以在ext3文件系统操作正常,而usb的操作对应的函数没有被导出?
作者: albcamus    时间: 2007-12-05 09:41
file->f_op是在open时,从inode->i_fop赋值的; 而inode->i_fop,是在ext3_read_inode时, 从ext3_file_operations赋值的。

file只代表一个打开文件,改写它只影响该文件。  如果更改file->dentry->inode->i_fop,就不会这样了。
作者: petsatan    时间: 2007-12-05 13:17
非常感谢  我试试 。
我知道大师2年前对这个就有研究了。
作者: petsatan    时间: 2007-12-05 13:57
标题: 果然老鸟!!!! 确实如此,但是还有个问题?
/mnt/usb中一定要有个文件a 才可以 ,缺乏通用性 如果没有文件a ,那我这个模块就截获不到了啊?有什么解决办法?

[ 本帖最后由 petsatan 于 2007-12-5 14:05 编辑 ]
作者: albcamus    时间: 2007-12-05 14:01
标题: 回复 #4 petsatan 的帖子
靠!! 我不知道!!別管我叫什麼夠日的「大師」,惡心誰呢!!
作者: petsatan    时间: 2007-12-05 14:06
标题: 呵呵
是不是打开a  就创建了一个读写的上下文 这时file_operations中read指针才不为空?
作者: albcamus    时间: 2007-12-05 14:22
标题: 回复 #6 petsatan 的帖子
是這樣的。 open一個文件時,其file被申請,並且用相關的值賦給它。  實在不行就在open時制定CREAT,然後exit時unlink它。 - 這實在不是個好主意,不過我沒有更好的思路了。
作者: petsatan    时间: 2007-12-05 14:31
标题: 非常感谢!!! 痛哭流涕啊!
您啊再帮我想想  这么做实在 有点拿不出去啊  要给人看的啊。
作者: 流氓无产者    时间: 2007-12-05 23:34
fs有个连表吧,看能否去直接替换它的ops
作者: petsatan    时间: 2007-12-06 09:45
标题: 非常感谢 --- 流氓无产者
好象是有个 叫 filesystem_type的吧?

是这个吗?

您的意思是从链表中找到对应的文件系统,直接替换其中的ops指针?
作者: albcamus    时间: 2007-12-06 10:22
該導出的符號都不導出了,或者你強行寫ext3_file_operations也可以。 或者看一下/proc/mounts的實現,用kprobe截獲相關的數據和操作。
作者: petsatan    时间: 2007-12-06 11:31
标题: 回复 #11 albcamus 的帖子
强行截获?  u盘 一般是fat格式的吧。

/proc/mounts  是在哪个函数中实现的啊?
作者: petsatan    时间: 2007-12-06 15:35
标题: 回复 #7 albcamus 的帖子
还有个问题: 为什么只有在执行vi  /mnt/usb下任意文件的时候 才有  printk("<0> Congratulation! \n")   的输出,按道理说 filp_open的时候应该已经创建了一个读写的上下文啊?
作者: albcamus    时间: 2007-12-06 15:37
原帖由 petsatan 于 2007-12-6 15:35 发表
还有个问题: 为什么只有在执行vi  /mnt/usb下任意文件的时候 才有  printk(" Congratulation! \n")   的输出,按道理说 filp_open的时候应该已经创建了一个读写的上下文啊?


filp_open只是创建file结构并赋值, 此后的操作才能进入新的操作流程
作者: petsatan    时间: 2007-12-06 15:51
我insmod的时候 printk 那个fops的地址是固定的啊,赋值不就是把对应的处理的函数加载到对应的地址吗?
那我用在ext3系统时是模块一加载就输出的啊 ?是因为时刻都有对ext3的读写。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2