首页
社区
课程
招聘
[求助]filedisk加密的离奇故障……我给filedisk使用rc4加密读写,无法格式化生成的盘
发表于: 2013-4-20 18:48 12249

[求助]filedisk加密的离奇故障……我给filedisk使用rc4加密读写,无法格式化生成的盘

2013-4-20 18:48
12249
我修改filedisk的IRP_MJ_WRITE and IRP_MJ_READ回调并对其buffer进行rc4的加密
但是就无法格式化生成的盘
据测试……
注释掉加密的选项后……没有出现任何问题
而使用此加密算法加密别的东西没有问题……也就是说这个算法也木有问题(rc4不需考虑对齐问题)
驱网上貌似也有人提出同样的问题……希望大家能帮我解决这个问题……谢谢
附简化后的代码……
IRP_MJ_WRITE:

……
				if ((io_stack->Parameters.Write.ByteOffset.QuadPart +
				        io_stack->Parameters.Write.Length) >
				        device_extension->file_size.QuadPart)
				{
					irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
					irp->IoStatus.Information = 0;
				}
				Length = io_stack->Parameters.Write.Length;
				buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Write.Length);
				RtlCopyMemory(buffer, MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority), io_stack->Parameters.Write.Length);
				//x = (ULONG)&(io_stack->Parameters.Write.ByteOffset);
				rc4_Crypt(&rc4_s1,(unsigned char *)buffer,Length);//加密
				KdPrint(("WRITE io_stack->Parameters.Write.ByteOffset = %x",Length));
				ZwWriteFile(
				    device_extension->file_handle,
				    NULL,
				    NULL,
				    NULL,
				    &irp->IoStatus,
				    buffer,
				    Length,
				    &io_stack->Parameters.Write.ByteOffset,
				    NULL
				);
				ExFreePool(buffer);
……


IRP_MJ_READ
……
system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
				if (system_buffer == NULL)
				{
					irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
					irp->IoStatus.Information = 0;
					break;
				}
				buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Read.Length);
				Length = io_stack->Parameters.Read.Length;
				if (buffer == NULL)
				{
					irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
					irp->IoStatus.Information = 0;
					break;
				}
				ZwReadFile(
				    device_extension->file_handle,
				    NULL,
				    NULL,
				    NULL,
				    &irp->IoStatus,
				    buffer,
				    io_stack->Parameters.Read.Length,
				    &io_stack->Parameters.Read.ByteOffset,
				    NULL
				);
				//x = (ULONG)&(io_stack->Parameters.Read.ByteOffset);

				rc4_Crypt(&rc4_s2,(unsigned char *)buffer,Length;//解密
				KdPrint(("Read io_stack->Parameters.Read.ByteOffset = %x",Length));
				RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length);
				ExFreePool(buffer);


十分感谢您花费时间阅读我的帖子……真是纠结死我了

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (24)
雪    币: 194
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
ixz

我觉得,需要在完成例程中对read处理一下,同时在write时,write前处理处理一下,在write的完成函数中同时需要对处理过的write irp恢复,我写的usb过滤就是这么处理的,可以格式化。
2013-4-20 20:43
0
雪    币: 194
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这个应该是方法问题。。。
2013-4-20 20:44
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
请问您能具体说一下吗?十分感谢
2013-4-20 20:52
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我使用xor算法却没问题…………
2013-4-20 20:54
0
雪    币: 194
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
十分抱歉,刚才没有看代码,看了代码感觉没有问题。
2013-4-20 21:02
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
请问您能告诉我qq吗?我想跟您详细聊聊……
谢谢
2013-4-20 21:41
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
检查了很久还是没有查出什么问题……
我把rc4换成rc6同样出问题……
但是xor md5 或者直接xor rc4的密钥则不会出问题……
……崩溃中
2013-4-20 22:33
0
雪    币: 194
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
filedisk,我没有做个,只看过代码,需要测测才知道为什么.
2013-4-21 11:55
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我上传这个源码吧……我把几乎所有的代码都排除掉了……只剩下filedisk的基本代码和那一行加密代码了……结果还是不行……您来测测吧……谢谢

也有人有同样的问题 http://bbs.pediy.com/showthread.php?t=149992&highlight=%E9%80%8F%E6%98%8E+%E6%98%8E%E5%8A%A0+%E5%8A%A0%E5%AF%86

http://bbs3.driverdevelop.com/simple/?t72391.html
上传的附件:
2013-4-21 12:08
0
雪    币: 194
活跃值: (271)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我感觉格式化应该不走read,write..
2013-4-21 17:02
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
什么?……不走这个……怎么可能……不走read write……那他是如何写入的?
而且如果是xor 一个字节的话……所有的数据都还是被加密了……
谢谢您,您能将得更详细一些吗?
2013-4-21 20:00
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
我来告诉你吧
IRP_MJ_READ,IRP_MJ_Write是无序的,而rc4却是有顺序,顺前后关联的
详细点是:
IRP_MJ_... 时,每个块必须为页(512)对齐.而这些块的地址,是随机的,不是先第一块,再第二块,再第三块,这样取,而是有可能跳跃式读写,
但是rc4加密,必须前后顺序关联,比如,
你加密顺序为,1,2,3块
再解密顺序却不一致,为1,3,2这样,解密出来的数据就不对了,完全错误
解密时,你也得按加密顺序来,1,2,3这样,数据解密出来才会正确。

个人建议你更换加密算法,如果实在不想更换,那你的rc4算法的用法得变化一下,一个rc4的key仅对一页数据有效,加密下一页数据时,重置rc4 的key
这样
第一页(512)
rc4_set _key
rc4_encrypt()

第二页(512)
rc4_set _key
rc4_encrypt()

第n页(512)
rc4_set _key
rc4_encrypt()

对于我的说法,你可以仔细测试一下rc算法,就明白了
2013-4-22 09:43
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
那岂不是磁盘加密无法使用高强度的算法?
2013-4-22 18:17
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
换成什么算法比较好呢?貌似cbc模式的aes同样不行
2013-4-22 23:51
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
但是从Parameters.Write.ByteOffset获取的长度来看……读写的长度并不能被512整除……

一般都是2000……
这是什么原因
呢?
2013-4-23 17:27
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
回答你上面三个问题

第一,cr4算高强度算法?现在一般都用分组加密,比如AES,才叫高强度算法呢
第二,没人告诉你cr4不行啊,13楼都告诉你方法了,AES更不用说,必须可以用。
第三,你的输出是%x,你的2000,是0x2000,你自己算算0x2000是多少,能否被512整除。
2013-4-23 18:18
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
aes貌似不能直接用
2013-4-23 20:48
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
19
不管使用rc4、aes或者其他加密算法,一般要有个最小加密长度,这样向下对齐之后加密解密才正常,我通常加密的最小长度选512字节,以512字节为一个加密单元,因为磁盘层都是512字节对齐的,所以这个加密单元长度最好能被512整除,处理了这种加密对齐的关系之后基本就没啥难度了,可以看truecrypt是怎么弄的,不过对于初学者来说truecrypt代码可能比较绕,至于强度,选个rc4的长密钥(256字节)完全够用了,关键是rc4速度快,和aes不是在一个数量级上的。
2013-4-23 21:49
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
请问您能拿rc4或者rc6帮我做个例子吗?谢谢……以前对加密算法没有研究……一直都是做普通的底层开发……

到底需要如何使用这个算法才是正确的

谢谢
2013-4-23 21:52
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
唉,为啥我的filedisk用AES用得好好的,怎么就你不能用呢,都告诉你13楼的就是方法了,为啥你不相信呢
2013-4-23 22:09
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
22
typedef struct tagCrypt_info
{
	unsigned char Size;
	unsigned char Hash[256];
}CRYPT_INFO,*PCRYPT_INFO;
#define MIN_CRYPT_LEN 512
#define KEY_LEN 32
int EncryptUnit(PCRYPT_INFO CryptInfo,void *BufferIn,void*BufferOut)
{
	unsigned char *Start,*Out;
	aes_encrypt_ctx ctx={0};
	int Count=MIN_CRYPT_LEN/16,k=0,p=0;
	Start=(unsigned char*)BufferIn;
	Out=(unsigned char*)BufferOut;
	for(k=0,p=0;k<Count;k++,p++)
	{
		p=p%(256/32);
		
		aes_encrypt_key256(CryptInfo->Hash+p*KEY_LEN,&ctx);
		aes_encrypt(Start+k*16,Out+k*16,&ctx);	
	}
	return 1;
}

int DecryptUnit(PCRYPT_INFO CryptInfo,void *BufferIn,void*BufferOut)
{
	unsigned char *Start,*Out;
	aes_decrypt_ctx ctx={0};
	int Count=MIN_CRYPT_LEN/16,k=0,p=0;
	Start=(unsigned char*)BufferIn;
	Out=(unsigned char*)BufferOut;
	for(k=0,p=0;k<Count;k++,p++)
	{
		p=k;
		p=p%(256/32);
		aes_decrypt_key256(CryptInfo->Hash+p*KEY_LEN,&ctx);
		aes_decrypt(Start+k*16,Out+k*16,&ctx);	
	}
	return 1;
}

这个是很久前学习truecrypt的时候写的,很垃圾,每次实现512字节加密或者解密,使用它们对所有读写后的缓冲区进行加密或者解密就可以了,我这边代码还是能工作的,可以根据读写的地址对CRYPT_INFO的Hash进行一些变换,呵呵自己发挥吧……写加密的时候不要直接使用原来的缓冲区,自己再分配一个
2013-4-23 22:15
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
[QUOTE=鹿剑;1169894]typedef struct tagCrypt_info
{
        unsigned char Size;
        unsigned char Hash[256];
}CRYPT_INFO,*PCRYPT_INFO;
#define MIN_CRYPT_LEN 512
#define KEY_LE...[/QUOTE]

十分感谢………………太谢谢了
2013-4-23 23:32
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
楼主您好,我最近也在学习这个,请问您的代码应该如何测试呢?
磁盘加密的作用是否是:如果拷贝本磁盘的数据到其他磁盘,显示为密文?
2014-2-12 22:00
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
你说的这个是透明加密……汗……
2014-2-13 10:16
0
游客
登录 | 注册 方可回帖
返回
//