使用文件过滤驱动sfilter,IRP_MN_NOTIFY_CHANGE_DIRECTORY会卡住问题

工程需要,用上了一个sfilter的过滤驱动。

最后发现在添加搜索目录监控post过滤函数时,使用IE作为样本跑起来的时候,会卡住。

 

windbg 后,发现挂在。

kd> !process -1 7
PROCESS 81c96860 SessionId: 0 Cid: 03f8 Peb: 7ffdc000 ParentCid: 068c
DirBase: 07dc0300 ObjectTable: e1a24088 HandleCount: 497.
Image: IEXPLORE.EXE
VadRoot 8210e420 Vads 364 Clone 0 Private 5333. Modified 223. Locked 0.
DeviceMap e1a6ac20
Token e220a6e8
ElapsedTime 00:02:35.984
UserTime 00:00:01.437
KernelTime 00:00:03.484
QuotaPoolUsage[PagedPool] 133164
QuotaPoolUsage[NonPagedPool] 19816
Working Set Sizes (now,min,max) (8628, 50, 345) (34512KB, 200KB, 1380KB)
PeakWorkingSetSize 8653
VirtualSize 118 Mb
PeakVirtualSize 125 Mb
PageFaultCount 12462
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 6676

THREAD 820e9da8 Cid 03f8.0454 Teb: 7ffdf000 Win32Thread: e1236c70 WAIT: (Executive) KernelMode Non-Alertable
f81a8c78 NotificationEvent
IRP List:
81a0b008: (0006,01b4) Flags: 00000000 Mdl: 00000000
Not impersonating
DeviceMap e1a6ac20
Owning Process 0 Image: <Unknown>
Attached Process 81c96860 Image: IEXPLORE.EXE
Wait Start TickCount 23866 Ticks: 5882 (0:00:01:31.906)
Context Switch Count 6968 LargeStack
UserTime 00:00:01.187
KernelTime 00:00:02.875
Win32 Start Address 0x00130000
Start Address kernel32!BaseProcessStartThunk (0x7c810867)
Stack Init f81a9000 Current f81a8c04 Base f81a9000 Limit f81a3000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 16
ChildEBP RetAddr Args to Child
f81a8c1c 8050117a 820e9e18 820e9da8 804fa9be nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
f81a8c28 804fa9be 81a0b190 81f4ae80 81a0b008 nt!KiSwapThread+0x46 (FPO: [0,0,0])
f81a8c50 b21d58ce 00000000 00000000 00000000 nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f81a8c90 804eedf9 81f4ae80 81a0b008 806d12d0 EBSFS!SfPassThrough+0x108 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\programjob\work\ebs\sfilter\sfilter.c @ 2028]
f81a8ca0 80574b42 81a0b198 81a0b008 81d417a8 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f81a8cb4 8056f1d9 81f4ae80 81a0b008 81d417a8 nt!IopSynchronousServiceTail+0x60 (FPO: [Non-Fpo])
f81a8d38 8053d808 00000904 00000000 00000000 nt!NtNotifyChangeDirectoryFile+0x22f (FPO: [Non-Fpo])
f81a8d38 7c92eb94 00000904 00000000 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f81a8d64)
0012c7b8 7c92dc8b 7c82916f 00000904 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0012c7bc 7c82916f 00000904 00000000 00000000 ntdll!NtNotifyChangeDirectoryFile+0xc (FPO: [9,0,0])
0012c828 766035f1 00000904 00000001 0000001b kernel32!FindFirstChangeNotificationW+0xcb (FPO: [Non-Fpo])
0012c84c 765f5119 00040000 00000900 03484650 CRYPT32!InitRegistryStoreChange+0x3f (FPO: [Non-Fpo])

定位代码,就是这里waitfor

 

			status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
		    if (STATUS_PENDING == status) 
			{
	            NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
			    ASSERT(STATUS_SUCCESS == localStatus);
		    }
			ASSERT(KeReadStateEvent(&waitEvent) ||
				!NT_SUCCESS(Irp->IoStatus.Status));
			OnSfilterIrpPost(
					DeviceObject,
					((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,
					(PVOID)(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->UserExtension),
					Irp,status,context);
			status = Irp->IoStatus.Status;

  最后栈回溯到这里,!irp 命令查看。发现

irpsp->MinorFunction==IRP_MN_NOTIFY_CHANGE_DIRECTORY

irpsp->MajorFunction==IRP_MJ_DIRECTORY_CONTROL

找了下MSDN说明

IRP_MN_NOTIFY_CHANGE_DIRECTORY

Indicates a request for notification of changes to the directory. Usually, instead of satisfying this request immediately, the file system driver holds the IRP in a private queue. When a change occurs to the directory, the file system driver performs the notification, and dequeues and completes the IRP.

 

可以看出,原本IE是异步发出这个请求,可最后由于sfilter框架的问题,最后把这个变成了同步请求。自然这个请求就一直被卡住了。

所以在Pre处理的时候,直接放过IRP_MN_NOTIFY_CHANGE_DIRECTORY即可,这个mn不要放在post操作即可

 

posted @ 2012-07-16 10:19  kkindof  阅读(1307)  评论(0编辑  收藏  举报