创建简单的Windows驱动程序并与应用程序通信

2023-11-18

创建简单的Windows驱动程序并与应用程序通信

在本篇博客中,我们将创建一个简单的Windows驱动程序,并实现与用户模式应用程序的通信。我们将展示如何创建驱动程序,处理IRP请求,并在应用程序中使用CreateFileWriteFile函数与驱动程序通信。

驱动程序实现

  1. 首先,定义设备对象名称和符号链接名称。
//设备对象名称
#define DEVICE_NAME L"\\Device\\IRP_tx"
//符号链接名称
#define LINK_NAME L"\\DosDevices\\core_object"
  1. 创建IRP派遣函数DispatchCommdn以处理不同类型的IRP请求。
NTSTATUS DispatchCommdn(PDEVICE_OBJECT pObject, PIRP pIrp) {
    UNREFERENCED_PARAMETER(pObject);
    
    PIO_STACK_LOCATION pStackLocation = IoGetCurrentIrpStackLocation(pIrp);
    ULONG majorFunction = pStackLocation->MajorFunction;
    NTSTATUS status = STATUS_SUCCESS;

    switch (majorFunction) {
        case IRP_MJ_CREATE:
            DbgPrint("IRP_MJ_CREATE");
            // 处理IRP_MJ_CREATE请求
            break;
        case IRP_MJ_CLOSE:
            DbgPrint("IRP_MJ_CLOSE");
            // 处理IRP_MJ_CLOSE请求
            break;
        case IRP_MJ_READ:
            DbgPrint("IRP_MJ_READ");
            // 处理IRP_MJ_READ请求
            break;
        case IRP_MJ_WRITE:
            DbgPrint("IRP_MJ_WRITE");
            // 处理IRP_MJ_WRITE请求
            break;
        default:
            DbgPrint("Unknown major function: %u", majorFunction);
            break;
    }

    // 设置IRP处理成功
    pIrp->IoStatus.Status = status;
    // 设置返回的字节数
    pIrp->IoStatus.Information = 0;
    // 结束IRP处理流程
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    // 返回成功
    return status;
}
  1. DriverUnload函数中删除符号链接和设备对象。
VOID DriverUnload(PDRIVER_OBJECT pDreverObject) {
    UNREFERENCED_PARAMETER(pDreverObject);
    DbgPrint("DriverUnload\r\n");
    //声明符号链接名称
    DECLARE_CONST_UNICODE_STRING(usLinkName, LINK_NAME);
    //删除符号链接
    IoDeleteSymbolicLink(&usLinkName);
    //删除设备对象
    IoDeleteDevice(pDreverObject->DeviceObject);
}
  1. DriverEntry函数中创建设备对象和符号链接,将所有IRP派遣处理函数设置为默认处理函数,并设置DriverUnload函数。
NTSTATUS DriverEntry(PDRIVER_OBJECT pDreverObject, PUNICODE_STRING pRegPath) {
    UNREFERENCED_PARAMETER(pRegPath);
    
    //返回状态
    NTSTATUS ntStatus = 0;
    //声明设备对象名称
    DECLARE_CONST_UNICODE_STRING(usDeviceName, DEVICE_NAME);
    //声明符号链接名称
    DECLARE_CONST_UNICODE_STRING(usLinkName, LINK_NAME);
    //设备对象
    PDEVICE_OBJECT pDeviceObject = NULL;
    //创建设备对象
	ntStatus = IoCreateDevice(pDreverObject, 0, &usDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, 	&pDeviceObject);
	//判断是否创建成功
	if (!NT_SUCCESS(ntStatus)) {
   	 	DbgPrint("IoCreateDevice Failed:%x\r\n",ntStatus);
    	return ntStatus;
	}
	//1.DO_BUFFERED_IO:基于缓存的IO方式
	//2.DO_DIRECT_IO:直接读写的IO方式
	//3.DO_FORCE_NEITHER_IO两者都不的IO方式
	pDeviceObject->Flags |= DO_BUFFERED_IO;//安全
	//创建符号链接
	ntStatus = IoCreateSymbolicLink(&usLinkName, &usDeviceName);
	if (!NT_SUCCESS(ntStatus)) {
    	//删除设备对象
    	IoDeleteDevice(pDeviceObject);
    	DbgPrint("IoCreateSymbolicLink Failed:%x\r\n", ntStatus);
    	return ntStatus;
	}
	/*将所有IRP派遣处理函数,设置默认处理函数*/
	for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++) {
    	pDreverObject->MajorFunction[i] = DispatchCommdn;
	}
	pDreverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

应用程序实现

  1. 定义符号链接名称。
#define LINK_NAME L"\\\\.\\core_object"
  1. 使用CreateFile函数打开符号链接,并使用GENERIC_WRITE访问权限。
HANDLE hDevice = CreateFile(LINK_NAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//判断符号链接是否打开成功
if (hDevice == INVALID_HANDLE_VALUE) {
    printf("ERROR:%d\r\n", GetLastError());
    system("pause");
    return false;
}
  1. 使用WriteFile函数将数据写入驱动程序。
ULONG ullRetWriteLength;
ULONG ullWriteLength = (wcslen(L"Hello World") + 1) * sizeof(wchar_t);
WriteFile(hDevice, L"Hello World", ullWriteLength, &ullRetWriteLength, NULL);
system("pause");

现在,您已经创建了一个简单的Windows驱动程序,并实现了与用户模式应用程序的通信。驱动程序通过处理不同类型的IRP请求来响应应用程序的请求。应用程序可以使用CreateFileWriteFile函数与驱动程序通信。

在本教程中,我们已经展示了如何创建一个简单的Windows驱动程序并与应用程序通信。然而,在开发过程中,您可能会遇到一些问题。这里列举了之前碰到的一些问题以及相应的解决方案,以帮助您更顺利地进行开发。

问题1:IoCreateSymbolicLink错误,返回NTSTATUS错误码:C0000035

在某些情况下,您可能会在卸载驱动程序后再次安装时遇到IoCreateSymbolicLink错误。这是因为在卸载过程中,有时驱动程序无法立即删除符号链接。这会导致符号链接已存在的错误(C0000035)。

解决方案:

确保在DriverUnload函数中正确删除符号链接。在卸载驱动程序时,您可以使用FltUnloadFilter函数确保符号链接被删除。另外,您还可以考虑在DriverEntry函数中使用IoDeleteSymbolicLink来删除符号链接,以防止重复创建错误。

问题2:应用程序无法读取驱动程序信息,返回错误代码5

当您尝试使用CreateFile函数打开符号链接时,可能会遇到访问被拒绝的问题(错误代码5)。这通常是由于访问权限不正确或者驱动程序中的IRP处理程序不完整导致的。

解决方案:

确保在应用程序中使用正确的访问权限(如GENERIC_WRITE)。同时,在驱动程序中,为每个主要功能编写正确的IRP处理程序(如IRP_MJ_CREATEIRP_MJ_CLOSEIRP_MJ_READIRP_MJ_WRITE)。

问题3:驱动程序加载失败,返回错误代码0xC0000428

当您尝试加载驱动程序时,可能会遇到签名问题(错误代码0xC0000428)。这是因为Windows要求驱动程序必须通过微软认证签名。

解决方案:

为了解决此问题,您可以尝试以下方法:

  1. 在测试阶段,禁用驱动程序签名强制要求。在命令提示符下,以管理员身份运行以下命令,然后重新启动计算机:
bcdedit.exe /set nointegritychecks on
  1. 为您的驱动程序获取合适的数字签名。在产品发布阶段,请确保您的驱动程序已经通过了微软的签名认证。

请注意,禁用驱动程序签名强制要求会降低系统的安全性。仅在测试和开发阶段使用此方法,永远不要在生产环境中禁用驱动程序签名检查。

请注意,本教程提供的示例仅供学习和研究目的。在实际项目中使用时,请确保遵循适当的编程和安全实践。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建简单的Windows驱动程序并与应用程序通信 的相关文章

  • 是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

    我正在使用 DirectShow Net 库创建一个过滤器图 该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频 然后 在网页上 我可以使用对象元素在 Windows Media Player 对象中呈现视频源
  • C#.Net 邮件将进入垃圾邮件文件夹

    我正在从 ASP net Web 应用程序发送电子邮件 邮件发送成功 没有失败 但大多数都进入了垃圾邮件文件夹 请帮助我克服垃圾邮件过滤器 我的发送邮件代码 public void SendMail string FromAddress s
  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 混合模型优先和代码优先

    我们使用模型优先方法创建了一个 Web 应用程序 一名新开发人员进入该项目 并使用代码优先方法 使用数据库文件 创建了一个新的自定义模型 这 这是代码第一个数据库上下文 namespace WVITDB DAL public class D
  • 如何停止执行的 Jar 文件

    这感觉像是一个愚蠢的问题 但我似乎无法弄清楚 当我在 Windows 上运行 jar 文件时 它不会出现在任务管理器进程中 我怎样才能终止它 我已经尝试过 TASKKILL 但它对我也不起作用 On Linux ps ef grep jav
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • 保证复制省略是否适用于函数参数?

    如果我理解正确的话 从 C 17 开始 这段代码现在要求不进行任何复制 Foo myfunc void return Foo auto foo myfunc no copy 函数参数也是如此吗 下面的代码中的副本会被优化掉吗 Foo myf
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 如何从 Ant 启动聚合 jetty-server JAR?

    背景 免责声明 I have veryJava 经验很少 我们之前在 Ant 构建期间使用了 Jetty 6 的包装版本来处理按需静态内容 JS CSS 图像 HTML 因此我们可以使用 PhantomJS 针对 HTTP 托管环境运行单元
  • 我们可以通过指针来改变const定义的对象的值吗?

    include
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • 当Model和ViewModel一模一样的时候怎么办?

    我想知道什么是最佳实践 我被告知要始终创建 ViewModel 并且永远不要使用核心模型类将数据传递到视图 这就说得通了 让我把事情分开 但什么是Model 和ViewModel一模一样 我应该重新创建另一个类还是只是使用它 我觉得我应该重
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐

  • 百度安全联盟砸场360的中国互联网安全大会说明啥(现场图)

    360承办的 具有官方背景的2013中国互联网安全大会22日召开 然而突发了 百度安全联盟大闹中国互联网安全大会 事件 据说各种闹场方式如百度安全联盟扩音喇叭 安全套等 传闻中的 百度安全联盟大闹中国互联网安全大会 到底真相如何 确实是安全
  • 【python爬虫】爬取豆瓣电影TOP250数据

    这次以豆瓣电影TOP250网为例编写一个爬虫程序 并将爬取到的数据 排名 电影名和电影海报网址 存入MySQL数据库中 下面是完整代码 Ps 在执行程序前 先在MySQL中创建一个数据库 pachong import pymysql imp
  • 需求:vue定时器随机显示冒泡

    html代码 div class tips div class item item1 div class txt item content div div div js代码 在data中定义indexNum生成随机数 mounted中开启定
  • 初学者如何学好Java,过来人的经验之谈

    多看书 多下载一些java相关的资料 多看多打代码 然后思考总结 书读百遍 其义自现 如果找不到合适的资料 可以上北网论坛找下适合自己的免费视频学习资料 都是一些大神买来共享的本来收费的内容 比如 由简入深绝版Java系列课程 t cn 8
  • 网站分布式技术有哪些?

    分布式软件系统 Distributed Software Systems 是支持 分布式处理的软件系统 是在由 通信网络互联的多处理机体系结构上执行任务的系统 它包括分布式操作系统 分布式程序设计语言及其编译 解释 系统 分布式文件系统和
  • 不要再循环里抛出异常

    今天遇到一个bug 是因为循环中抛出了异常 导致之后的代码都没有执行 所以哇 这种抛出有可能中断程序执行的 运行中异常 不要在循环中抛出 只记录异常就可以了 举个栗子 反面示例 try throw new Exception 我发生异常啦
  • 2019 SIGGRAPH paper

    20190704 Image Science 1 Hyperparameter Optimization in Black box Image Processing using Differentiable Proxies 基于可微代理的黑
  • Linux部署项目

    一 Linux介绍 背景 Java项目通常基于windows系统进行开发 服务器部署则是基于Linux 1 1 Linux系统概述 Linux是一套免费使用 自由传播的类unix操作系统 支持多用户 多任何 支持多线程和多CPU的操作系统
  • idea技巧之同时编辑多行代码

    如何同时编辑多行代码 eclipse好像没有这种功能 有一次看到老师用eclipse写代码 10多行 每一行添加一个单引号 一个一个添加 慢的想死 想起做前端项目使用的 webstone可以同时编辑多行代码 现在看到idea 功能如此强大
  • Window10屏幕亮度无法调节尝试解决方法

    换成win10后突然屏幕亮度调节不了 尝试几种方法 失败方法一 注册表修改 1 首先 请大家在桌面上按下Windows徽标键 R键 打开运行菜单窗口 在窗口中输入 regedit 关键字 按下回车键之后打开注册表编辑器 2 打开注册表编辑器
  • vue中使用高德地图,只加载出地图logo,地图没有加载出来

    在使用vue开发的过程中 需要使用到高德地图 但按照高德地图的官方文档配置后 只显示高德地图的logo 但是始终加载不到地图 如下图所示 解决办法 将全局引用的的mockjs注释掉就可以解决这个冲突问题
  • Elaticsearch安装越南语分词器

    1 目标 实现支持英 德 法 葡萄牙 西班牙 俄 印尼 泰 繁中 简中 日 韩 越南 意大利 阿拉伯 土耳其 乌克兰 荷兰 波兰 19种文字的分词器 2 自带的分词器 英 english 德 german 法 french 葡萄牙 port
  • 用spss进行主成分分析

    此次同样通过一道例题讲解如何运用spss进行对数据的主成分分析 下表是我国2005年第1 2季度各地区城镇居民家庭收支基本情况的统计数据 根据这些数据进行主成分分析 并依据分析结果对地区城镇居民家庭收支情况进行排序和分类 地区 平均每户人口
  • 买《Kotlin从小白到大牛》专题视频课程,送配套纸质图书

    经过一年多时间的呕心沥血 Kotlin立体化图书 Kotlin从小白到大牛 即将与大家见面了 所谓立体化图书包括 电子图书 视频 课件和服务等内容 Kotlin从小白到大牛 纸质图书已经上市 为了答谢广大学员对智捷课堂以及关老师的支持 现购
  • python x=[random.randint(0,100) for i in range(50)]什么意思?列表解析

    如有错误欢迎指正 在写python的时候遇到一个问题 其中一段代码是x random randint 0 100 for i in range 50 这个用法叫 列表解析 这句代码的功能是生成一个具有50个0 100之间的整数 具体可以看下
  • Python:简易的串口收发程序

    Python 简易的串口收发程序 更新历史 20201204 首次发布 最近需要搞一个基于Python的串口程序 要求 能够将字符串形式的十六进制数 例如 12 34 CD EF 转化成对应的二进制数据后发送给一个串口设备 能够从串口设备接
  • ChatGPT做到人人都可以配置思科华为网络设备

    最近有个一个想法 chatgpt能不能帮忙配置网络设备 于是我开始在网上找了个拓扑图 然后我将拓扑图及需求 以prompt的形式发送给chatgpt 然后chatgpt根据我的要求 将所有节点的配置全部输出了出来 真是一个新时代来了 我觉得
  • AIOps 在美团的探索与实践 —— 故障发现篇

    摘要 AIOps 最初的定义是Algorithm IT Operations 是利用运维算法来实现运维的自动化 最终走向无人化运维 随着技术成熟 逐步确定为Artificial Intelligence for IT Operations
  • Java ee学习笔记

    Servlet简介 Servlet技术规范是JavaEE技术规范中的一个重要组成部分 Servlet是一种独立于平台和协议的服务器端的Java应用程序 可以生成动态的Web页面 实际上 Servlet不仅仅是用于返回HTML的页面的 比如
  • 创建简单的Windows驱动程序并与应用程序通信

    创建简单的Windows驱动程序并与应用程序通信 在本篇博客中 我们将创建一个简单的Windows驱动程序 并实现与用户模式应用程序的通信 我们将展示如何创建驱动程序 处理IRP请求 并在应用程序中使用CreateFile和WriteFil