阅读:4411回复:24
关于透明为文件增加文件头的问题
我现在正在写一个过滤驱动,需要为文件增加一个文件头,并且向应用程序屏蔽增加了文件头这个事实。
我尝试了在IRP_MJ_CREATE例程完成后,将文件头写入到文件中的方法,但是存在一些问题。我使用的代码如下: BOOLEAN SetFileHeader( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN PVOID FileHeader ){ HANDLE hFile = NULL; NTSTATUS status; LONGLONG CurrentByteOffset; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER ByteOffset; FILE_END_OF_FILE_INFORMATION EndOfFileInfo; //获得文件句柄 status = ObOpenObjectByPointer( FileObject, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &hFile ); if( !NT_SUCCESS( status ) ){ return FALSE; } ByteOffset.QuadPart = 0; status = ZwWriteFile( hFile, NULL, NULL, NULL, &IoStatus, FileHeader, PAGE_SIZE, &ByteOffset, NULL ); if( !NT_SUCCESS( status ) ){ ZwClose( hFile ); return FALSE; } ZwClose( hFile ); return TRUE; } 这段代码导致的结果是在cmd.exe中执行copy con 1.txt时,如果文件不存在时,文件头和内容均无法被写入,跟踪之后,发现问题出在ObOpenObjectByPointer和ZwClose上。 我现在有两个问题: 1)在IRP_MJ_CREATE例程中手工构造IRP来写入文件头是否可行? 2)还有没有更合适的写入文件头的时机? |
|
最新喜欢:![]() |
沙发#
发布于:2007-07-25 11:13
引用第22楼coolw于2007-06-02 23:05发表的 : 放在文件尾就是一个定时炸弹。文件损坏的风险太大。 |
|
|
板凳#
发布于:2007-07-24 13:06
测试发现:
在读文件标识时,我设置flag = 1, 到read中也是flag == 1 。。。。。。(1: IRP_NOCACHE) 但是,读真文时,flag = 0x900 (IRP_DEFER_IO_COMPLETION | IRP_READ_OPERATION) IRP_DEFER_IO_COMPLETION 应该是io延时的意思,我不理解了?????? |
|
地板#
发布于:2007-06-02 23:05
还是放在文件尾部好做点 文件头是比较难 不过也是可以完全实现的 嘿嘿
|
|
地下室#
发布于:2007-05-29 17:19
现在在CloseRoutine中,构建IRP_MJ_CREATE和IRP_MJ_WRITE的IRP来写入文件尾,但是总是出现STATUS_FILE_LOCK_CONFLICT的错误,不知道是怎么回事?
再有,由于手工构建IRP_MJ_CREATE时,必须自己调用ObCreateObject来创建FileObject对象,那么创建出来的FileObject对象该如何销毁呢?如果调用ObDereferenceObject来递减对象引用,那么肯定会导致IRP_MJ_CLOSE重入,这个问题又该怎么解决呢? 请killvxk和znsoft大侠明示。 |
|
5楼#
发布于:2007-05-19 21:48
没啥联系方式,QQ:86879759~
你用那个ZwCreateFile会有重入问题,你的用另外一个函数啊~Zw*函数对于irql有要求,你看一下就知道为啥推荐自己irp了~ 另外就是那个fileobject改标识,最好自己来查,自己动手丰衣足食 |
|
|
6楼#
发布于:2007-05-19 18:22
兄台,有没有什么联系方式,我们单独交流一下?
|
|
7楼#
发布于:2007-05-19 18:21
大哥,能不能告诉小弟需要修改哪几个标志可以直接使用close时的fileobject来执行写操作?
难道打开文件也要自己构建IRP来做?这样真的可以解决问题吗? 我现在是在closeroutine中执行了iocalldriver之后才调用写函数的,并且当pending时也进行了等待。 |
|
8楼#
发布于:2007-05-19 10:30
根据你的代码和你的描述~~
1.千万不要用ZW*的api来操作文件,用irp来工作。 2.重入打开文件的函数好像不对吧~ 3.另外就是一定得在Close完成後(pending的话,你得等啊~),再打开~ 4.可以通过改fileobject的几项来实现直接用close时的fileobject来写——请自己记录一下Close时的fileobject和READ/WRITE等时的Fileobject的区别~ 哈哈~ |
|
|
9楼#
发布于:2007-05-18 22:46
现在设置文件扩展信息的代码变成了如下的样子:
BOOLEAN SetFileHeader( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN PWCHAR FullFileName, IN PVOID FileHeader ){ PWCHAR FileNameBuffer = FullFileName; HANDLE hFile = NULL; PWCHAR FileName = NULL; UNICODE_STRING UniFileName; OBJECT_ATTRIBUTES Attributes; NTSTATUS Status; IO_STATUS_BLOCK StatusBlock; PHOOK_EXTENSION hookExt = (PHOOK_EXTENSION)DeviceObject->DeviceExtension; CHAR Drive = (CHAR)hookExt->LogicalDrive; BOOLEAN retVal = FALSE; LARGE_INTEGER ByteOffset; PFILE_OBJECT objFile; PIPPS_FILE_XINFO XInfo = (PIPPS_FILE_XINFO)FileHeader; FILE_STANDARD_INFORMATION StandardInfo; FileName = (PWCHAR)ExAllocatePoolWithTag( NonPagedPool, MAXPATHLEN*sizeof(WCHAR), IO_POOL_TAG_FILENAME ); memset( FileName,0,MAXPATHLEN*sizeof(WCHAR) ); wcsncpy( FileName,SHADOW_DEVICE_PREFIX,wcslen(SHADOW_DEVICE_PREFIX) ); if( FileNameBuffer[0] != L'\\' ){ wcsncat( FileName,L"\\",1 ); } wcsncat( FileName,FileNameBuffer,MAXPATHLEN-wcslen( FileNameBuffer ) ); FileName[20] = Drive; RtlInitUnicodeString( &UniFileName,FileName ); InitializeObjectAttributes( &Attributes, &UniFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); memset( &StatusBlock,0,sizeof(IO_STATUS_BLOCK) ); Status = ZwCreateFile( &hFile, FILE_GENERIC_WRITE, &Attributes, &StatusBlock, NULL, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_NO_INTERMEDIATE_BUFFERING, NULL, 0 ); if( !NT_SUCCESS( Status ) ){ retVal = FALSE; goto exit0; } // // Set shadow file object's Vpb // Status = ObReferenceObjectByHandle( hFile, FILE_ALL_ACCESS, NULL, KernelMode, &objFile, NULL); if( NT_SUCCESS( Status ) ){ if( ((PHOOK_EXTENSION)objFile->DeviceObject->DeviceExtension)->Type==SHADOW ){ IoDbgPrint( ("The file object is on a shadow device\n") ); } objFile->Vpb = NULL; ObDereferenceObject( &objFile ); } // // Query file size // Status = ZwQueryInformationFile( hFile, &StatusBlock, &StandardInfo, sizeof(StandardInfo), FileStandardInformation ); if( !NT_SUCCESS( Status ) ){ retVal = FALSE; goto exit0; } // // Set the LastPageFreeBytes of the extend information object // XInfo->LastPageFreeBytes = PAGE_SIZE - StandardInfo.EndOfFile.LowPart % PAGE_SIZE; DbgPrint( "LastPageFreeBytes: %d\n",XInfo->LastPageFreeBytes ); if( XInfo->LastPageFreeBytes == PAGE_SIZE ){ XInfo->LastPageFreeBytes = 0; } // // Write the extend information to the file // ByteOffset.QuadPart = StandardInfo.EndOfFile.QuadPart + XInfo->LastPageFreeBytes; DbgPrint( "ByteOffset: %d\n",ByteOffset.LowPart ); Status = ZwWriteFile( hFile, NULL, NULL, NULL, &StatusBlock, FileHeader, PAGE_SIZE, &ByteOffset, NULL ); // // Read extend information failure // if( !NT_SUCCESS( Status ) ){ retVal = FALSE; goto exit0; } // // Set the return values // retVal = TRUE; exit0: if( hFile != NULL ){ ZwClose( hFile ); } if( FileName != NULL ){ ExFreePool( FileName ); } return retVal; } |
|
10楼#
发布于:2007-05-18 22:44
没有找到STATUS_FILE_CLOSED的解决办法:(
使用隐藏设备来写入文件扩展信息,在CloseRoutine中调用IoCallDriver之后,使用独占的方式打开文件然后将文件扩展信息写入到文件中。使用这个办法担心如果在CloseRoutine完成之前,其他程序去打开这个文件该怎么办?独占模式能否解决这个问题? 但是使用隐藏设备时使用独占模式打开文件时出现了无法打开的问题,总是出现 STATUS_SHARE_VIOLATION错误:( 不知道到底在CloseRoutine中写入文件尾到底该怎么做? |
|
11楼#
发布于:2007-05-17 17:28
在处理IRP_MJ_CLOSE的CloseRoutine中使用传进来的FileObject构建IRP来执行写入操作,报STATUS_FILE_CLOSED错误。
我在网上查找STATUS_FILE_CLOSED时,只能找到很少的资料,不知道什么情况下会报这个异常?引起这个异常的原因是不是因为FileObject的某个标志引起的? 请版主、killvxk 和各位大牛们明示..... |
|
12楼#
发布于:2007-05-17 09:40
我现在也有阅读devia提供的2003的部分源代码,希望能够对实现这个功能有所帮助~~~~~~
|
|
13楼#
发布于:2007-05-17 09:39
天哪~~~~~~~~~~~~~~~
![]() |
|
14楼#
发布于:2007-05-16 11:52
才处理掉,嘿嘿~
|
|
|
15楼#
发布于:2007-05-16 11:52
继续努力,我在这个问题上卡了两个月~
|
|
|
16楼#
发布于:2007-05-16 09:41
处理映射文件太难了
我试过Hook ZwMapViewOfSection函数的方法,试图通过改变其中的offset来改变映射方式,但是在hook函数中,通过SectionHandle获取FileObject时遇到了问题,无法正常获取,所以没有办法了 我觉得要出力映射文件除了在这个地方做之外,再没有更合适的地方了,因为一旦这个函数调用结束,返回的BaseAddress就已经和文件的起始位置关联起来了 继续处理解决放在尾部的问题...... 呜呼哀哉。。。。。 |
|
17楼#
发布于:2007-05-16 09:22
引用第7楼stephenlv于2007-05-15 11:12发表的 : 放在文件尾部,要处理CLOSE问题,更痛苦~ 不如放在头部,放在头部主要是处理文件的映射问题, 挺困难,搞成了就好了~ |
|
|
18楼#
发布于:2007-05-15 11:12
放在文件首部,内存映射文件的问题太难解决了
尝试着放在文件尾部吧.... |
|
19楼#
发布于:2007-05-14 09:28
你说的自己来处理FastIo是什么意思?是不是自己来执行从缓存中拷贝数据的动作,如果不在缓存中,需要自己来构造IRP来执行PAGE IO?
本论坛的关于这方面的文章我都读过了,也看了本版版主的文章,说是把加密标志放在文件头很困难,所以他放在了文件的尾部。 但是我在想,如果放在尾部,Allocation Size, EndOfFile还有ValidDataLength是否该按如下方式进行调整: AllocationSize += TAG_SIZE; EndOfFile += TAG_SIZE; ValidDataLength保持不变? 如果标志放在文件尾部,如果在过滤驱动未被加载的时候,将文件拷贝其他的地方,譬如FTP到服务器上,是否文件加密标志就丢失了?? 这些问题请版主和各位大牛明示,谢谢! |
|
上一页
下一页