免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
上一个内容: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通信

