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、

 

posted @ 2016-12-16 09:12  DriverSkill  阅读(666)  评论(0编辑  收藏  举报