磁盘设备栈的设备传递

来源:互联网 发布:正版办公软件价格 编辑:程序博客网 时间:2024/04/30 10:03

磁盘设备栈的设备传递

 (2013-01-09 11:22:11)
转载
标签: 

磁盘设备栈

 

分区设备

 

卷设备

 

drx

 

小端口设备

 

it

分类: windows知识
理理清楚,主要是今天需要获取c盘对应的DRx设备。
文件访问的时候,关系到的设备栈如下:
ntfs device -> volume device -> partmgr device -> disk device -> port(mini-port) device

其中,文件系统设备到卷设备使用vpb;而分区设备到下面使用attach设备关系就可以找到。不过实际中,disk device到下层设备使用了extension+8,而不是attach关系设备。

剩下一个问题,卷设备如何传递到分区设备呢?

下个断点看到这样的栈:
1: kd> kb
ChildEBP RetAddr  Args to Child              
97d47cf0 81a4ba7c 856827b0 85b0a7e0 85b0a7e0 CLASSPNP!ClassGlobalDispatch
97d47d0c 889e82ed 00000000 85682430 857acc04 nt!IofCallDriver+0x3f
97d47d3c 81a4ba7c 00682430 85b0a7e0 857accd8 partmgr!PmGlobalDispatch+0x2e8
97d47d58 82862120 00000000 857acc20 82e6f404 nt!IofCallDriver+0x3f
97d47d7c 81a4ba7c 857acc20 85b0a7e0 82e6f420 volmgr!VmReadWrite+0x11b
97d47d98 82e6bc98 85b0a7e0 f9bd6000 857ad0d8 nt!IofCallDriver+0x3f
97d47dac 82e6bd9c 857ad0d8 85b0a7e0 00000001 fvevol!FveRequestPassThrough+0x5e
97d47dc8 82e6bfa9 00000001 f9bd6000 00000000 fvevol!FveReadWrite+0x38
97d47df8 82e6c03e 00000001 97d47e20 81a4ba7c fvevol!FveFilterRundownReadWrite+0x159
97d47e04 81a4ba7c 857ad020 85b0a7e0 000a0245 fvevol!FveFilterRundownWrite+0x48
97d47e20 82f1e740 85b0a7e0 00000000 00000003 nt!IofCallDriver+0x3f
97d47e94 82f1e86f 857add20 00000000 857adc68 rdyboost!SmdProcessReadWrite+0x73b
97d47ebc 81a4ba7c 857adc68 85b0a7e0 857ab0d8 rdyboost!SmdDispatchReadWrite+0x104
97d47ed8 82ed8782 00000000 857ab020 84a80004 nt!IofCallDriver+0x3f
97d47f0c 82ed84c6 85b0a7e0 97d47f34 81a4ba7c volsnap!VolsnapWriteFilter+0x277
97d47f18 81a4ba7c 857ab020 85b0a7e0 84a80040 volsnap!VolSnapWrite+0x19
97d47f34 88a2bc44 891872f8 97d47f54 81b0b3ba nt!IofCallDriver+0x3f
97d47f40 81b0b3ba 891873d4 ffffffff 81b317e8 Ntfs!NtfsStorageDriverCallout+0x14
97d47f40 81ac3150 891873d4 ffffffff 81b317e8 nt!KiSwitchKernelStackAndCallout+0x9e
89187388 81ac2fcf 88a2bc30 891873d4 00003000 nt!KeExpandKernelStackAndCalloutInternal+0x16b
891873a8 88a26bd0 88a2bc30 891873d4 00003000 nt!KeExpandKernelStackAndCalloutEx+0x1f
89187400 88a260bf 00000001 857ab020 88a2bc8c Ntfs!NtfsMultipleAsync+0xb7
8918756c 88a21233 89187710 0001f000 00000000 Ntfs!NtfsNonCachedIo+0x2f7
89187708 88a22e3a 0150070a 00000000 00100801 Ntfs!NtfsCommonWrite+0xe00
891878dc 81a4ba7c 857d7018 85b0a7e0 85be7768 Ntfs!NtfsFsdWrite+0x187
891878f8 82a21a9f 85b0a7e0 857f5ba0 857f5ba0 nt!IofCallDriver+0x3f
89187934 82a217db 89187958 00000000 00000000 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x24c
89187970 81a816be 857f5ba0 85b0a7e0 89187a80 fltmgr!FltpDispatch+0xc6
8918798c 81a81281 84a80274 00187a80 891879d4 nt!IoSynchronousPageWrite+0x1de

volmgr!VmReadWrite第一个参数就是卷设备:
1: kd> !object 857acc20
Object: 857acc20  Type: (84a8c040) Device
    ObjectHeader: 857acc08 (new version)
    HandleCount: 0  PointerCount: 10
    Directory Object: 83012600  Name: HarddiskVolume2

然后,VmReadWrite内部调用IofCallDriver把irp传递给下层分区设备处理,分区设备是怎么找到的呢?看下ida这个函数的实现,咋调用IofCallDriver的:

磁盘设备栈的设备传递

原来是通过卷设备的DeviceExtension+d0处找到下层分区设备的,这个disk到(小)端口设备很像,那个是+8:
1: kd> dt nt!_device_object 857acc20 
   +0x000 Type             : 0n3
   +0x002 Size             : 0x1c0
   +0x004 ReferenceCount   : 0n2751
   +0x008 DriverObject     : 0x85518428 _DRIVER_OBJECT
   +0x00c NextDevice       : 0x857afbf8 _DEVICE_OBJECT
   +0x010 AttachedDevice   : 0x857ad020 _DEVICE_OBJECT
   +0x014 CurrentIrp       : (null) 
   +0x018 Timer            : (null) 
   +0x01c Flags            : 0x1150
   +0x020 Characteristics  : 0x60000
   +0x024 Vpb              : 0x85680740 _VPB
   +0x028 DeviceExtension  : 0x857accd8 Void
   +0x02c DeviceType       : 7
   +0x030 StackSize        : 5 ''
   +0x034 Queue            :
   +0x05c AlignmentRequirement : 0
   +0x060 DeviceQueue      : _KDEVICE_QUEUE
   +0x074 Dpc              : _KDPC
   +0x094 ActiveThreadCount : 0
   +0x098 SecurityDescriptor : 0x8319e430 Void
   +0x09c DeviceLock       : _KEVENT
   +0x0ac SectorSize       : 0x200
   +0x0ae Spare1           : 1
   +0x0b0 DeviceObjectExtension : 0x857acde0 _DEVOBJ_EXTENSION
   +0x0b4 Reserved         : (null) 
1: kd> dd 0x857accd8+d0 l1
857acda8  85682430
1: kd> !object 85682430
Object: 85682430  Type: (84a8c040) Device
    ObjectHeader: 85682418 (new version)
    HandleCount: 0  PointerCount: 5
1: kd> !devobj 85682430
Device object (85682430) is for:
  \Driver\partmgr DriverObject 85519320
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000010
Dacl 8c0d152c DevExt 856824e8 DevObjExt 85682740 
ExtensionFlags (0x00000800)  
                             Unknown flags 0x00000800
AttachedTo (Lower) 856827b0 \Driver\disk
Device queue is not busy.
1: kd> !devstack 85682430
  !DevObj   !DrvObj            !DevExt   ObjectName
> 85682430  \Driver\partmgr    856824e8  
  856827b0  \Driver\disk       85682868  DR0
  8552f030  \Driver\LSI_SAS    8552f0e8  0000002d
!DevNode 8554adc0 :
  DeviceInst is "SCSI\Disk&Ven_VMware_&Prod_VMware_Virtual_S\5&1982005&0&000000"
  ServiceName is "disk"

现在,怎么传递已经清楚了。那么,系统是如何获取卷设备下层的分区设备并填充在卷设备的扩展中的呢?
 
TODO
0 0