7.Windows驱动-驱动lrp通信

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

上一个内容:6.Windows驱动-驱动对象卸载相关

Irp通信写它是个什么东西,不好写,直接看效果,首先在之前的MyCreate函数中写下图红框的代码

代码说明:

c 复制代码
// ###########################################################################
// 函数名称:MyCreate
// 函数作用:内核驱动的"请求处理函数",专门处理用户态程序发来的两种请求:
//           1. 打开设备(对应3环 CreateFile 函数调用)
//           2. 关闭设备(对应3环 CloseHandle 函数调用)
// 简单说:这是驱动和用户态程序沟通的"桥梁",用户态操作设备时,内核就调用这个函数
// ###########################################################################
// 参数说明(小白版):
// _In_ struct _DEVICE_OBJECT* DeviceObject:
//   驱动创建的"设备对象"指针,相当于驱动在核内的"实体",用户态操作的就是这个设备
// _Inout_ struct _IRP* Irp:
//   核心参数!相当于"请求包裹",里面装着用户态程序的请求信息(比如是要打开还是关闭设备)
//   _Inout_ 表示:既要读里面的请求(In),也要写处理结果(Out)
// ###########################################################################
NTSTATUS
MyCreate(
	_In_ struct _DEVICE_OBJECT* DeviceObject,
	_Inout_ struct _IRP* Irp
) {

	// #######################################################################
	// 1. 拿到"请求包裹"里的"详情单"
	// IoGetCurrentIrpStackLocation(Irp):内核API,作用是从"Irp请求包裹"里
	// 取出当前的"请求详情单"(PIO_STACK_LOCATION),简称isl
	// 详情单里藏着关键信息:用户态到底发的是"打开"还是"关闭"请求
	// #######################################################################
	PIO_STACK_LOCATION isl = IoGetCurrentIrpStackLocation(Irp);

	// #######################################################################
	// 2. 根据"详情单"判断请求类型,分支处理
	// switch (isl->MajorFunction):判断请求的"大类型"
	// isl->MajorFunction 就是详情单上的"请求类型编号",内核预定义了固定编号(宏)
	// #######################################################################
	switch (isl->MajorFunction) {
		// case 1:请求类型是"打开设备"(IRP_MJ_CREATE 是内核预定义的"打开设备"编号)
		// 触发时机:用户态调用 CreateFile(驱动符号, ...) 时,内核会触发这个分支
		case IRP_MJ_CREATE: {
			// 调试打印日志:告诉我们"打开设备"的请求被驱动收到了(WinDbg里能看到)
			DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "IRP_MJ_CREATE\n");
			break; // 处理完这个请求,跳出分支
		}
		//  case 2:请求类型是"关闭设备"(IRP_MJ_CLOSE 是内核预定义的"关闭设备"编号)
		// 触发时机:用户态调用 CloseHandle(设备句柄) 时,内核会触发这个分支
		case IRP_MJ_CLOSE: {
			// 调试打印日志:告诉我们"关闭设备"的请求被驱动收到了(WinDbg里能看到)
			DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "IRP_MJ_CLOSE\n");
			break; // 处理完这个请求,跳出分支
		}
		// default:其他未处理的请求类型(比如读/写设备),这里暂时不处理
		default: {
			break;
		}
	}

	// #######################################################################
	// 3. 告诉系统"请求处理完了,处理成功"(核心步骤!不能少,少了会蓝屏)
	// #######################################################################
	// Irp->IoStatus.Status:给"请求包裹"设置处理结果,STATUS_SUCCESS 表示"处理成功"
	// 系统会把这个结果返回给用户态程序(比如CreateFile返回的句柄是否有效,就看这个)
	Irp->IoStatus.Status = STATUS_SUCCESS;

	// Irp->IoStatus.Information:设置"本次请求传输的数据长度"
	// 打开/关闭设备不需要传输数据,这里设为4也可以(设为0也没问题,不影响功能)
	Irp->IoStatus.Information = 4;

	// IoCompleteRequest:内核API,作用是"通知系统:这个请求我处理完了,你可以回收资源了"
	// IO_NO_INCREMENT:表示不提升系统优先级(小白不用管,照写就行)
	// 重点:必须调用这个函数,不然系统会一直等请求完成,最后蓝屏!
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	// 返回处理结果:和上面的 Irp->IoStatus.Status 保持一致,告诉系统处理成功
	return STATUS_SUCCESS;
}

// ###########################################################################
// 小白必看补充说明(关键!)
// ###########################################################################
// 1. 为什么这个函数叫 MyCreate,却能处理"关闭设备"(IRP_MJ_CLOSE)?
//    → 因为后面会在 DriverEntry 里给"关闭设备"请求(IRP_MJ_CLOSE)
//      绑定这个函数(就像给"关闭请求"配个专属处理器),所以能通过 switch 区分两种请求
//
// 2. 为什么必须写 Irp->IoStatus 和 IoCompleteRequest?
//    → 内核是"严谨的管家",收到请求后必须得到"处理结果+完成通知"
//      少写会导致系统一直等,最后卡死甚至蓝屏(相当于快递寄到了不签收,管家一直等)
//
// 3. 怎么触发这两个分支?
//    → 3环程序调用 CreateFile(三环符号, ...) → 驱动触发 IRP_MJ_CREATE 分支
//    → 3环程序调用 CloseHandle(设备句柄) → 驱动触发 IRP_MJ_CLOSE 分支
//
// 4. 日志在哪里看?
//    → 用 WinDbg 连接虚拟机/物理机,执行命令 !dbgprint 就能看到打印的日志
// ###########################################################################

然后重新生成

点击获取驱动后

点击关闭驱动按钮时,打印IRP_MJ_CLOSE,这就是Irp通信


相关推荐
hszmoran1 个月前
电脑关机重启时显示rundll32 内存不能为read解决方法
电脑·nvidia·驱动
sheepwjl2 个月前
《嵌入式驱动(二):驱动开发基本概念》
arm开发·驱动开发·单片机·嵌入式硬件·imx6ull·驱动·裸机
肖爱Kun3 个月前
LINUX中USB驱动架构—URB请求块
linux·驱动
肖爱Kun3 个月前
LINUX中USB驱动架构—设备驱动
linux·驱动
肖爱Kun3 个月前
SPI设备驱动
驱动
驱动探索者4 个月前
USB ADB 简介
linux·adb·驱动·usb
Meraki.Zhang5 个月前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
Suagrhaha5 个月前
驱动入门的进一步深入
linux·嵌入式硬件·驱动