阅读:2249回复:8
请tooflat版主进来看看
我参考了你的流加密代码sfilter,写了如下东西,结果运行蓝屏,请指教
NTSTATUS SfCreate ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This function filters create/open operations. It simply establishes an I/O completion routine to be invoked if the operation was successful. Arguments: DeviceObject - Pointer to the target device object of the create/open. Irp - Pointer to the I/O Request Packet that represents the operation. Return Value: The function value is the status of the call to the file system's entry point. --*/ { NTSTATUS status; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = IrpSp->FileObject; PAGED_CODE(); // // If this is for our control device object, don't allow it to be opened. // if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { // // Sfilter doesn't allow for any communication through its control // device object, therefore it fails all requests to open a handle // to its control device object. // // See the FileSpy sample for an example of how to allow creates to // the filter's control device object and manage communication via // that handle. // Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_INVALID_DEVICE_REQUEST; } ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); // // If debugging is enabled, do the processing required to see the packet // upon its completion. Otherwise, let the request go with no further // processing. // if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION | SFDEBUG_GET_CREATE_NAMES| SFDEBUG_DISPLAY_CREATE_NAMES )) { // // Don't put us on the stack then call the next driver // IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } else { KEVENT waitEvent; // // Initialize an event to wait for the completion routine to occur // KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); // // Copy the stack and set our Completion routine // IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, SfCreateCompletion, &waitEvent, TRUE, TRUE, TRUE ); // // Call the next driver in the stack. // status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); // // Wait for the completion routine to be called // if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } // // Verify the IoCompleteRequest was called // ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); // // Retrieve and display the filename if requested // if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } // // Save the status and continue processing the IRP // status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); { POST_CREATE_WORKER_CONTEXT WorkerCtx; PFILE_CONTEXT FileCtxPtr = NULL; FileCtxPtr = ExAllocatePoolWithTag( NonPagedPool, sizeof( FILE_CONTEXT ), SFLT_POOL_TAG ); if(FileCtxPtr==NULL) return status; FileCtxPtr->RefCount = 1; KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE); ExInitializeWorkItem(&WorkerCtx.WorkItem, SfIsEncryptFlagExist, &WorkerCtx); WorkerCtx.DeviceObject = DeviceObject; WorkerCtx.FileObject = FileObject; KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE); WorkerCtx.FileContext = FileCtxPtr; //WorkerCtx.NewElement = NewElement; if (KeGetCurrentIrql() == PASSIVE_LEVEL) SfIsEncryptFlagExist(&WorkerCtx); else { ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue); KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL); } ExFreePool(FileCtxPtr); } return status; } } NTSTATUS SfIsEncryptFlagExist(IN PVOID Context) { PPOST_CREATE_WORKER_CONTEXT WorkerCtx = Context; NTSTATUS Status; IO_STATUS_BLOCK IoStatus={0}; UCHAR Buff[512]={0}; //PACKAGERINFO packagerinfo; //包信息 int nPackagerLen; WCHAR EncryptFlagFile[MAX_PATH*2] = {L'\0'}; LARGE_INTEGER ByteOffset; PFILE_CONTEXT FileCtxPtr = WorkerCtx->FileContext; KeWaitForSingleObject(&FileCtxPtr->Event, Executive, KernelMode, FALSE, NULL); wcscpy(EncryptFlagFile,L"\\??\\"); //wcscat(EncryptFlagFile,WorkerCtx->FileContext->Name); //if(wcscmp(WorkerCtx->FileContext->Name,L"c:\\test\\test.txt")==0) { nPackagerLen=0; } //if(wcscmp(WorkerCtx->FileContext->Name,L"C:\\test\\test.txt")==0) { nPackagerLen=0; } ByteOffset.QuadPart=0; IoStatus.Status = STATUS_SUCCESS; IoStatus.Information = 0; Status =SfIssueReadWriteIrpSynchronously(WorkerCtx->DeviceObject ,WorkerCtx->FileObject,IRP_MJ_READ,&IoStatus,Buff, sizeof(Buff),&ByteOffset,0); if (!NT_SUCCESS(Status)) { if (STATUS_END_OF_FILE == Status) { WorkerCtx->FileContext->EncryptFlagExist=FALSE; Status = STATUS_SUCCESS; } KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE); return Status; } // memcpy(&packagerinfo,Buff,sizeof(PACKAGERINFO)); // if(memcmp(packagerinfo.btflags,"ftsafe",6)==0) // { // WorkerCtx->FileContext->EncryptFlagExist=TRUE; // memcpy(WorkerCtx->FileContext->Key,"123456",6);//解密密钥 // WorkerCtx->FileContext->Key[6]=0; // } // else // WorkerCtx->FileContext->EncryptFlagExist=FALSE; KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE); return Status; } NTSTATUS SfIssueReadWriteIrpSynchronously( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN ULONG MajorFunction, IN PIO_STATUS_BLOCK IoStatus, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset, IN ULONG IrpFlags ) { PIRP Irp = NULL; PIO_STACK_LOCATION IrpSp = NULL; KEVENT Event; NTSTATUS Status; ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE)); KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest( MajorFunction, DeviceObject, Buffer, Length, ByteOffset, &Event, IoStatus ); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Irp->Flags |= IrpFlags; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->FileObject = FileObject; Status = IoCallDriver(DeviceObject, Irp); if (STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } return IoStatus->Status; }蓝屏信息如下:BugCheck 7E, {c0000005, 804f9810, f9e7aad8, f9e7a7d8} ANALYSIS: Kernel with unknown size. Will force reload symbols with known size. ANALYSIS: Force reload command: .reload /f ntoskrnl.exe=FFFFFFFF804D5000,1F2700,3D6DE35C ***** Kernel symbols are WRONG. Please fix symbols to do analysis. Probably caused by : ntoskrnl.exe ( nt!ExFreeToPagedLookasideList+9d ) Followup: MachineOwner --------- nt!DbgBreakPointWithStatus+0x4: 805113fa cc int 3 kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common bugcheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: c0000005, The exception code that was not handled Arg2: 804f9810, The address that the exception occurred at Arg3: f9e7aad8, Exception Record Address Arg4: f9e7a7d8, Context Record Address Debugging Details: ------------------ ***** Kernel symbols are WRONG. Please fix symbols to do analysis. MODULE_NAME: nt FAULTING_MODULE: 804d5000 nt DEBUG_FLR_IMAGE_TIMESTAMP: 3d6de35c EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" FAULTING_IP: nt!ExFreeToPagedLookasideList+9d 804f9810 8b4024 mov eax,dword ptr [eax+24h] EXCEPTION_RECORD: f9e7aad8 -- (.exr 0xfffffffff9e7aad8) ExceptionAddress: 804f9810 (nt!ExFreeToPagedLookasideList+0x0000009d) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 00000124 Attempt to read from address 00000124 CONTEXT: f9e7a7d8 -- (.cxr 0xfffffffff9e7a7d8) eax=00000100 ebx=806ca190 ecx=00000000 edx=00000000 esi=f7bb0c20 edi=806ca158 eip=804f9810 esp=f9e7aba0 ebp=f9e7acf0 iopl=0 nv up ei pl zr na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246 nt!ExFreeToPagedLookasideList+0x9d: 804f9810 8b4024 mov eax,dword ptr [eax+24h] ds:0023:00000124=???????? Resetting default scope DEFAULT_BUCKET_ID: WRONG_SYMBOLS BUGCHECK_STR: 0x7E LAST_CONTROL_TRANSFER: from 80581d00 to 804f9810 STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. f9e7acf0 80581d00 f7bb0c20 00000000 00000000 nt!ExFreeToPagedLookasideList+0x9d f9e7ad34 804ef99d 81bbc298 8054fda0 81bbeda8 nt!FsRtlAcquireFileExclusive+0xd f9e7ad74 804ee629 81bbc298 00000000 81bbeda8 nt!KeReadStateEvent+0xa5 f9e7adac 8057d73a 81bbc298 00000000 00000000 nt!KeInsertQueue+0xfc f9e7addc 805134c1 804ee556 00000000 00000000 nt!CcUnpinDataForThread+0x66d 00000000 00000000 00000000 00000000 00000000 nt!KeProfileInterruptWithSource+0x28e FOLLOWUP_IP: nt!ExFreeToPagedLookasideList+9d 804f9810 8b4024 mov eax,dword ptr [eax+24h] SYMBOL_STACK_INDEX: 0 FOLLOWUP_NAME: MachineOwner IMAGE_NAME: ntoskrnl.exe SYMBOL_NAME: nt!ExFreeToPagedLookasideList+9d STACK_COMMAND: .cxr 0xfffffffff9e7a7d8 ; kb BUCKET_ID: WRONG_SYMBOLS Followup: MachineOwner --------- 这啥原因呀,难道下发自己的IRP有问题,屏蔽下发IRP后就没问题了。。。 |
|
沙发#
发布于:2007-07-10 09:43
自己顶一个
|
|
板凳#
发布于:2007-07-10 13:18
你是在IoCompleteRequest( Irp, IO_NO_INCREMENT );
后进行处理的,这时候可能这个FileObject已经不存在了,这是问题一。 另外如果这个FileObject是从栈上分配,用缓冲IO去读文件,会导致cache mgr对这个文件进行缓冲处理。当这个FileObject从栈上释放掉,cache mgr再操作备份的FileObject时,就会蓝屏,这是问题二。 |
|
地板#
发布于:2007-07-10 13:44
感谢tooflat回答,但我看你的代码也是在完成例程后对file_object对象进行操作的,下面代码为你的
Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp);//这里完成例程 if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status)) { FILE_CONTEXT FileCtx; PFILE_CONTEXT FileCtxPtr = NULL; BOOLEAN NewElement = FALSE; FileCtx.FsContext = FileObject->FsContext; ExAcquireFastMutex(&DevExt->FsCtxTableMutex); FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtx); if (FileCtxPtr) ++FileCtxPtr->RefCount; else { FileCtxPtr = RtlInsertElementGenericTable( &DevExt->FsCtxTable, &FileCtx, sizeof(FILE_CONTEXT), &NewElement ); FileCtxPtr->RefCount = 1; ASSERT(FileName); wcscpy(FileCtxPtr->Name, FileName); KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE); } ExReleaseFastMutex(&DevExt->FsCtxTableMutex); ExInitializeWorkItem(&WorkerCtx.WorkItem, SfPostCreateWorker, &WorkerCtx); WorkerCtx.DeviceObject = DeviceObject; WorkerCtx.FileObject = FileObject; KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE); WorkerCtx.FileContext = FileCtxPtr; WorkerCtx.NewElement = NewElement; if (KeGetCurrentIrql() == PASSIVE_LEVEL) SfPostCreateWorker(&WorkerCtx); else { ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue); KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL); }我的与你的好像没有区别呀! |
|
地下室#
发布于:2007-07-10 14:56
看看IoCompleteRequest是在什么调用的
|
|
5楼#
发布于:2007-07-10 16:38
我改了还是不行
NTSTATUS SfCreate ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This function filters create/open operations. It simply establishes an I/O completion routine to be invoked if the operation was successful. Arguments: DeviceObject - Pointer to the target device object of the create/open. Irp - Pointer to the I/O Request Packet that represents the operation. Return Value: The function value is the status of the call to the file system's entry point. --*/ { NTSTATUS status; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = IrpSp->FileObject; PAGED_CODE(); // // If this is for our control device object, don't allow it to be opened. // if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { // // Sfilter doesn't allow for any communication through its control // device object, therefore it fails all requests to open a handle // to its control device object. // // See the FileSpy sample for an example of how to allow creates to // the filter's control device object and manage communication via // that handle. // Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_INVALID_DEVICE_REQUEST; } ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); // // If debugging is enabled, do the processing required to see the packet // upon its completion. Otherwise, let the request go with no further // processing. // if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION | SFDEBUG_GET_CREATE_NAMES| SFDEBUG_DISPLAY_CREATE_NAMES )) { // // Don't put us on the stack then call the next driver // IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } else { KEVENT waitEvent; // // Initialize an event to wait for the completion routine to occur // KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); // // Copy the stack and set our Completion routine // IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, SfCreateCompletion, &waitEvent, TRUE, TRUE, TRUE ); // // Call the next driver in the stack. // status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); // // Wait for the completion routine to be called // if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } // // Verify the IoCompleteRequest was called // ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); // // Retrieve and display the filename if requested // if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } // // Save the status and continue processing the IRP // ///*****添加by lrf do{ POST_CREATE_WORKER_CONTEXT WorkerCtx; PFILE_CONTEXT FileCtxPtr = NULL; if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) { // // We don't care about directories // //ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); break; } FileCtxPtr = ExAllocatePoolWithTag( NonPagedPool, sizeof( FILE_CONTEXT ), SFLT_POOL_TAG ); if(FileCtxPtr==NULL) break; FileCtxPtr->RefCount = 1; KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE); ExInitializeWorkItem(&WorkerCtx.WorkItem, SfIsEncryptFlagExist, &WorkerCtx); WorkerCtx.DeviceObject = DeviceObject; WorkerCtx.FileObject = FileObject; KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE); WorkerCtx.FileContext = FileCtxPtr; //WorkerCtx.NewElement = NewElement; if (KeGetCurrentIrql() == PASSIVE_LEVEL) SfIsEncryptFlagExist(&WorkerCtx); else { ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue); KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL); } ExFreePool(FileCtxPtr); }while (FALSE); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } }tooflat大侠,帮忙呀 |
|
6楼#
发布于:2007-07-10 17:09
不清楚什么原因,有可能就是我上面说的问题二,改成用内存映射方式读试试。
另外你的调试符号有问题。 |
|
7楼#
发布于:2007-07-10 22:32
内存映射方式?如何实现亚,还请tooflat再度出手指点
|
|
8楼#
发布于:2007-07-12 09:44
期待
|
|