i8042prt__VMware中分析
参考网址:http://blog.csdn.net/iqian1314/article/details/5644943
我的环境:主机Win7x64,VMware10x86(XPsp3),WDK(GRMWDK_EN_7600_1.ISO) 安装的WinDBG也是x86版本
1、设备链
1.1、驱动对象
kd> !object \driver\i8042prt
Object: 82831da0 Type: (82da5398) Driver
ObjectHeader: 82831d88 (old version)
HandleCount: 0 PointerCount: 5
Directory Object: e12f59a0 Name: i8042prt
1.2、“kd> !strct driver_object fe4f69f0” 提示错误信息:“No export strct found”,换struct也一样“No export struct found”... 于是 换成命令dt:
kd> dt _driver_object 82831da0
nt!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : 0x827a7578 _DEVICE_OBJECT // ZC: 驱动"\driver\i8042prt"中的设备链中的第1个设备对象
+0x008 Flags : 0x12
+0x00c DriverStart : 0xf7677000 Void
+0x010 DriverSize : 0xb900
+0x014 DriverSection : 0x82c6e668 Void
+0x018 DriverExtension : 0x82831e48 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\i8042prt"
+0x024 HardwareDatabase : 0x80671ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf7680285 long i8042prt!GsDriverEntry+0
+0x030 DriverStartIo : 0xf7677910 void i8042prt!I8xStartIo+0
+0x034 DriverUnload : 0xf767deb6 void i8042prt!I8xUnload+0
+0x038 MajorFunction : [28] 0xf767aaa6 long i8042prt!I8xCreate+0
1.3、驱动"\driver\i8042prt"中的设备链中的第1个设备对象
kd> !devobj 827a7578
Device object (827a7578) is for:
\Driver\i8042prt DriverObject 82831da0
Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
DevExt 827a7630 DevObjExt 827a78c0
ExtensionFlags (0000000000)
AttachedDevice (Upper) 82bb5020 \Driver\vmmouse
AttachedTo (Lower) 82d9c3c8 \Driver\ACPI
Device queue is not busy.
这是用于鼠标的那个设备对象
1.3.1、
kd> dt _device_object 827a7578
nt!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0x348
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0x82831da0 _DRIVER_OBJECT
+0x00c NextDevice : 0x828313e8 _DEVICE_OBJECT // ZC: 指向设备链中的下一个设备对象
+0x010 AttachedDevice : 0x82bb5020 _DEVICE_OBJECT
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x2004
+0x020 Characteristics : 0
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x827a7630 Void
+0x02c DeviceType : 0x27
+0x030 StackSize : 5 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : (null)
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 1
+0x0b0 DeviceObjectExtension : 0x827a78c0 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
1.4、设备链中的下一个设备对象 (具体到本次情况为 驱动"\driver\i8042prt"中的设备链中的第2个设备对象)
kd> !devobj 828313e8
Device object (828313e8) is for:
\Driver\i8042prt DriverObject 82831da0
Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
DevExt 828314a0 DevObjExt 82831730
ExtensionFlags (0000000000)
AttachedDevice (Upper) 82831200 \Driver\Kbdclass
AttachedTo (Lower) 82d9c4e0 \Driver\ACPI
Device queue is not busy.
1.4.1、
kd> dt _device_object 828313e8
nt!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0x348
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0x82831da0 _DRIVER_OBJECT
+0x00c NextDevice : (null)
+0x010 AttachedDevice : 0x82831200 _DEVICE_OBJECT
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x2004
+0x020 Characteristics : 0
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x828314a0 Void
+0x02c DeviceType : 0x27
+0x030 StackSize : 5 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : (null)
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 1
+0x0b0 DeviceObjectExtension : 0x82831730 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
1.5、
2、设备栈
2.1、
kd> !devstack 828313e8 !DevObj !DrvObj !DevExt ObjectName 82831200 \Driver\Kbdclass 828312b8 KeyboardClass0 > 828313e8 \Driver\i8042prt 828314a0 82d9c4e0 \Driver\ACPI 82d8b630 0000006e !DevNode 82de6410 : DeviceInst is "ACPI\PNP0303\4&5289e18&0" ServiceName is "i8042prt"
2.2、从上到下 来看:
2.2.1、最上面的 设备对象(3个设备对象 中的 第1个设备对象)
kd> !devobj 82831200
Device object (82831200) is for:
KeyboardClass0 \Driver\Kbdclass DriverObject 82831810 // ZC: 这个设备对象的名字为"KeyboardClass0",可以看到这一行前面是1个空格
Current Irp 00000000 RefCount 0 Type 0000000b Flags 00002044
Dacl e1000504 DevExt 828312b8 DevObjExt 82831398
ExtensionFlags (0000000000)
AttachedTo (Lower) 828313e8 \Driver\i8042prt // ZC: Attach到下面的设备对象828313e8上(这个设备对象属于驱动"\driver\i8042prt")
Device queue is not busy.
kd> dt _device_object 82831200
nt!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0x198
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0x82831810 _DRIVER_OBJECT // ZC: 属于驱动“\driver\kbdclass”(可以通过"!object 82831810"或者"!drvobj 82831810"来查看)
+0x00c NextDevice : (null)
+0x010 AttachedDevice : (null) // ZC: 本设备对象没有被别的设备对象Attach
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x2044
+0x020 Characteristics : 0
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x828312b8 Void
+0x02c DeviceType : 0xb
+0x030 StackSize : 6 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : 0xe10004f0 Void
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 0
+0x0b0 DeviceObjectExtension : 0x82831398 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
设备扩展:
kd> !devext _DEVOBJ_EXTENSION 82831398 // ZC: 莫名其妙,自己还蒙了个命令出来... !devext [<address> <type>] <address> is the address of a device extension to be dumped. <type> is the type of the object owning this extension: PCI if it is a PCI device extension ISAPNP if it is an ISAPNP device extension PCMCIA if it is a PCMCIA device extension HID if it is an HID device extension
kd> dt _DEVOBJ_EXTENSION 82831398
nt!_DEVOBJ_EXTENSION
+0x000 Type : 0n13
+0x002 Size : 0
+0x004 DeviceObject : 0x82831200 _DEVICE_OBJECT
+0x008 PowerFlags : 0x10
+0x00c Dope : (null)
+0x010 ExtensionFlags : 0
+0x014 DeviceNode : (null)
+0x018 AttachedTo : 0x828313e8 _DEVICE_OBJECT // ZC: Attach到下层的设备对象
+0x01c StartIoCount : 0n0
+0x020 StartIoKey : 0n0
+0x024 StartIoFlags : 0
+0x028 Vpb : (null)
2.2.2、中间的 设备对象(3个设备对象 中的 第2个设备对象)
kd> !devobj 828313e8
Device object (828313e8) is for:
\Driver\i8042prt DriverObject 82831da0 // ZC: 这个设备对象的名字为空,可以看到 这一行前面是2个空格
Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
DevExt 828314a0 DevObjExt 82831730
ExtensionFlags (0000000000)
AttachedDevice (Upper) 82831200 \Driver\Kbdclass // ZC: 被上层设备对象(82831200)Attach(这个设备对象属于驱动"\driverkbdclass")
AttachedTo (Lower) 82d9c4e0 \Driver\ACPI // ZC: Attach到下层的设备对象(82d9c4e0)(这个设备对象属于驱动"\driver\acpi")
Device queue is not busy.
kd> dt _device_object 828313e8
nt!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0x348
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0x82831da0 _DRIVER_OBJECT // ZC: 属于驱动i8042prt
+0x00c NextDevice : (null)
+0x010 AttachedDevice : 0x82831200 _DEVICE_OBJECT // ZC: 被上层设备对象 Attach
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x2004
+0x020 Characteristics : 0
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x828314a0 Void // ZC: 这个是“设备扩展”(这个是干嘛用的?),和下面的那个“设备对象扩展”有区别(区别是什么?)
+0x02c DeviceType : 0x27
+0x030 StackSize : 5 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : (null)
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 1
+0x0b0 DeviceObjectExtension : 0x82831730 _DEVOBJ_EXTENSION // ZC: 这个才是 “设备对象扩展”
+0x0b4 Reserved : (null)
kd> dt _DEVOBJ_EXTENSION 828314a0 // ZC: 这里显示的是“设备扩展”,不是“设备对象扩展”,而且对应的结构体肯定不是_DEVOBJ_EXTENSION !!!
nt!_DEVOBJ_EXTENSION
+0x000 Type : 0n5096
+0x002 Size : 0x8283
+0x004 DeviceObject : 0x82888d98 _DEVICE_OBJECT
+0x008 PowerFlags : 0
+0x00c Dope : 0x82d9c4e0 _DEVICE_OBJECT_POWER_EXTENSION
+0x010 ExtensionFlags : 0x82d9c4e0
+0x014 DeviceNode : (null)
+0x018 AttachedTo : 0x00000001 _DEVICE_OBJECT
+0x01c StartIoCount : 0n262145
+0x020 StartIoKey : 0n0
+0x024 StartIoFlags : 0x828314c4
+0x028 Vpb : 0x828314c4 _VPB
kd> dt _DEVOBJ_EXTENSION 82831730 // ZC: 这个 显示的才是“设备对象扩展”
nt!_DEVOBJ_EXTENSION
+0x000 Type : 0n13
+0x002 Size : 0
+0x004 DeviceObject : 0x828313e8 _DEVICE_OBJECT
+0x008 PowerFlags : 0
+0x00c Dope : (null)
+0x010 ExtensionFlags : 0
+0x014 DeviceNode : (null)
+0x018 AttachedTo : 0x82d9c4e0 _DEVICE_OBJECT // ZC: Attach到下层的设备对象
+0x01c StartIoCount : 0n0
+0x020 StartIoKey : 0n0
+0x024 StartIoFlags : 0
+0x028 Vpb : (null)
误打误撞,字段“设备扩展(DeviceExtension)” 还真能显示一些信息:(不知字段“设备扩展(DeviceExtension)” 是否对应的是 结构体_DEVICE_EXTENSION?)
kd> dt _DEVICE_EXTENSION 828314a0
ACPI!_DEVICE_EXTENSION
+0x000 Flags : 0x82888d98`828313e8
+0x000 UFlags : __unnamed
+0x008 Signature : 0
+0x00c DebugFlags : 0x82d9c4e0
+0x010 DispatchTable : 0x82d9c4e0 IRP_DISPATCH_TABLE
+0x014 WorkContext : WORK_QUEUE_CONTEXT
+0x014 Fdo : _FDO_DEVICE_EXTENSION
+0x014 Filter : _FILTER_DEVICE_EXTENSION
+0x014 Pdo : _PDO_DEVICE_EXTENSION
+0x058 WorkQueue : EXTENSION_WORKER
+0x058 Button : BUTTON_EXTENSION
+0x058 Thermal : THERMAL_EXTENSION
+0x058 LinkNode : LINK_NODE_EXTENSION
+0x058 Dock : DOCK_EXTENSION
+0x058 Processor : _PROCESSOR_DEVICE_EXTENSION
+0x088 DeviceState : 0 ( Stopped )
+0x08c PreviousState : 0 ( Stopped )
+0x090 PowerInfo : _ACPI_POWER_INFO
+0x10c DeviceID : 0xf767ebab "???"
+0x10c Address : 0xf767ebab
+0x110 InstanceID : 0xf767eb7d "???"
+0x114 ResourceList : (null)
+0x118 PnpResourceList : (null)
+0x11c OutstandingIrpCount : 0n0
+0x120 ReferenceCount : 0n2
+0x124 HibernatePathCount : 0n2
+0x128 RemoveEvent : (null)
+0x12c AcpiObject : 0x00010102 _NSObj
+0x130 DeviceObject : 0x00000008 _DEVICE_OBJECT
+0x134 TargetDeviceObject : 0x00000193 _DEVICE_OBJECT
+0x138 PhysicalDeviceObject : 0x00000001 _DEVICE_OBJECT
+0x13c ParentExtension : (null)
+0x140 ChildDeviceList : _LIST_ENTRY [ 0x1010000 - 0x10101 ]
+0x148 SiblingDeviceList : _LIST_ENTRY [ 0x1c9c0000 - 0x0 ]
+0x150 EjectDeviceHead : _LIST_ENTRY [ 0x1000013 - 0x0 ]
+0x158 EjectDeviceList : _LIST_ENTRY [ 0x0 - 0xf767a0ef ]
2.2.3、最下面的 设备对象(3个设备对象 中的 第3个设备对象)
kd> !devobj 82d9c4e0
Device object (82d9c4e0) is for:
0000006e \Driver\ACPI DriverObject 82de2df8 // ZC: 这个设备对象的名字为"0000006e",可以看到这一行前面是1个空格
Current Irp 00000000 RefCount 1 Type 00000032 Flags 00001040
Dacl e1000504 DevExt 82d8b630 DevObjExt 82d9c598 DevNode 82de6410
ExtensionFlags (0000000000)
AttachedDevice (Upper) 828313e8 \Driver\i8042prt // ZC: 被上层设备驱动(828313e8)Attach(这个设备对象属于驱动"\driver\i8042prt")
Device queue is not busy.
kd> dt _device_object 82d9c4e0
nt!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0xb8
+0x004 ReferenceCount : 0n1
+0x008 DriverObject : 0x82de2df8 _DRIVER_OBJECT // ZC: 属于的 驱动对象的地址
+0x00c NextDevice : 0x82d9c5f8 _DEVICE_OBJECT
+0x010 AttachedDevice : 0x828313e8 _DEVICE_OBJECT // ZC: 被上层设备对象Attach
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x1040
+0x020 Characteristics : 0x80
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x82d8b630 Void
+0x02c DeviceType : 0x32
+0x030 StackSize : 4 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : 0xe10004f0 Void
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 1
+0x0b0 DeviceObjectExtension : 0x82d9c598 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
kd> dt _devobj_extension 82d9c598
nt!_DEVOBJ_EXTENSION
+0x000 Type : 0n13
+0x002 Size : 0
+0x004 DeviceObject : 0x82d9c4e0 _DEVICE_OBJECT
+0x008 PowerFlags : 0x10
+0x00c Dope : (null)
+0x010 ExtensionFlags : 0
+0x014 DeviceNode : 0x82de6410 Void
+0x018 AttachedTo : (null) // ZC: 往下层没有Attach任何设备对象
+0x01c StartIoCount : 0n0
+0x020 StartIoKey : 0n0
+0x024 StartIoFlags : 0
+0x028 Vpb : (null)
从上自下:
\Device\KeyboardClass0(DRIVER_OBJECT 是 kbdclass)可以找到 没有名字地址为828313e8的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt);
没有名字地址为828313e8的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)可以找到 \Device\0000006e(DRIVER_OBJECT 是 ACPI)。
从下自上:
\Device\0000000e(DRIVER_OBJECT 是 ACPI) 可以找到 没有名字地址为828313e8的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt);
没有名字地址为828313e8的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)可以找到 \Device\KeyboardClass0(DRIVER_OBJECT 是 ACPI)。
现在我们对设备栈上的设备对象之间的联系,做一个总结:
设备栈上的设备对象,从上自下,通过 DEVICE_OBJECT 的 DEVOBJ_EXTENSION 的 +18 struct _DEVICE_OBJECT *AttachedTo 联系在一起。
设备栈上的设备对象,从下自上,通过 DEVICE_OBJECT 的 +10 struct _DEVICE_OBJECT *AttachedDevice 联系在一起。
ZC: 设备栈上的设备对象,往下层找 设备对象:_DEVICE_OBJECT.(+0x0b0 DeviceObjectExtension : _DEVOBJ_EXTENSION).(+0x018 AttachedTo) ==> 找到下层 设备对象(为NULL 则说明没有)
ZC: 设备栈上的设备对象,往上层找 设备对象:_DEVICE_OBJECT.(+0x010 AttachedDevice : 0x828313e8 _DEVICE_OBJECT) ==> 找到上层 设备对象(为NULL 则说明没有)
ZC: _DRIVER_OBJECT.(+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT) --> 得到本驱动中的 设备链中的第一个设备 --> 通过这个设备在 设备栈中 向上/下 寻找,即可遍历整个设备栈。
ZC: 设备链 / 设备栈 的 区别 和 联系 还是 不太明白... 以下是个人理解:
ZC: 设备链: _DRIVER_OBJECT.(+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT) --> 得到本驱动中的 设备链中的第一个设备 --> 然后通过 _DEVICE_OBJECT.(+0x00c NextDevice : Ptr32 _DEVICE_OBJECT) 遍历整个设备链
ZC: 一个设备链中的所有设备对象 属于 一个驱动程序中。
ZC: 看上面的操作例子 设备链 中的设备对象 可能不是同一类设备对象,而 设备栈 里面的都是相似类型的设备对象 (感觉这个说法不太准确,暂时[20161216]先这样理解,以后再说)
在观察键盘驱动的初始化过程中,我们看到了设备栈是如何建立起来的。
驱动 i8042prt ,驱动 kbdclass 分别调用 IoAttachDeviceToDeviceStack ,把自己相应的设备对象加入到键盘设备栈中。IoAttachDeviceToDeviceStack 会设置 DEVICE_OBJECT 的 DEVOBJ_EXTENSION 的 +18 struct _DEVICE_OBJECT *AttachedTo 和 DEVICE_OBJECT 的 +10 struct _DEVICE_OBJECT *AttachedDevice ,把两个对象联系在一起。并设置新加入的设备对象的 +30 char StackSize。
ZC: 遗留问题:(1)、本文章中 没有讲到 如何“观察键盘驱动的初始化过程” (2)、如何“观察键盘驱动的初始化过程”?
3、