yangsuqing
驱动牛犊
驱动牛犊
  • 注册日期2009-02-19
  • 最后登录2010-07-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望41点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4126回复:13

透明加密标识总结

楼主#
更多 发布于:2009-11-18 15:07
近日写了个Demo,主要是在文件尾部添加加密标识,采用的sfilter,刷缓存的技术


透明加密最重要需要关注几点
一、缓存管理
由于我采用的是单缓存技术,比较传统,所以必须刷缓存
刷缓存需要注意刷缓存的策略和时机。


二、文件追踪管理

主要是文件在打开、编辑、关闭的时候的跟踪
1、打开的时候创建跟踪,RtlInsertElementGenericTable
2、读写的时候引用跟踪
3、关闭的时候清除跟踪
需要搞清楚IRP_MJ_CLEANUP和irp_mj_close的区别
一般在应用层对文件的句柄为0的时候会进入IRP_MJ_CLEANUP中
而在kernel中对fileobject的引用为0的时候,会进入IRP_MJ_CLOSE中。缓存管理器初始化缓存的时候第一次会引用fileobject对象





三、加密标识管理

加密标识可以添加在文件头,文件尾,或者硬盘其它处,我做的稳定的是文件尾

添加加密标识重点需要搞清楚几个问题
举个简单的例子文档,如notepad操作txt,首先是notepad写内容至缓存,发write irp,然后set_info,设置文件长度,然后是system进程page io至硬盘
如果我们要添加加密标识的话,就是在写缓存的时候添加文件尾,然后在set_info的时候把我们添加的文件尾长度加上,最好pageio的时候加密

读的时候,notepad根本不发irp,直接采用的是mapviewoffile,怎么保证能经过我们的过滤驱动,就是刷缓存了。


1、在什么时候判断加密标识
很显然是在IRP_MJ_CREATE例程里面判断是否存在加密标识,自己发irp给文件系统查询

2、在什么时候写加密标识
在IRP_MJ_WRITE例程里面添加加密标识
大家都知道,在写例程里面重点关注两种,一种是写入缓存,irp Flag一般是0xa00(IRP_DEFER_IO_COMPLETION|IRP_WRITE_OPERATION);一种是page io写入硬盘
写入缓存的长度也就是IrpSp->Parameters.Write.Length就是你实际写入的长度,而写入硬盘page io,则写入的长度都是页的倍数(4k的倍数)
对数据的加密是在写入硬盘的时候加密,而添加文件尾是在写缓存的时候添加呢还是在写硬盘的时候添加呢:在写缓存的时候

非page io,进程上下文基本是应用程序的进程
而page io,进程一般是有system进程

当然也有文档操作是直接发page io的,如ppt,这需要在其它例程里面添加加密标识

添加加密标识需要注意的是,原来文件的长度有可能不是512的倍数,需要先拓展文件的长度,然后再添加文件尾

3、怎样“纠正”添加加密标识后的长度
说实话,这是比较麻烦的一块,需要用监控工具去查看很多文件类型的编辑过程
需要处理的过程比较多,如irp_mj_read,IRP_MJ_SET_INFORMATION、IRP_MJ_QUERY_INFORMATION、IRP_MJ_DIRECTORY_CONTROL,fastio里面的几个例程,都需要处理
处理的逻辑都不是很复杂,获取到真实长度,减去文件尾的长度和补齐的长度即可

总之这有个原则,就是保证应用层序读的长度不包含文件尾的长度,而在应用程序设置文件长度的时候又需要加上文件尾长度



四、其它细节处理

包括文件名的获取、重入管理、目录判断,字节对齐、自己构造发irp,这些网上都有成熟的代码,与业务没有太大的关系。



文件尾和文件头都做过,相对文件尾比较简单而稳定

现在论坛上讨论的比较多的minifilter、双缓存技术比较多,还需要学习哈

最新喜欢:

flyingeagles125flying...
游客

返回顶部