请教文件系统过滤驱动开发的大体步骤
工作需要,开发文件系统上层过滤,比如说截获对磁盘的写操作,先
加密再写到磁盘,读的时候要解密再传给操作系统.要实现这样一来功能应该怎么做.有没有些参考资料推荐. windows下面介绍这东西挺多,反倒是linux下面的好像资料不多见.希望不吝赐教.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
[quote]原帖由 "viton_xuan" 发表:
工作需要,开发文件系统上层过滤,比如说截获对磁盘的写操作,先
加密再写到磁盘,读的时候要解密再传给操作系统.要实现这样一来功能应该怎么做.有没有些参考资料推荐. windows下面介绍这东西挺多,反倒是linux下面
若不想改, 就截获 它的系统调用
顶
如何截获?
我只想到修改应用层的动态连接库、系统调用和驱动程序这三种方法,但这些都需要修改原来的东西。有没有简单一些的,不用修改源码的那种?
你先写好自己的函数, 然后找到(运行时的) sys_call_table, 那里存放着系统调用的指针, 你修改指针, 指向你的函数, 你的函数来调用原来的函数
听君一句话,胜读10天书
意思大概明白,但是“找到(运行时的) sys_call_table”如何实现
有没有什么推荐资料
以前写的一个截获系统调用的模块,这个模块有很好的移植性,适应于2.4和2.6内核。
#include <linux/kernel.h>;
#include <linux/module.h>;
#include <linux/init.h>;
#include <linux/sched.h>;
#include <asm/unistd.h>;
MODULE_LICENSE("GPL";
unsigned long *sys_call_table=NULL;
asmlinkage int (*orig_mkdir)(const char *,int);
struct _idt
{
unsigned short offset_low,segment_sel;
unsigned char reserved,flags;
unsigned short offset_high;
};
unsigned long *getscTable(){
unsigned char idtr[6],*shell,*sort;
struct _idt *idt;
unsigned long system_call,sct;
unsigned short offset_low,offset_high;
char *p;
int i;
/* get the interrupt descriptor table */
__asm__("sidt %0" : "=m" (idtr));
/* get the address of system_call */
idt=(struct _idt*)(*(unsigned long*)&idtr[2]+8*0x80);
offset_low = idt->;offset_low;
offset_high = idt->;offset_high;
system_call=(offset_high<<16)|offset_low;
shell=(char *)system_call;
sort="\xff\x14\x85";
/* get the address of sys_call_table */
for(i=0;i<(100-2);i++)
if(shell==sort[0]&&shell[i+1]==sort[1]&&shell[i+2]==sort[2])
break;
p=&shell;
p+=3;
sct=*(unsigned long*)p;
return (unsigned long*)(sct);
}
asmlinkage int hacked_mkdir(const char * pathname, int mode){
printk("ID %d called sys_mkdir !\n",current->;pid);
return orig_mkdir(pathname,mode);
}
static int __init find_init(void){
sys_call_table = getscTable();
orig_mkdir=(int(*)(const char*,int))sys_call_table[__NR_mkdir];
sys_call_table[__NR_mkdir]=(unsigned long)hacked_mkdir;
return 0;
}
static void __exit find_cleanup(void){
sys_call_table[__NR_mkdir]=(unsigned long)orig_mkdir;
}
module_init(find_init);
module_exit(find_cleanup);
如单单是截获文件系统相关的系统调用,还有一个方法。这种方法与sys_call_table无关,而是作用于vfs文件系统。
Adore-ng rootkit提供了一种方法:可以通过修改vfs的函数跳转表来截获系统调用。
下面是一个截获readdir系统调用的模块例子:
#include <linux/sched.h>;
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/init.h>;
#include <linux/fs.h>;
#include <linux/file.h>;
MODULE_LICENSE("GPL";
char *root_fs="/";
typedef int (*readdir_t)(struct file *,void *,filldir_t);
readdir_t orig_root_readdir=NULL;
int myreaddir(struct file *fp,void *buf,filldir_t filldir)
{
int r;
printk("<1>;You got me partner!\n";
r=orig_root_readdir(fp,buf,filldir);
return r;
}
int patch_vfs(const char *p,readdir_t *orig_readdir,readdir_t new_readdir)
{
struct file *filep;
filep=filp_open(p,O_RDONLY,0);
if(IS_ERR(filep))
return -1;
if(orig_readdir)
*orig_readdir=filep->;f_op->;readdir;
filep->;f_op->;readdir=new_readdir;
filp_close(filep,0);
return 0;
}
int unpatch_vfs(const char *p,readdir_t orig_readdir)
{
struct file *filep;
filep=filp_open(p,O_RDONLY,0);
if(IS_ERR(filep))
return -1;
filep->;f_op->;readdir=orig_readdir;
filp_close(filep,0);
return 0;
}
static int patch_init(void)
{
patch_vfs(root_fs,&orig_root_readdir,myreaddir);
printk("<1>;VFS is patched!\n";
return 0;
}
static void patch_cleanup(void)
{
unpatch_vfs(root_fs,orig_root_readdir);
printk("<1>;VFS is unpatched!\n";
}
module_init(patch_init);
module_exit(patch_cleanup);
"\xff\x14\x85"是什么意思?为什么找到它就找到系统调用表的地址?