阅读:4113回复:12
一份编译通过的可以针对word透明加密的驱动源代码,里边还有一些问题,向高手求助
一份编译通过的可以针对word透明加密的驱动源代码,是从楚狂人的代码例子中改的,里边还有一些问题,向高手求助
已经克服了重命名问题,现在这一份终于可以用word新建文件了,但是打开时出错,希望高手帮忙解决一下。 我还有以前的几份,其中一份已经实现把任意文件复制到d:\test目录下后就加密,然后用指定程序打开后就解密,但是word新建文件保存时就会word进程出错,等着整理一下也发上来。 这份代码,其中一个关键代码是在这里: cfIrpCreatePre { ………… // 得到了路径,打开这个文件。 file_h = cfCreateFileAccordingIrp( next_dev, &path, irpsp, &status, &my_file, &information); // 如果没有成功的打开,那么说明这个请求可以结束了 if(!NT_SUCCESS(status)) { /////////////ret = SF_IRP_COMPLETED;楚狂人原来是这样写的,结果rename前系统中会先出现一个Create新文件名的操作,应该是先查询一下啦,这里还是要放过的,否则会失败的。我跟踪调试了好一阵子才找出来的。 ret = SF_IRP_PASS;////////////现在我这样写,嘿嘿,可以重命名啦! break; } } 整个cfIrpCreatePre都列出来吧。 // 打开预处理。 ULONG cfIrpCreatePre( PIRP irp, PIO_STACK_LOCATION irpsp, PFILE_OBJECT file, PDEVICE_OBJECT next_dev) { UNICODE_STRING path = { 0 }; // 首先获得要打开文件的路径。 ULONG length = cfFileFullPathPreCreate(file,&path); NTSTATUS status; ULONG ret = SF_IRP_PASS; PFILE_OBJECT my_file = NULL; HANDLE file_h; ULONG information = 0; LARGE_INTEGER file_size,offset = { 0 }; BOOLEAN dir,sec_file; // 获得打开访问期望。 ULONG desired_access = irpsp->Parameters.Create.SecurityContext->DesiredAccess; WCHAR header_flags[4] = {L'C',L'F',L'H',L'D'}; WCHAR header_buf[4] = { 0 }; ULONG disp; // 无法得到路径,直接放过即可。 if(length == 0) return SF_IRP_PASS; // 如果只是想打开目录的话,直接放过 if(irpsp->Parameters.Create.Options & FILE_DIRECTORY_FILE) return SF_IRP_PASS; do { // 给path分配缓冲区 path.Buffer = ExAllocatePoolWithTag(NonPagedPool,length+4,CF_MEM_TAG); path.Length = 0; path.MaximumLength = (USHORT)length + 4; if(path.Buffer == NULL) { // 内存不够,这个请求直接挂掉 status = STATUS_INSUFFICIENT_RESOURCES; ret = SF_IRP_COMPLETED; break; } length = cfFileFullPathPreCreate(file,&path); if(!ustr_startwith(&path,L"\\Device\\HarddiskVolume2\\test")) //break; { if(path.Buffer != NULL) { ExFreePool(path.Buffer); path.Buffer =NULL;} return ret; } if(ustr_havechar(&path,L':')) { return ret; } // 得到了路径,打开这个文件。 file_h = cfCreateFileAccordingIrp( next_dev, &path, irpsp, &status, &my_file, &information); // 如果没有成功的打开,那么说明这个请求可以结束了 if(!NT_SUCCESS(status)) { //ret = SF_IRP_COMPLETED; ret = SF_IRP_PASS; break; } // 得到了my_file之后,首先判断这个文件是不是已经在 // 加密的文件之中。如果在,直接返回passthru即可 cfListLock(); sec_file = cfIsFileCrypting(my_file); cfListUnlock(); if(sec_file) { ret = SF_IRP_PASS; break; } // 现在虽然打开,但是这依然可能是一个目录。在这里 // 判断一下。同时也可以得到文件的大小。 status = cfFileGetStandInfo( next_dev, my_file, NULL, &file_size, &dir); // 查询失败。禁止打开。 if(!NT_SUCCESS(status)) { ret = SF_IRP_COMPLETED; break; } // 如果这是一个目录,那么不管它了。 if(dir) { ret = SF_IRP_PASS; break; } // 如果文件大小为0,且有写入或者追加数据的意图, // 就应该加密文件。应该在这里写入文件头。这也是唯 // 一需要写入文件头的地方。 if(file_size.QuadPart == 0 && (desired_access & (FILE_WRITE_DATA| FILE_APPEND_DATA))) { // 不管是否成功。一定要写入头。 DbgPrint("cfWriteAHeader \n"); cfWriteAHeader(my_file,next_dev); // 写入头之后,这个文件属于必须加密的文件 ret = SF_IRP_GO_ON; break; } // 这个文件有大小,而且大小小于头长度。不需要加密。 if(file_size.QuadPart < CF_FILE_HEADER_SIZE) { ret = SF_IRP_PASS; break; } // 现在读取文件。比较来看是否需要加密,直接读个8字 // 节就足够了。这个文件有大小,而且比CF_FILE_HEADER_SIZE // 长。此时读出前8个字节,判断是否要加密。 length = 8; status = cfFileReadWrite(next_dev,my_file,&offset,&length,header_buf,TRUE); if(status != STATUS_SUCCESS) { // 如果失败了就不加密了。 ASSERT(FALSE); ret = SF_IRP_PASS; break; } // 读取到内容,比较和加密标志是一致的,加密。 if(RtlCompareMemory(header_flags,header_buf,8) == 8) { // 到这里认为是必须加密的。这种情况下,必须返回GO_ON. ret = SF_IRP_GO_ON; break; } // 其他的情况都是不需要加密的。 ret = SF_IRP_PASS; } while(0); if(path.Buffer != NULL) ExFreePool(path.Buffer); if(file_h != NULL) ZwClose(file_h); if(ret == SF_IRP_GO_ON) { // 要加密的,这里清一下缓冲。避免文件头出现在缓冲里。 cfFileCacheClear(my_file); } if(my_file != NULL) ObDereferenceObject(my_file); // 如果要返回完成,则必须把这个请求完成。这一般都是 // 以错误作为结局的。 if(ret == SF_IRP_COMPLETED) { irp->IoStatus.Status = status; irp->IoStatus.Information = information; IoCompleteRequest(irp, IO_NO_INCREMENT); } // 要注意: // 1.文件的CREATE改为OPEN. // 2.文件的OVERWRITE去掉。不管是不是要加密的文件, // 都必须这样做。否则的话,本来是试图生成文件的, // 结果发现文件已经存在了。本来试图覆盖文件的,再 // 覆盖一次会去掉加密头。 disp = FILE_OPEN; irpsp->Parameters.Create.Options &= 0x00ffffff; irpsp->Parameters.Create.Options |= (disp << 24); return ret; } |
|
|
沙发#
发布于:2009-12-08 12:41
关于测试时的一些说明:
1。在这里可以很简单的添加加密进程。 BOOLEAN cfIsCurProcSec(void) { WCHAR name_buf[32] = { 0 }; UNICODE_STRING proc_name = { 0 }; UNICODE_STRING note_pad = { 0 }; ULONG length; RtlInitEmptyUnicodeString(&proc_name,name_buf,32*sizeof(WCHAR)); length = cfCurProcName(&proc_name); //RtlInitUnicodeString(¬e_pad,L"notepad.exe"); /*RtlInitUnicodeString(¬e_pad,L"wordpad.exe"); if(RtlCompareUnicodeString(¬e_pad,&proc_name,TRUE) == 0) return TRUE;*/ #define HHH(a) RtlInitUnicodeString(¬e_pad,a); if(RtlCompareUnicodeString(¬e_pad,&proc_name,TRUE) == 0) return TRUE; HHH(L"mspaint.exe"); HHH(L"wordpad.exe"); HHH(L"notepad.exe"); HHH(L"WINWORD.EXE"); return FALSE; } 2。cfIrpCreatePre中 if(!ustr_startwith(&path,L"\\Device\\HarddiskVolume2\\test")) 这里可以设置对某个盘某个目录加密。 否则word打开任意文件时都加密可不行了。 |
|
板凳#
发布于:2009-12-08 12:48
楚狂人的那个代码,对word文档进行透明,还要动大手术,拿来学习还可以……
|
|
地板#
发布于:2009-12-08 13:24
是呀,太多的改动需要进行了,我是正在做.
JeTus 是不是已经做成功了? |
|
地下室#
发布于:2009-12-09 10:51
不过,不是大手术,框架骨架都有了,就是一些细节问题啦.
|
|
5楼#
发布于:2009-12-09 12:20
呵呵,估计问题才刚刚开始。 打不开可能是文件长度处理不对,或者解密不对。
|
|
|
6楼#
发布于:2009-12-11 13:43
再看了楚狂人的文件透明加密以后,我现在也在做关于word透明加密的研究。有时间一起探讨探讨.QQ;563289754
|
|
7楼#
发布于:2009-12-15 15:20
upup
|
|
8楼#
发布于:2010-02-11 15:45
打开时出错问题怎么解决呀?
|
|
9楼#
发布于:2010-03-18 14:48
楼主,你的代码里缺少文件啊?
FileSecretHeader.c FileSecretHeader.h fat_headers整个目录都没有? 不知道能否给个完整的,我也刚开始学透明,woshixiaomao001@163.com 先谢谢了~ |
|
10楼#
发布于:2010-04-20 20:38
楼主的问题解决了吗? 给个联系方式 探讨一下吧
|
|
11楼#
发布于:2010-04-20 21:40
楼主你的测试代码也看不到加密呀。test目录中文件不能被普通进程打开,又不能考到别的地方,怎么看到文件是否加密呢?
|
|
12楼#
发布于:2010-09-21 09:06
楼主的问题不知道解决了没有,你那个重命名简单的那样改是不行的,后面对office文件编辑时那里确实需要设为complete
还有就是,新建word打不开应该是文件长度设定不对,在write里你可以看一下获得的文件长度是不是比实际的小 不知道楼主其他问题都解决没,我最近在做也遇到一些问题,希望可以探讨一下 |
|