msddk样例中toaster是一个比较完整和值得学习的pnp驱动,包括了一个完整的设备栈(含总线驱动/功能驱动,以及设备栈中各层过滤驱动)和驱动安装程序(含驱动安装包/类安装程序/协安装程序)。本篇记录在xp下调试busenum驱动入口(关于环境的搭建网上一搜一大把,这里就省了,当然也可以参考这篇:win7 x64部署和串口调试虚拟驱动toaster)。

通过添加硬件的方式安装busenum.sys后,会依次进入busenum.c!DriverEntry和pnp.c!Bus_AddDevice。AddDevice是本篇的重点,因此进入DriverEntry后在这个函数上下一个断点:

kd> lmvm busenum //查看驱动和调试符号加载是否正确
start    end        module name
b20e9000 b20f2b80   busenum    (private pdb symbols)  d:\winddk\7600.16385.1\src\general\toaster\wdm\bus\objchk_wxp_x86\i386\BusEnum.pdbLoaded symbol image file: busenum.sys kd> !itoldyouso busenum
busenum.sysTimestamp: 57639546SizeOfImage: 9B80pdb: d:\winddk\7600.16385.1\src\general\toaster\wdm\bus\objchk_wxp_x86\i386\BusEnum.pdbpdb sig: A0EB3691-6995-416E-9BF4-C25A160C9318age: 1
Loaded pdb is d:\winddk\7600.16385.1\src\general\toaster\wdm\bus\objchk_wxp_x86\i386\BusEnum.pdb
BusEnum.pdbpdb sig: A0EB3691-6995-416E-9BF4-C25A160C9318age: 1MATCH: BusEnum.pdb and busenum.sys

确定sys文件加载正确后,查找函数并下断点,然后继续运行:

kd> x busenum!Bus_AddDevice
b20eca60 busenum!Bus_AddDevice (struct _DRIVER_OBJECT *, struct _DEVICE_OBJECT *)
kd> bp busenum!Bus_AddDevice
kd> bl1 e b20eca60     0001 (0001) busenum!Bus_AddDevice

当windbg进入Bus_AddDevice遇到断点时,函数有两个参数:PDRIVER_OBJECT DriverObject和PDEVICE_OBJECT PhysicalDeviceObject。DriverObject很好理解,就是busenum.sys,有windbg为证:

kd> dd DriverObject l1
f8ae99e8  8227a3b8kd> !drvobj 8227a3b8
Driver object (8227a3b8) is for:\Driver\busenum

PhysicalDeviceObject是什么 呢?如果是pnp设备驱动,那很简单,这就是底层总线驱动对应的设备。但busenum本身是总线驱动,谁提供底层设备?答案是pnp管理器

kd> dd PhysicalDeviceObject l1
f8ae99ec  81f41030
kd> !devobj 81f41030 ---> 这个设备是pnp创建的设备
Device object (81f41030) is for:00000082 \Driver\PnpManager DriverObject 823eb2b0 ---> windbg指出,创建设备对象的驱动对象kd> !drvobj 823eb2b0
Driver object (823eb2b0) is for:\Driver\PnpManager  --->驱动对象
Driver Extension List: (id , addr)
该驱动对象的设备对象
Device Object list:
81f41030  823e73d0  823e7610  823e7850

原来,pnp管理器为了维护一颗设备树,在加载总线驱动前会为总线设备创建一个pnpmanage设备对象,作为设备栈的栈底对象,让总线设备attach上去。在busenum.sys代码中也有这种设备栈的上下体现:

NTSTATUS
Bus_AddDevice(__in PDRIVER_OBJECT DriverObject,__in PDEVICE_OBJECT PhysicalDeviceObject)
{status = IoCreateDevice (DriverObject,...,&deviceObject);deviceData->UnderlyingPDO = PhysicalDeviceObject;deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (deviceObject,PhysicalDeviceObject);
}

首先代码创建busenum.sys的设备对象,然后attach到pnpmanager设备对象上。难怪toaster的帮助文档中注释这个对象为Fdo,而把Bus_AddDevice的第二个参数认为是Pdo。

来看下创建设备后设备栈情况:

kd> !drvobj 8227a3b8
Driver object (8227a3b8) is for:\Driver\busenum
Driver Extension List: (id , addr)
;相比刚进入DriverEntry时,现在busenum驱动对象下已经有一个设备对象了,这个就是调用IoCreateDevice时创建的
Device Object list:
81f2a930
kd> dd deviceObject l1
f8ae99dc  81f2a930 ;设备对象的地址
kd> !devobj 81f2a930 ;验证一下设备对象的属主
Device object (81f2a930) is for:\Driver\busenum DriverObject 8227a3b8
Current Irp 00000000 RefCount 0 Type 0000002a Flags 00000088
DevExt 81f2a9e8 DevObjExt 81f2aa90
ExtensionFlags (0000000000)
Device queue is not busy.
kd> !devstack 81f2a930 ;81f2a930就是前面IoCreateDevice创建的设备对象!DevObj   !DrvObj            !DevExt   ObjectName> 81f2a930  \Driver\busenum    81f2a9e8  81f41030  \Driver\PnpManager 00000000  00000082!DevNode 81f2a008 :DeviceInst is "ROOT\UNKNOWN\0000" ;设备实例ServiceName is "busenum"          ;设备对应的服务名

至此busenum的设备栈已经成形了,可以创建Fdo了。

在结束本文前,还有一些琐碎的东西需要记录。就是busenum.inf中DDinstall section

安装busenum驱动后,打开设备管理器,在system devices下可以看到设备对象。

如图所示,设备出现在system devices下,设备实例是ROOT\Unknow\0000。问题来了,为什么会这样?

首先,设备管理器是以类设备为视图,不同的设备类归入不同的类下(物以类聚)。因此出现在system devices下一定是刻意设定,那么这由谁来设定?当然是inf文件了,在version节中指定:下面的内容摘自bus.inf

[Version]
Signature="$WINDOWS NT$"
Class=System ;指明busenum属于system类
ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} ;类的guid
Provider=%MSFT%
DriverVer=09/21/2006,6.0.5736.1
CatalogFile=toaster.cat

其次,硬件ID,由inf文件DDinstall节指定,msdn文档上一般将DDinstall节认为是从Manufacturer开始:

[Manufacturer]
%StdMfg%=Standard[Standard]
; These are the toaster bus pnp ids%ToasterBus.DeviceDesc%=ToasterBus_Device, root\busenum ;root\busenum指定了设备的HardwareID

有了这两项,在结合驱动在注册表下的路径可以找到相应的信息:

先确定设备的总线关系,inf文件中已经指出了busenum属于root总线,它在注册表中的路径为:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root

设备实例ROOT\Unknow\0000表明,busenum在root总线的Unknow\0000下,在这个项中可以找到驱动的service和class信息:

1)通过ROOT\Unknow\0000索引驱动的service为busenum

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{SerivceName}下可以找到各种驱动注册的服务相关的注册表值:

对于busenum驱动ServiceName是busenum

ImagePath是驱动程序被安装的路径,这些信息在Inf文件中都有对应内容,

[ToasterBus_Device.NT.Services] ;这个节是服务安装节
AddService = busenum,%SPSVCINST_ASSOCSERVICE%, busenum_Service_Inst 
;AddService对应驱动在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\下创建的服务名
{4D36E97D-E325-11CE-BFC1-08002BE10318}
; -------------- busenum driver install sections
[busenum_Service_Inst]
DisplayName    = %busenum.SVCDESC% ;<span style="font-family: Arial, Helvetica, sans-serif;">busenum.SVCDESC</span><span style="font-family: Arial, Helvetica, sans-serif;">=busenum.SVCDESC = "Toaster Bus Enumerator"对应注册表项DisplayName和在设备管理器上显示的名字</span>
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START <span style="font-family: Arial, Helvetica, sans-serif;">;对应注册表的Start</span>
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\busenum.sys                       ;对应注册表中ImagePath
LoadOrderGroup = Extended Base

2)通过ROOT\Unknow\0000索引驱动的class信息

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{ClassGuid}
对于busenum驱动ClassGuid是{4D36E97D-E325-11CE-BFC1-08002BE10318},挨个找过去可以找到busenum注册表项:

这里InfPath名为oem12.inf,是因为系统把所有inf文件拷到系统路径后(c:\windows\inf),统一命名为oemxx.inf形式。而InfSection应该对应了设备的DDInstall节,这个节可能是当系统重启时需要加载设备时到对应的oemxx.inf中寻找DDInstall进行驱动安装的依据

DDK样例toaster分析(1)相关推荐

  1. amaze样例页面分析(一)

    amaze样例页面分析(一) 一.总结 1.从审查(inspect)中是很清楚的可以弄清楚这些part之间的结构关系的 2.一者在于弄清楚他们之间的结构关系,二者在于知道结构的每一部分是干嘛的 3.i ...

  2. (性能测试压箱底知识点)LR性能测试---结果(样例)分析

    LR性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源 ...

  3. linux waitpid实例,【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)...

    本文内容: 1.僵尸进程,孤儿进程的定义,区别,产生原因,处理方法 2.wait函数,waitpid函数的分析,以及比较 背景:由于子进程的结束和父进程的运行是一个异步的过程,即父进程永远无法预测子进 ...

  4. GoJS-FlowChart样例代码分析

    var $ = go.GraphObject.make; // 别名,方便使用myDiagram =$(go.Diagram, "myDiagramDiv", // 通过id指定画 ...

  5. Hyperledger Indy:开发指南样例代码分析 - 节点 Onboarding

    英文指南:https://github.com/hyperledger/indy-sdk/blob/master/doc/getting-started/getting-started.md#step ...

  6. 关联规则算法c语言样例及分析_推荐系统总结系列-关联规则算法(四)

    基于关联规则的推荐有三种方法:Apriori关联规则算法FP Tree关联规则算法:PrefixSpan关联规则算法: 关联规则挖掘推荐算法: 关联规则挖掘是一种在大规模交易中识别类似规则关系模式的通 ...

  7. python docx库使用样例_Python docx库用法示例分析

    本文实例分析了Python docx库用法.分享给大家供大家参考,具体如下: 打开及保存文件: from docx import Document document = Document('test. ...

  8. php session 反序列化,PHP SESSION反序列化本地样例分析

    PHP SESSION反序列化本地样例分析 0X00漏洞原因 主要原因是: ini_set('session.serialize_handler', 'php_serialize'); ini_set ...

  9. 斗地主AI算法——第十六章の样例分析

    上一章,我们已经完成了测试模块的开发.至此我们已经可以进行整体测试了.本章主要内容就是对随机生成的对局情况进行简单的分析. 实际上整个开发过程绝大部分时间都是用在样例分析上,通过样例给出的返回操作分析 ...

  10. 【原创】一个简单的StreamInsight样例分析:MarketMonitor

    MarketMonitor是2009年微软专业开发者大会上StreamInsight小组资深程序经理Torsten Grabs演讲中的第一个StreamInsight Demo.这个Demo演示了如何 ...

最新文章

  1. 原版销售累计超过150 000册的经典JavaScript入门书
  2. Android实时取景:用SurfaceView实现
  3. python3中map函数_解决Python3下map函数的显示问题
  4. Visual Studio .NET、.NET Framework和C#之间的联系
  5. DB2 SQL 递归实现多行合并
  6. java语言中的标识符_Java语言基本语法(一)————关键字标识符(Java语言标识符命名规范Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )...
  7. Graph(2014辽宁ACM省赛)
  8. 【追光者系列】Hikari连接池大小多大合适?(第一弹)
  9. 开发工具 idea中出现Error:(1, 1) java: 非法字符: ‘\ufeff‘
  10. 【JS点滴】substring和substr以及slice和splice的用法和区别。
  11. 几种程序的反汇编代码入口特征
  12. 【Golang】Go语言defer用法大总结(含return返回机制)
  13. COSMIC的后端学习之路——1.4 + 1.5 设计模式
  14. (最新版 易卷/自动出题平台)自动阅卷系统 | 自动阅卷机 | 网络阅卷系统
  15. 面试拆解:系统上线后Cpu使用率飙升如何排查?
  16. SQL Server研习录(25)——sql server触发器、instered表和deleted表知识详解及示例分析
  17. Python爬取满7天赎回零费率基金:短线基金定投
  18. GNS3基础路由技术实验
  19. MLCC(贴片)电容啸叫分析
  20. linux 动态库 软链接,Linux操作系统下动态库的生成及链接方法

热门文章

  1. 计算机毕业设计Java在线小说系统(源码+系统+mysql数据库+Lw文档)
  2. java实现飞机大战小游戏(源码+注释)
  3. JAVA实现简单计算器布局与功能(附完整源码)
  4. TCP-IP协议详解(2) 小喇叭开始广播 (以太网与WiFi协议)
  5. sql盲注 解决_sql盲注解决方案.docx
  6. SQL语句之数据库之创建视图
  7. vi vim 查找和替换字符串 命令
  8. plsql32位链接64位oracle,32位PLsql连接64位Oracle问题
  9. mark制图软件_绘图软件有哪些?
  10. 海康威视监控有线/无线安装调试