既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果一个驱动需要和应用程序通信,那么首先要生成一个设备对象(DeviceObject),往往称之为控制设备对象。
设备对象是非常重要的元素。设备对象和派遣函数构成了整个内核体系的基本框架。设备对象可以在内核中暴露出来给应用层,应用层可以像操作文件一样操作它。
生成控制设备可以使用函数:IoCreateDevice。
示例代如下:
2.2 控制设备的名字和符号链接
控制设备需要有一个名字,这样它才会被暴露出来,供其他程序打开与之通信。设备的名字可以在调用IoCreateDevice时指定。
此外,应用层是无法直接通过设备的名字来打开对象的,为此必须要建立一个暴露给应用层的符号链接。
生成符号链接的函数是:IoCreateSymbolicLink。
示例代如下:
2.3 控制设备的删除
在驱动中生成了控制设备及其符号链接,那么在驱动卸载时就应该删除它们;否则符号链接就会一直存在。应用程序还可能会尝试打开进行操作。
依次删除符号链接和控制设备即可。
使用函数 IoDeleteSymbolicLink 和 IoDeleteDevice 。
示例代如下:
2.4 分发函数(派遣函数)
分发函数是一组用来处理发送给设备对象的请求的函数。这些函数由内核驱动的开发者编写,以便处理这些请求并返回给Windows。
每个驱动都有一组自己的分发函数。Windows的IO管理器在收到请求时,会根据请求发送的目标,也就是一个设备对象,来调用这个设备对象所从属的驱动对象上对应的分发函数。
不同的分发函数处理不同的请求。
- 打开设备,会触发IRP_MJ_CREATE,
- 关闭设备,会触发IRP_MJ_CLEANUP和IRP_MJ_CLOSE
2.5 请求的处理
在分发函数中处理请求的第一步是获得请求的当前栈空间(Current StackLocation)。
请求的当前栈空间可以用IoGetCurrentIrpStackLocation取得。利用当前栈空间指针来获得主功能号。每种请求都有一个主功能号来说明这是一个什么请求,然后可以根据主功能号做不同的处理。
●打开请求的主功能号是IRP_ MJ_ CREATE。
●关闭请求的主功能号是IRP_ MJ_ CLOSE。
●设备控制请求的主功能号是IRP_MJ_ DEVICE _CONTROL.
3.应用方面编程
3.1 基本的功能需求
前面的内容中介绍了在内核驱动中需要增加的部分。但是到此为止,都没有说明应用和内核之间要进行怎样的通信。
下面将举一个例子实现应用程序与内核通信,访问PCI配置空间、枚举系统内的所有PCI设备。
3.2 在应用程序中打开与关闭设备
在应用程序中打开设备和打开文件没有什么不同,除了路径有点特殊。
打开设备使用API函数 CreateFile。
文件的路径就是符号链接的路径,但是符号链接的路径在应用层看来,是以“.\”开头的。注意,这些“\”在C语言中要使用“\”来转义,所以在C代码中,生成的符号链接就变成了这个样子。 L"\.\HelloDDK"
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新