阅读:1550回复:10
内存恢复为明文的问题
用sfilter进行加解密时,我在写完成例程中将内存恢复为明文,为什么磁盘上显示的是明文而不是密文呢。
|
|
最新喜欢:cyliu |
沙发#
发布于:2005-06-21 21:03
我再说明白点,就是在IRP_MJ_WRITE中
OldBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority); OldBuffer获得内核的虚拟地址, 然后构造一个Mdl指向MyBuffer, Irp->MdlAddress = IoAllocateMdl(MyBuffer,DataLength,FALSE,TRUE,NULL); 加密时,直接对OldBuffer取反,然后将取反后的值copy给MyBuffer,当调用IoCallDriver()将MyBuffer传给底层驱动后,再在写完成例程中将OldBuffer恢复为明文,但最后的结果是传到磁盘上的文件前4K没有加密后面的都加密了,请问大家这是什么原因 |
|
板凳#
发布于:2005-06-22 08:41
不要直接对原来的缓冲区操作,包括去反、加密等等,而是先将原来缓冲区的内容拷贝给新缓冲区,然后对新缓冲区加密,这样就不用在完成例程当中做操作了。
|
|
地板#
发布于:2005-06-22 09:50
你说的我曾用过,但我没有将原来缓冲区的内容拷贝给新缓冲区,而是将原缓冲区取反后再赋值给新缓冲区的(如((PUCHAR)MyBuffer) = ~((PUCHAR)OldBuffer)),我觉的这样和你说的先将原来缓冲区的内容拷贝给新缓冲区,然后对新缓冲区加密差不多,但我用新建一个txt做测试时发现写的内容没加密,
|
|
地下室#
发布于:2005-06-22 11:10
你应该单字节去反吧,"MyBuffer = ~(PUCHAR)OldBuffer",这样的去反是什么结果?
for (Offset = 0; Offset < Length; ++Offset) { ((PUCHAR) MyBuffer)[Offset] = ~((PUCHAR) OldBuffer)[Offset]; } |
|
5楼#
发布于:2005-06-22 11:21
我就是单字节取反的,我刚才写错了,但是对新缓冲区加密时写到磁盘上后总是前4K没有加密,而调试时确实每个字节都取反加密的呀。你遇到过吗,请再帮帮忙
|
|
6楼#
发布于:2005-06-22 16:04
你说的问题我没有碰到过,我是加密到64字节以后就不加密了,后来换成每512自己处理一次以后就好了。
我以前用的也是单字节取反。 |
|
7楼#
发布于:2005-06-23 09:18
我给出IRP_MJ_WRITE的部分代码,请帮我看看,为什么新建时头4K就不能加密
SfWrite() { if(Irp->MdlAddress) OldBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority); else OldBuffer = Irp->UserBuffer; CompletionCtx = ExAllocateFromNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList); MyBuffer = ExAllocatePoolWithTag(NonPagedPool,DataLength,SFLT_POOL_TAG); RtlCopyMemory(MyBuffer,OldBuffer,DataLength); Irp->MdlAddress = IoAllocateMdl(MyBuffer,DataLength,FALSE,TRUE,NULL); for(Offset = 0;Offset<DataLength;++Offset) ((PUCHAR)MyBuffer)[Offset] = ~((PUCHAR)MyBuffer)[Offset]; CompletionCtx->OldMdl = Irp->MdlAddress; CompletionCtx->OldUserBuffer = Irp->UserBuffer; CompletionCtx->OldSystemBuffer = Irp->AssociatedIrp.SystemBuffer; CompletionCtx->OldBuffer = OldBuffer; CompletionCtx->MyBuffer = MyBuffer; CompletionCtx->Length = DataLength; MmBuildMdlForNonPagedPool(Irp->MdlAddress); Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,SfWriteCompletion, CompletionCtx, TRUE, TRUE,TRUE); return IoCallDriver( DevEx->AttachedToDeviceObject,Irp ); } 然后在写完成例程中,主要做的事就是将Irp中的几项恢复,如下 Irp->MdlAddress = CompletionCtx->OldMdl; Irp->UserBuffer = CompletionCtx->OldUserBuffer; Irp->AssociatedIrp.SystemBuffer = CompletionCtx->OldSystemBuffer; 这样有问题吗 |
|
8楼#
发布于:2005-06-23 10:26
以前我测试过单字节去反的加密方法,没有发现任何问题,包括大于64K字节的加密。你上面的代码我以前也用过,应该没有问题。
能不能这样猜想:前4k没有加密也可能是前4k被重复加密了,因为去反两次就又恢复明文了。 |
|
9楼#
发布于:2005-06-23 10:55
谢谢关注,我知道为什么前4K没加密了,主要是我用了改变文件长度再文件头加标记的方法来区别是否为加过密的文件,如果我把改变文件长度的代码注释掉,则文件都可以被加密,但我只知其一不知其二,不明白为什么改变了文件长度就不能对文件的头4K单子节取反,
|
|
10楼#
发布于:2005-06-23 11:37
的确在驱动当中想修改文件的长度十分困难,就是因为这个原因,对透明加解密采用的加密算法也提出了要求,也就是不能采用变长的分组加密算法,例如DES,3DES等等,以前有人说DES也有等长加密模式,可是我没有找到,如果哪位了解这方面的信息,麻烦告诉我。
|
|