驱动开发(WDM)

windows

设备对象名称(内核对象必须命名才能被用户层访问产生句柄)

  • \Driver\ 内核模式下访问
  • \.\ 用户模式下访问

winObj(symbollink设备名称的别名,各个节点查看)和devicetree等工具可查看,下载地址:http://www.osronline.com/

  • 设备节点driverNode,对应不同的设备资源PCI、USB等
  • 设备树,pnp管理的设备内部维护一个动态树

  • 设备堆栈driverStack,fdo、pdo、do组成设备栈(devtree的单个分支),irp从设备栈的顶层向底层传递,iocompelete从底层向顶层返回状态
  • 设备对象driverdeObject,一个设备至少一个设备对象,设备对象用户io请求响应,IoCreateDevice创建(需要指定devicetype,例如 FILE_DEVICE_UNKNOWN ),IoAttachDeviceToDeviceStack加入堆栈,DEVICE_EXTENSION用户自定义

分层模型

  • driver_object(结构未开放)和device_object,driver包含多个device对象的链表
  • device包含多个文件对象file_object
  • file_object接收多个irp数据包(内核和应用层隔离通过磁盘交互,需要文件对象)

不同设备的驱动使用不同结构,显卡设备函数地址存储在VIDEO_HW_INITIALIZATION_DATA中,修改函数地址即可自定义设备驱动

三种驱动程序

  • 总线驱动程序(负责和具体的硬件设备交互),单个 I/O 总线设备,并提供与设备无关的单槽功能,创建设备对象=>PDO
  • 功能驱动程序(设备功能的具体实现),驱动单个设备,创建设备对象=>FDO
  • 筛选器驱动,筛选设备的 I/O 请求、设备类或总线(使用ObReferenceObjectByHandle打开设备修改驱动关联的函数),创建设备对象=>DO

API

  • Io,IO管理
  • Ex,内存分配
  • Ke,内核对象调用函数,不能分页
  • Rtl,字符串内存操作
  • Zw、NT,文件和注册表操作
  • Ps,进程、线程

内核用户层数据交换

  • DO_BUFFERED_IO,内存小,效率低
  • DO_DIRECT_IO,内存大(浪费多),效率高

内核执行级别

  • CPU有0~3级的4个执行级别,ring0和ring3是操作系统使用的级别
  • wdm里面的代码不都是Kernel、有的运行在管理模块Executive中,内核代码不支持分页,管理成的代码都应加上PAGED_CODE
  • PAGED_CODE()只有check版本有效,当前函数执行级别>=DISPATCH_LEVAL只能使用非分页内存,使用分页内存assert中断,避免free版本蓝屏
  • #pragma alloc_text()允许函数页面回退

内核对象

  • 对象名称
  • 对象管理器ObReferenceObject引用+1

IRP

  • irp的目标是driverObject的成员FileObject,指向各个设备文件
  • startio(设备忙排队等待)和多线程
  • irp状态决定了io状态,同步io、异步io、延迟io,IoCompleteRequest调用IoComplete函数
  • 内存指针MdlAddress 、AssociatedIrp、SystemBuffer
  • IoStartPacket、IoStartNextPacket遍历irp调用startio
  • fastio,文件系统专用
  • 用户层请求通过服务管理器做api映射后,传入io管理器,查询指定设备

工具:https://github.com/MartinDrab/IRPMon/releases/tag/v1.0-rc

注释

  • 静态分析工具使用,提高分析的准确度

参考:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/sal-2-annotations-for-windows-drivers

  • 自旋锁,线程不睡眠高效,占用CPU一般用于代码量较少情况
  • 删除锁,避免处理过程中设备被删除,IoAcquireRemoveLock、IoReleaseRemoveLock释放

内核交互

  • mmap(linux的方式,内核物理内存,应用层虚拟内存,通过共享内存映射内核到文件上(磁盘交互的方式),实现应用层对内核的快速访问),windows可以参考wdm安装包sample中的video,mirror模块disp
  • deviceIoControl
  • createfile、deletefile、openfile、createdc(参考video的mirror示例)

其他

  • CONTAINING_RECORD已知成员地址,求首地址,(&(struct *)0)->member不会报错
  • isr中断服务函数,irql level中断处理级别
  • irql中断最高级别dirql处理中断
  • DISPATCH_LEVEL级别处理dpc队列
  • APC_LEVEL处理回调apc
  • PASSIVE_LEVEL处理driverentry等分发函数
  • umdf的接口IDriverEntry
  • hardware id 标识inf文件
  • 每个线程都有一个APC队列,用户线程在唤醒和睡眠前(可警醒状态未真正睡眠)都会先执行apc队列中的函数
  • 驱动安装setupapi或者cmapi(pnp安装)

WDM

WDM、WDF(WDM基础上架构的开发框架)

  • NT驱动通过服务安装(服务通过sc命令查询)
  • WDM驱动inf、cat、cer文件安装

windows ssdt hook技术

windows有两个ssdt(System Service Description Table)

  • ssdt(kernel.dll)
  • shadow ssdt(user32.dll、gdi32.dll)

InstallSysServiceHook函数在driverentry中替换原有的函数地址
https://www.cnblogs.com/BoyXiao/archive/2011/09/04/2166596.html

linux

  • 设备文件:/dev目录下,设备分为
  • 字符设备,能够像字节流(类似文件)一样被访问的设备
  • 块设备,设备每次只能传输一个或多个完整的块,而每块包含512字节
  • 网络设备
  • driver注册和注销,int driver_register(struct device_driver *drv)
  • bus注册和注销,bus_register(struct bus_type *bus)
  • device注册和注销,int device_register(struct device *dev)

驱动安装

  • 静态加载,把驱动程序直接编译进内核,系统启动后可以直接调用,重新下载(源码下载地址:https://www.kernel.org/)和编译内核,效率较低
  • 动态加载,下载linux内核源码,使用内核工具编译成模块,系统启动后用insmod命令添加模块(.ko),在不需要的时候用rmmod命令卸载模块

linux的三个基本构件是:引导系统(boot loader), linux内核,根文件系统,包含3个基本构件可以生成镜像img文件,busybox可以生成最小文件系统

参考

micosoft:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/kernel/
linux:https://www.cnblogs.com/Bright-Ho/p/5497481.html

第一章概述...........................................................................................................................6 1.1 本教程的规划:...............................................................................................................6 第二章WDM驱动程序的运行.................................................................................................7 2.1 WDM驱动程序的基本调用流程:.....................................................................................7 2.1.1驱动程序何时从何处开始执行?........................................................................7 2.1.1.1第一次安装好驱动程序:................................................................7 2.1.1.2驱动程序正常运行:........................................................................7 2.1.2 DriverEntry()大约做些什么?.........................................................................7 2.1.2.1 IRP主功能码(Major Function Code).......................................9 2.1.2.2 IRP_MJ_PNP次功能码(Minor Function Code).......................10 2.1.2.3 IRP_MJ_POWER次功能码(Minor Function Code)...................10 2.1.3驱动程序与应用程序相关的功能码如何调用?..............................................10 2.1.3.1 DriverEntry()您必须要注册回调函数...................................10 2.1.3.2 在您的应用程序正确调用CreateFile().............................11 2.1.3.3 应用层调用驱动的消息参照:.....................................................11 2.1.3.4 IoControl调用:...........................................................................11 第三章开始编写WDM驱动程序...........................................................................................13 3.1 得到一个Demo工程:.....................................................................................................13 3.2 在VC下配置DDK的开发环境...........................................................................................15 3.2.1 我的目录.............................................................................................15 3.2.1.1我们应该在系统环境变量里设置..................................................15 3.2.2安装VC6................................................................................................17 3.2.3 打开wdm1\sys\Wdm1.dsp工作区文件...............................................18 3.2.4 修改H:\driverDev\MakeDrvr.bat文件...........................................18 3.2.5 设置VC的环境.....................................................................................19 3.2.5.1前面的内容编译时出了错误(配置'MakeDrvr')......................19 3.2.5.1.1 在project -> settings设置成如下:.......................19 3.2.5.1.2 还可以在Tools-> Options-〉directories选择“Executable files”并添加MakeDrvr.bat的目录即可.................20 3.2.5.1.3 再按F7编译 有编译提示..................................................20 3.2.5.1.4 搞清楚 MakeDrvr.BAT文件的功能...................................21 3.2.5.2前面的内容编译时出了错误,让我们看看是什么原因..............22 第四章 安装DebugPrintMonitor驱动程序.................................................................................24 4.1 用控制面板安装DebugPrintMonitor...........................................................................24 4.2 检查DebugPrint driver的安装情况...........................................................................29 第五章 安装wdm1驱动程序..........................................................................................................30 5.1 INF 文件.........................................................................................................................30 5.1 全新安装驱动.................................................................................................................30 5.1.1 安装驱动WDM1.SYS.............................................................................................30 5.2 测试DebugPrintMonitor...............................................................................................30 第六章 执行应用程序...................................................................................................................32 6.1 打开Wdm1Test.dsp.........................................................................................................32 6.2 编译Wdm1Test 工程.......................................................................................................32 6.3 修改Wdm1Test .CPP文件的setupapi.h的路径...........................................................33 6.3 重新指定Wdm1Test 工程的setupapi.lib的路径.......................................................35 6.4 类型DWORD_PTR和ULONG_PTR没定义的错误.................................................................36 6.4 调试WdmTest工程...........................................................................................................37 6.4.1 设置断点.............................................................................................................37 6.4.2 单步执行.............................................................................................................38 6.4.3 SYS目录下驱动程序代码对照:.......................................................................40 6.4.4 EXE继续往下执行ReadFile/WriteFile.......................................................40 6.4.4.1 执行ReadFile的情况.............................................................................40 6.4.4.2 执行WriteFile的情况...........................................................................42 6.4.5其他的请自己执行..............................................................................................43 第七章 启用wdm1驱动程序..........................................................................................................44 第八章 停用wdm1驱动程序..........................................................................................................45 8.1 点击“我的电脑” –〉“属性” –〉“硬件”.........................................................45 8.2 点击 “设备管理器”并展开其他设备.......................................................................45 第九章还有更好的DebugView.exe.............................................................................................47 9.1得到DebugView.exe.........................................................................................................47 9.2 原理..................................................................................................................................48 9.2.1 DBG.......................................................................................................................48 9.2.2 DbgPrint().........................................................................................................48 9.2.3 如何使用DbgPrint()........................................................................................48 9.2.4 修改wdm1工程的例子........................................................................................48 9.3 如何使用DebugView.......................................................................................................48
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪力左手

囧rz

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值