关于磁盘类过滤驱动,实现透明加密的几个小问题

关于磁盘类过滤驱动,实现透明加密的几个问题?
首先说一下思路:修改微软的diskperf框架,在IRP_MJ_READ和IRP_MJ_WIRTE中捕获读写数据,在加解密,然后在交给下一层驱动。

问题1:捕获数据是在IRP_MJ_READ和IRP_MJ_WIRTE中吗,当然IRP_MJ_READ是在完成例程中捕获的还是在其他地方?

问题2:在IRP_MJ_READ和IRP_MJ_WIRTE中的确能捕获到数据,但是我打开一个txt文档写入abcd4个字节保存,调试发现有4个以上的IRP包产生,但是只有一个包的MDL中有abcd,其他的IRP不知道是怎么产生的,如果我想加密的话,这些也加密可能会产生隐患,那么怎么过滤掉,或者说当什么标志产生的时候,是真正读写文件内容的数据。
读操作则产生的IRP更多,而且对所有读操作的IRP进行算法解密的时候,出现打开磁盘时提示磁盘未格式化的错误。

问题3:真正读写数据的大小,按理说我写入4个字节的数据,应该实际的写入大小是4字节啊!但是从两个地方获得的读写长度都不对Irp->IoStatus.Information和irpStack->Parameters.Write.Length

问题4:KdPrint(( "UserBuffer 写操作 Buffer: %ls length : %u\n \tWritelength :%u\n",
outstr, length,irpStack->Parameters.Write.Length));
这样为什么打印不出数据,outstr是从MDL中获得的缓冲区指针(char*型)。直接开内存是可以看到的。


写代码:
if ( Irp->MdlAddress != NULL )
{
buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
length = Irp->IoStatus.Information;
outstr = (CHAR*)buffer;
KdPrint(("MDL 写操作 Buffer: %ls length : %u\n \tWritelength :%u\n",
buffer, length,irpStack->Parameters.Write.Length));
// RtlCopyMemory(buffer,"JinEver",7);
}
else if ( Irp->UserBuffer != NULL)
{
buffer = Irp->UserBuffer;
length = Irp->IoStatus.Information;
outstr = (CHAR*)buffer;
KdPrint(( "UserBuffer 写操作 Buffer: %ls length : %u\n \tWritelength :%u\n",
outstr, length,irpStack->Parameters.Write.Length));
// RtlCopyMemory(buffer,"JinEver",7);
}
else
{
length = Irp->IoStatus.Information;
KdPrint(("Others 写操作 length :%u\n \tWritelength :%u\n",
length,irpStack->Parameters.Write.Length));
}

问题有点长,希望看仔细点。

------解决方案--------------------
寫磁盤不止寫在一個扇區中,而且先要寫到緩存。你改的地方不對吧。
------解决方案--------------------
寫磁盤不止寫在一個扇區中,而且先要寫到緩存。你改的地方不對吧。
------解决方案--------------------
磁盘读写最小单位是扇区
------解决方案--------------------
1、有很多IRP是不用处理的,你只需要处理IRP_MJ_READ和IRP_MJ_WIRTE就够了,长度为0的不用管
2、长度的问题我记不清楚了,但我记得应该是按照字长来处理的,如果是32位的系统,每次读写的应该是4的倍数,如果是64位系统,读写的长度是8的倍数,不够的会自动补足。
3、写的过程中,加密完了以后,在IRP返回时要对内存进行解密,将内存恢复到明文。
磁盘加密和文件加密都要注意一个地方,那就是要确保内存中的数据为明文!
------解决方案--------------------
每次写可能还会更新其他位置,比如文件修改时间,文件大小之类的
------解决方案--------------------
探讨

引用:

每次写可能还会更新其他位置,比如文件修改时间,文件大小之类的


我捕获到的数据可以看出,一般一次正常的写可以捕获到两个IRP,一个类似于log的IRP信息,另外一个才是真正读写的数据,但是不知道怎么区分开来

------解决方案--------------------
如果没缓存,磁盘读写最小一个扇区,一般512字节,如果是通过文件系统读写,一次最小一个簇,一般4096字节
如果有缓存,则不一定是这些数的整数倍

关键你这是磁盘过滤,不是文件系统过滤,文件系统驱动程序在写文件内容时还会干别的,有时把多次的写打包起来一次交给磁盘驱动,所以磁盘过滤驱动没法获得针对文件的精细的信息