Windows驱动之驱动对象和设备对象

文章目录

  • Windows驱动之驱动对象和设备对象
    • 1. 驱动对象
    • 2. 设备对象

Windows驱动之驱动对象和设备对象

在Windows驱动开发中,最重要的三个数据结构是驱动对象、设备对象和IRP;本文我们来探讨一下设备对象和驱动对象的结构。

1. 驱动对象

在windows中,驱动对象的结构体如下:

kd> dt nt!_DRIVER_OBJECT 86a37eb8
   +0x000 Type             : 0n4
   +0x002 Size             : 0n168
   +0x004 DeviceObject     : 0x86a36030 _DEVICE_OBJECT
   +0x008 Flags            : 0x212
   +0x00c DriverStart      : 0x89669000 Void
   +0x010 DriverSize       : 0x11000
   +0x014 DriverSection    : 0x86342918 Void
   +0x018 DriverExtension  : 0x86a37f60 _DRIVER_EXTENSION
   +0x01c DriverName       : _UNICODE_STRING "\Driver\Disk"
   +0x024 HardwareDatabase : 0x841be250 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
   +0x028 FastIoDispatch   : (null) 
   +0x02c DriverInit       : 0x89676c11     long  disk!GsDriverEntry+0
   +0x030 DriverStartIo    : (null) 
   +0x034 DriverUnload     : 0x8969592b     void  CLASSPNP!ClassUnload+0
   +0x038 MajorFunction    : [28] 0x8967e39f     long  CLASSPNP!ClassGlobalDispatch+0
  1. Type为对象的类型,作为驱动对象,这个类型为IO_TYPE_DRIVER.
  2. Size整个对象的大小。
  3. DeviceObject 设备对象的指针;对于一个驱动中创建的设备对象(IoCreateDevice),都是通过这个结构体和设备对象中的指针串联起来。
  4. Flags这个标记作用暂时未知。
  5. DriverStart 驱动文件加载到内存中的地址。
  6. DriverSize : 驱动文件的大小,这个是映射到内存中的大小,例如如下:
kd> lm vm disk
Browse full module list
start    end        module name
89669000 8967a000   disk       (pdb symbols)          e:\symbols\disk.pdb\D2AD04F7F4BF45C8A8F0E2BF689326F11\disk.pdb
    Loaded symbol image file: disk.sys
    Image path: disk.sys
    Image name: disk.sys
    Browse all global symbols  functions  data
    Timestamp:        Tue Jul 14 07:11:28 2009 (4A5BBF20)
    CheckSum:         000152A4
    ImageSize:        00011000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
  1. DriverSection : 这个是一个比较神奇的结构,在很多地方都没有讲明白这个结构,其实这个结构是一个LDR_DATA_TABLE_ENTRY的结构;windows系统中,所有的驱动都是通过这个结构串联起来。因此这里诞生出来一种猥琐的方法,就是摘除这个结构隐藏驱动,这个结构如下:
kd> dt nt!_LDR_DATA_TABLE_ENTRY 0x86342918 
   +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x86342898 - 0x86342990 ]
   +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xffffffff - 0xffffffff ]
   +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x018 DllBase          : 0x89669000 Void
   +0x01c EntryPoint       : 0x89676c11 Void
   +0x020 SizeOfImage      : 0x11000
   +0x024 FullDllName      : _UNICODE_STRING "\SystemRoot\system32\drivers\disk.sys"
   +0x02c BaseDllName      : _UNICODE_STRING "disk.sys"
   +0x034 Flags            : 0x9104000
   +0x038 LoadCount        : 1
   +0x03a TlsIndex         : 0
   +0x03c HashLinks        : _LIST_ENTRY [ 0x0 - 0x152a4 ]
   +0x03c SectionPointer   : (null) 
   +0x040 CheckSum         : 0x152a4
   +0x044 TimeDateStamp    : 0
   +0x044 LoadedImports    : (null) 
   +0x048 EntryPointActivationContext : (null) 
   +0x04c PatchInformation : 0x86342899 Void
   +0x050 ForwarderLinks   : _LIST_ENTRY [ 0x0 - 0x11000 ]
   +0x058 ServiceTagLinks  : _LIST_ENTRY [ 0x4a5bbf20 - 0x690064 ]
   +0x060 StaticLinks      : _LIST_ENTRY [ 0x6b0073 - 0x73002e ]
   +0x068 ContextInformation : 0x00730079 Void
   +0x06c OriginalBase     : 0
   +0x070 LoadTime         : _LARGE_INTEGER 0x644c6d4d`0410000f
  1. DriverExtension : 这个是驱动的扩展数据,结构如下(主要是AddDevice的回调函数):
kd> dt ntkrpamp!_DRIVER_EXTENSION 0x86a37f60
   +0x000 DriverObject     : 0x86a37eb8 _DRIVER_OBJECT
   +0x004 AddDevice        : 0x89693603     long  CLASSPNP!ClassAddDevice+0
   +0x008 Count            : 2
   +0x00c ServiceKeyName   : _UNICODE_STRING "Disk"
   +0x014 ClientDriverExtension : 0x86a378e8 _IO_CLIENT_EXTENSION
   +0x018 FsFilterCallbacks : (null) 
  1. DriverName : 驱动对象的名字,例如:"\Driver\Disk"。
  2. HardwareDatabase : 硬件数据库路径。
  3. FastIoDispatch : FastIo例程,这个是专门给文件系统使用的。
  4. DriverInit : 驱动入口函数,也就是DriverEntry.
  5. DriverStartIo : 这个指向串行处理的IO请求函数。
  6. DriverUnload : 驱动的卸载回调例程,如果驱动没有设置这个回调函数,那么驱动将不支持卸载。
  7. MajorFunction : 驱动IRP的分发函数,支持各种IRP的回调操作。

2. 设备对象

设备对象代码驱动的一个设备,结构如下:

kd> dt nt!_DEVICE_OBJECT 86f67020
   +0x000 Type             : 0n3
   +0x002 Size             : 0xf90
   +0x004 ReferenceCount   : 0n0
   +0x008 DriverObject     : 0x865bc670 _DRIVER_OBJECT
   +0x00c NextDevice       : 0x86f58020 _DEVICE_OBJECT
   +0x010 AttachedDevice   : 0x86f66a50 _DEVICE_OBJECT
   +0x014 CurrentIrp       : (null) 
   +0x018 Timer            : (null) 
   +0x01c Flags            : 0x40000
   +0x020 Characteristics  : 0
   +0x024 Vpb              : (null) 
   +0x028 DeviceExtension  : 0x86f670d8 Void
   +0x02c DeviceType       : 8
   +0x030 StackSize        : 8 ''
   +0x034 Queue            : <unnamed-tag>
   +0x05c AlignmentRequirement : 0
   +0x060 DeviceQueue      : _KDEVICE_QUEUE
   +0x074 Dpc              : _KDPC
   +0x094 ActiveThreadCount : 0
   +0x098 SecurityDescriptor : (null) 
   +0x09c DeviceLock       : _KEVENT
   +0x0ac SectorSize       : 0x200
   +0x0ae Spare1           : 1
   +0x0b0 DeviceObjectExtension : 0x86f67fb0 _DEVOBJ_EXTENSION
   +0x0b4 Reserved         : (null) 

这里我们只挑重要的成员来讲解,例如Type,Size意义不大的成员不做相关解释。

  1. DriverObject : 指向驱动对象,每个设备对象附属于驱动对象存在,这个指针就是指向对应的驱动对象。
  2. NextDevice : 下一个设备对象,驱动对象可能会创建很多的设备对象,所有的设备对象都是通过这个结构串联起来。
  3. AttachedDevice : 这个对象的上层设备对象,当我们发送IRP的时候,就会沿着这个指针找到设备对象的顶端,从顶端开始发送IRP。
  4. CurrentIrp : 这个结构体指向StartIo当前正在处理的IRP。
  5. Flags : 代表设备的属性:
flag值 含义
DO_BUFFERED_IO 读写操作使用缓冲方式(系统复制缓冲区)访问用户模式数据
DO_EXCLUSIVE 一次只允许一个线程打开设备句柄
DO_DIRECT_IO 读写操作使用直接方式(内存描述符表)访问用户模式数据
  1. DeviceExtension : 设备的扩展部分,用来驱动中各个函数交互的上下文。
  2. DeviceTypev : 设备类型。
  3. StackSize : 从当前设备开始,到PDO的设备栈数目(也就是说设备的个数)。
  4. DeviceQueue : 串行IO使用的设备队列。
  5. Dpc 设备的DPC队列。
  6. SecurityDescriptor : 设备的安全描述符。
  7. SectorSize : sector的大小,对于文件型对象这个是扇区大小512.
    13 DeviceObjectExtension : 设备对象的扩展,如下:
kd> dt nt!_DEVOBJ_EXTENSION 0x86f67fb0
   +0x000 Type             : 0n13
   +0x002 Size             : 0
   +0x004 DeviceObject     : 0x86f67020 _DEVICE_OBJECT
   +0x008 PowerFlags       : 0
   +0x00c Dope             : (null) 
   +0x010 ExtensionFlags   : 0x800
   +0x014 DeviceNode       : (null) 
   +0x018 AttachedTo       : (null)   //下层设备对象,这个一般很少使用
   +0x01c StartIoCount     : 0n0
   +0x020 StartIoKey       : 0n0
   +0x024 StartIoFlags     : 0
   +0x028 Vpb              : 0x86a339a0 _VPB  //卷参数块,如果是文件系统,那么联系卷和文件系统的桥梁
   +0x02c DependentList    : _LIST_ENTRY [ 0x86f67fdc - 0x86f67fdc ]
   +0x034 ProviderList     : _LIST_ENTRY [ 0x86f67fe4 - 0x86f67fe4 ]

你可能感兴趣的:(Windows驱动开发)