WinX86内核02-驱动程序
把昨天的程序改用 c++ 编译,改成 .cpp ,发现编译报错
原因是名称粉碎,因此可以直接 extern “C”声明一下这个函数 或者用 头文件(推荐)
因为 在头文件中 可以把 头文件一起包含进去
#pragma once extern "C" { #include <Ntddk.h> /*驱动入口函数*/ NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT* DriverObject, __in PUNICODE_STRING RegistryPath); /*驱动卸载函数*/ VOID Unload(__in struct _DRIVER_OBJECT* DriverObject); }
api
在驱动编程里面也可以面向对象编程,可以用class ,但是有很多功能是禁止的 ,例如 try catch 这是3环的机制,内核处理的方法不一样, malloc , printf ,scanf,new 等 基本的库函数 和 3环 的 api都不行 因为 内核有一套独立的内核空间,必须用微软提供的独立的内核api去申请 .操作系统会提供一套独立的 内核专用的 内核 api
Reference 里面就是所有的api
WDM(NT)驱动框架
我们前面写的算一个一个驱动程序 (有打印功能),但不具备交互性,即不能跟驱动沟通
那么怎么让驱动具备交互性呢(跟3环程序作交互)
内核驱动一般不做界面功能,有3环程序来做,因为内核不能中出bug
因此 内核驱动开发有一个原则,驱动里面3环能解决的问题就在3环解决,驱动里面只做内核才能做的事
- 1.
想要跟3环做交互,那就要按操作系统的设计来做这个框架
- 2.
如果不需要跟3环程序交互,可能不需要 按 操作系统的设计来
- 3.
卸载函数必须有,不然装上了就无法卸载 (因为有些驱动可能是系统一定要用的,防止被误卸载了)如果是开机启动,重启也无法卸载,除非进安全模式
步骤
- 1.
实现驱动入口函数 DriverEntry
- 2.
创建设备
- 3.
注册派函数
- 4.
注册卸载函数 Unload
系统 =》 驱动接口 =》 硬件
因为将来的硬件我们也知道有什么,所以驱动接口必须支持现在的硬件,还要支持将来的硬件,因此驱动接口的设计就十分重要,必须抽象
驱动接口 => 抽象 =》 硬件共同的特点 => 文件
应用程序 =》 文件API => 系统 => 驱动操作接口(open read write close) Dispatch Routines =》 硬件
写驱动就是想操作系统提供 open read write close 的接口,就是文件指针,这些函数就是派遣函数
设备对象 DEVICE_OBJECT 存放 open read write close 的接口
绑定
驱动对象 DRIVER_OBJECT 虚拟出来的,当操作系统加载驱动的时候,就会创建一个驱动对象来描述加载的驱动的所有信息 DriverObject
3环程序只需要 操作设备对象 ,设备对象自然会跟驱动对象绑定
实现
实现驱动入口函数 DriverEntry
/*驱动入口函数*/ NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT* DriverObject, __in PUNICODE_STRING RegistryPath) { return STATUS_SUCCESS; }
添加设备
操作系统会提供内核API 实现王操作系统添加一个设备
ms-help://MS.WDK.v10.7600.091201/Kernel_r/hh/Kernel_r/k104_1e38a631-7e65-4b4b-8d51-3150a8073511.xml.htm
最常用的就是 IoCreateDevice
参数:
- 1.
驱动对象 (一个驱动可以创建多个设备对象,他就会挂链表)
- 2.
设备口拓展大小 (驱动对象结构体有一个空指针成员,可以用来存放用户申请的地址,对结构体进行拓展,用来取代全局变量),一般定义一个结构体,也可以不用
- 3.
设备名字 (在内核中基本不用 3环的字符串格式char* 即不是'\0'结尾的字符串,而是用 UNICODE_STRING 结构体),名字有要求 前面必须要有 \Device\ 。而且必须唯一,不可以与其他设备相同
- 4.
设备种类,不能为NULL
- 5.
是否独占 一般是false true表示独占:该软件使用时,其他软件无法使用
- 6.
返回的设备对象
不用char* 是因容易字符串一处造成漏洞
内核中有些库函数还是可以用的 如: strlen strcpy但不推荐,因为不是 "\0" 结尾
windows整个操作系统是由C语言 + 汇编写的,但他整个设计用的是面向对象的思想的
内核里面基本返回值统一,这样调 api 可以统一检查 ,通过宏 NT_SUCCESS 检查
驱动卸载下次在安装将创建不了,因为名称被占用了,因此需要在upload 中 删除对象设备
#define DEVICE_NAME L"\\Device\\CR42" UNICODE_STRING ustrDevName; //ustrDevName.Length = 8; //ustrDevName.MaximumLength = 10; //ustrDevName.Buffer = L"CR42"; RtlInitUnicodeString(&ustrDevName, DEVICE_NAME); //该函数就是实现上面3 行代码 PDEVICE_OBJECT pDevObj = NULL; NTSTATUS Status = IoCreateDevice(DriverObject, sizeof(MyDeviceExt), &ustrDevName, FILE_DEVICE_UNKNOWN, //不知道的设备类型 FILE_DEVICE_SECURE_OPEN, FALSE, //独占 &pDevObj); if (!NT_SUCCESS(Status)) { //检查错误 DbgPrint("[51asm] IoCreateDevice Status:%p\n", Status); return Status; //失败返回 状态码 }
注册派遣函数
驱动对象最后一项是一个函数指针数组,我们驱动有什么功能就填什么功能,而且通过宏说明了每个下标分别放什么功能
一般对一内核驱动来说 必须提供 打开 关闭 控制 3个功能
这些函数就是派遣函数,也可以称回调函数
NTSTATUS DispatchCreate( _In_ struct _DEVICE_OBJECT* DeviceObject, _Inout_ struct _IRP* Irp ); NTSTATUS DispatchClose( _In_ struct _DEVICE_OBJECT* DeviceObject, _Inout_ struct _IRP* Irp ); NTSTATUS DispatchRead( _In_ struct _DEVICE_OBJECT* DeviceObject, _Inout_ struct _IRP* Ir
相关文章:

WinX86内核02-驱动程序
把昨天的程序改用 c++ 编译,改成 .cpp ,发现编译报错 原因是名称粉碎,因此可以直接 extern “C”声明一下这个函数 或者用 头文件(推荐) 因为 在头文件中 可以把 头文件一起包含进去 #pragma once extern "C" { #include <Ntddk.h> /*驱动入口函…...

基于SpringBoot+Vue的体育馆场地预约系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【WebGIS】Cesium:天地图加载
天地图是中国国家基础地理信息系统,由中国测绘地理信息局和国家地理信息公共服务平台共同开发和运营。它提供多项地理信息服务,包括地图数据、地理编码、路径规划以及地理搜索等。天地图的目标是为各行业提供高质量、全面的地理信息数据和解决方案。 天…...

[产品管理-46]:产品组合管理中的项目平衡与管道平衡的区别
目录 一、项目平衡 1.1 概述 1.2 项目的类型 1、根据创新程度和开发方式分类 2、根据产品开发和市场周期分类 3、根据风险程度分类 4、根据市场特征分类 5、根据产品生命周期分类 1.3 产品类型的其他分类 1、按物理形态分类 2、按功能或用途分类 3、按技术或创新程…...

【MySQL】MySQL的简单了解详解SQL分类数据库的操纵方法
一、mysql定义 mysql是数据库服务的客户端,mysqld是数据库服务的服务器端。mysql的本质就是基于CS模式下的一种网络服务。数据库一般指的是在磁盘中或内存中存储的特定结构组织的数据,将来就是在磁盘上存储的一套数据库方案。 创建数据库,本质…...

【Python爬虫实战】正则:从基础字符匹配到复杂文本处理的全面指南
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、正则表达式 (一)正则表达式的基本作用 …...
10.18Python基础迭代器生成器_函数式编程
Python迭代器与生成器 1. 迭代器 Iterator 什么是迭代器 迭代器是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器可以重复使用,而不会像列表那样在迭代时被修改。 迭代器函数iter和next 函数说明iter(iterable)从可迭代对象中返回一个迭…...
HttpPost 类(构建 HTTP POST 请求)
HttpPost 类是 Apache HttpClient 库中的一个类,用于构建 HTTP POST 请求。以下是 HttpPost 类的一些常用方法和代码案例: 常用方法 构造方法: HttpPost(String uri):创建一个 HttpPost 对象,并将请求的 URI 作为参数…...

xtu oj 原根
文章目录 回顾杂思路c 语言代码 回顾 AB III问题 H: 三角数问题 G: 3个数等式 数组下标查询,降低时间复杂度1405 问题 E: 世界杯xtu 数码串xtu oj 神经网络xtu oj 1167 逆序数(大数据) 杂 有一些题可能是往年的程设的题,现在搬到…...

Java Spring 中常用的 @PostConstruct 注解使用总结
引言 在最近的学习中,我发现了一个非常实用的注解 —— PostConstruct。通过深入学习,逐步发现这个注解在实际开发中可以帮助我们更轻松地解决不少原本复杂的问题,特别是在项目启动时自动执行一些必要的初始化操作。相比于手动调用ÿ…...

Visual Studio--VS安装配置使用教程
Visual Studio Visual Studio 是一款功能强大的开发人员工具,可用于在一个位置完成整个开发周期。 它是一种全面的集成开发环境 (IDE)。对新手特别友好,使用方便,不需要复杂的去配置环境。用它学习很方便。 Studio安装教程 Visual Studio官…...
什么叫CMS?如何使用CMS来制作网站?
CMS是什么? 内容管理系统(Content Management System,CMS),是一种位于WEB前端(Web 服务器)和后端办公系统或流程(内容创作、编辑)之间的软件系统。内容的创作人员、编辑人…...
如何获取谷歌浏览器窗口句柄并将其设置为Qt的父窗口
1、首先,确保你在项目的 .pro 文件中加入对WinAPI的支持: win32: LIBS -luser322、步骤概述: 使用WinAPI获取谷歌浏览器窗口的句柄。获取Qt窗口的句柄。使用SetParent函数,将Qt窗口设置为谷歌浏览器窗口的子窗口。调整Qt窗口的…...
牛客小白月赛102:最短?路径(分层bfs)
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 给定一个 nnn 个点 mmm 条边的无向图,LH 打算从点 111 出发去点 nnn。 假如 LH 到达了一个点 iii,那么他可以选择在这个点花费 aia_iai 的时间休息后继续赶…...
JSON字符串转成java的Map对象
要将这个JSON字符串转换成Java对象,你可以定义一个Element类来表示每个要素,然后使用一个Map来存储这些要素。以下是具体的实现步骤: 步骤 1: 定义 Element 类 首先,定义一个Element类来表示每个要素的结构: public…...
重读《人月神话》(8)-为什么巴比伦塔会失败?(Why Did the Tower of Babel Fail?)
据《创世纪》记载,巴比伦塔是人类继诺亚方舟之后的第二大工程壮举,但巴比伦塔同时也是第一个彻底失败的工程。 巴比伦塔的管理教训 这个项目具备了几乎所有成功的先决条件: 有清晰的目标,尽管目标理想化到了近乎不可实现的地步&…...

STL源码剖析:Hashtable
hashtable 概述 哈希表是一种数据结构,它提供了快速的数据插入、删除和查找功能。它通过使用哈希函数将键(key)映射到表中的一个位置来实现这一点,这个位置称为哈希值或索引。哈希表使得这些操作的平均时间复杂度为常数时间&…...

spring-boot学习(2)
上次学习截止到拦截器 1.构建RESfun服务 PathVariable通过url路径获取url传递过来的信息 2.MyBatisPlus 第三行的mydb要改为自己的数据库名 第四,五行的账号密码改成自己的 MaooerScan告诉项目自己的这个MyBatisPlus是使用在哪里的,包名 实体类的定义…...

《案例》—— OpenCV 实现2B铅笔填涂的答题卡答案识别
文章目录 一、案例介绍二、代码解析 一、案例介绍 下面是一张使用2B铅笔填涂选项后的答题卡 使用OpenCV 中的各种方法进行真确答案识别,最终将正确填涂的答案用绿色圈出,错误的答案不圈出,用红色圈出错误题目的正确答案最终统计正确的题目数…...

新员工入职流程指南_完整入职流程解析
文章介绍了新员工入职流程的重要性、步骤及持续时间,并推荐ZohoPeople软件自动化管理入职流程,提升新员工入职体验,减少离职率,确保合规性,提升公司品牌形象。 一、新员工入职流程是怎样的? 入职流程是指一…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...