Windows内核-7-(IRP)I/O请求包

IRP(I/O Request Packet)就是一个进行I/O操作的请求包。

IRP是一个结构体,谁分配谁就得释放,通常由执行体里的管理器,获取内核驱动程序来分配。

IRP不是单独的,只要创建了IRP就会跟着创建IRP的I/O栈,有一个栈是给内核驱动用的:

驱动需要调用IoGetCurrentIrpStackLocation函数来获取内驱驱动对应的I/O栈。

I/O传递

I/O系统是以设备对象为中心,而不是以驱动对象为中心的。IRP可以在设备对象中传来传去:

有点类似于计算机网络的体系结构。但是不可否认的是I/O可以在设备直接进行各种传递,所以通常用来作为读取文本数据。

具体的传递过程有点类似于栈。

IRP和I/O栈

这张图是对前面第一张图的细化。

分发例程(dispatch routine)

IRP最主要的一个作用就是拿来做分发例程,其实也就是分发的实例函数,就是对文件数据的传递。在我的理解里,就是对信息的分发,让大家一起用到数据。

所有的分发例程都有一个原型:

typedef NTSTATUS DRIVER_DISPATCH (
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp);

分发例程必须保存在驱动对象的MajorFunction里面,且需要对应和驱动的连接状态:

状态 描述
IRP_MJ_CREATE 获取文件句柄,对应User下的CreateFile
IRP_MJ_CLOSE 关闭文件句柄,对应User下的CloseHandle
IRP_MJ_READ 对应ReadFile
IRP_MJ_WRITE 对应WriteFile
IRP_MJ_DEVICE_CONTROL 对应DeviceIoControl,即可读又可写
IRP_MJ_INTERNAL_DEVICE_CONTROL 和IRP_MJ_DEVICE_CONTROL差不多,但是只有Kernel可用

完成请求

一旦决定要处理IRP(意味着不会把该IRP传递给下一个设备对象),就必须要完成它。

比如:

NTSTATUS MyDispatchRoutine(PDEVICE_OBJECT, PIRP Irp) {
//...
Irp->IoStatus.Status = STATUS_XXX;
Irp->IoStatus.Information = NumberOfBytesTransfered; // depends on request type
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_XXX;
}
//这里的IoCompleteRequest就是必须的

安全IRP操作

由于线程原因,很有可能一个去读一个去写,导致两个只有一个拿到了想要的数据。

还有页面内存的原因,修改的时候有可能一起修改了。

内核提供了两种比较安全的处理方式:

1 缓冲I/O

2 直接I/O

缓冲I/O

要使用缓冲I/O只需要在设备对象的Flag字段里面添加一个DO_BUFFERED_IO

DeviceObject->Flags |= DO_BUFFERED_IO

缓冲I/O的原理就是在系统内存中开辟一段缓冲区,作为一个中间人。

比如说要写,就先把内容写到系统内存缓冲区里,然后系统内存缓冲区再写入/读取到缓冲区里面。

直接I/O

直接缓冲采用物理内存映射来处理,将User和Kernel的缓冲区都指向物理内存里面,并且锁定在内存里,然后读写都采用它。这样的好处是减少了调用的开销。但是占了部分内存。

IRP_MJ_DEVICE_CONTROL 调度

前面的缓冲和直接I/O是读或写操作,这里的IRP_MJ_DEVICE_CONTROL操作是基于控制代码来选择读或写两个都可以的。

User态的IRP_MJ_DEVICE_CONTROL 和Kernel态的调用函数原型差不多:

BOOL DeviceIoControl(
HANDLE       hDevice,
DWORD       dwIoControlCode,
LPVOID       lpInBuffer,
DWORD       nInBufferSize,
LPVOID       lpOutBuffer,
DWORD       nOutBufferSize,
LPDWORD     lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

dwIoControlCode:控制代码,由CTL_CODE宏的四个参数来处理。

Zero驱动程序

Client+Kernel的一个练手项目:

对于读请求,会将提供的缓冲区清零然后输出

对于写请求,会把缓冲区消耗掉

源代码zodiacon/windowskernelprogrammingbook: The Windows Kernel Programming book samples (github.com)

Windows内核-7-(IRP)I/O请求包的更多相关文章

  1. 《天书夜读:从汇编语言到windows内核编程》六 驱动、设备、与请求

    1)跳入到基础篇的内核编程第7章,驱动入口函数DriverEnter的返回值决定驱动程序是否加载成功,当打算反汇编阅读驱动内核程序时,可寻找该位置. 2)DRIVER_OBJECT下的派遣函数(分发函 ...

  2. Windows环境中,通过Charles工具,抓取安卓手机、苹果手机中APP应用的http、https请求包信息

    Windows环境中,通过Charles工具,抓取安卓手机.苹果手机中APP应用的http.https请求包信息1.抓取安卓手机中APP应用的http请求包信息1)在电脑上操作,查看Windows机器 ...

  3. windows内核驱动内存管理之Lookaside使用

    Windows内存管理中使用了类似于容器的东西,叫做Lookaside对象,每次程序员申请内存都会从Lookaside里面申请,只有不足的时候,Lookaside才会向内存又一次申请内存空间,这样减少 ...

  4. [14]Windows内核情景分析 --- 文件系统

    文件系统 一台机器上可以安装很多物理介质来存放资料(如磁盘.光盘.软盘.U盘等).各种物理介质千差万别,都配备有各自的驱动程序,为了统一地访问这些物理介质,windows设计了文件系统机制.应用程序要 ...

  5. Windows内核原理-同步IO与异步IO

    目录 Windows内核原理-同步IO与异步IO 背景 目的 I/O 同步I/O 异步I/O I/O完成通知 总结 参考文档 Windows内核原理-同步IO与异步IO 背景 在前段时间检查异常连接导 ...

  6. Windows驱动开发-IRP结构体

    IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构. 上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的 ...

  7. Windows内核-7-IRP和派遣函数

    Windows内核-7-IRP和派遣函数 IRP以及派遣函数是Windows中非常重要的概念.IRP 是I/O Request Pocket的简称,意思是I/O操作的请求包,Windows中所有Use ...

  8. 【windwos 操作系统】关键的Windows内核数据结构一览(下)

    I/O管理器 nt!_IRP IRP表示一个I/O请求包结构体,它用来封装执行一个特定I/O操作所需要的所有参数以及I/O操作的状态.IRP的表现也类似于一个线程独立调用栈因此它可以从一个线程传递到另 ...

  9. Windows内核 WDM驱动程序的基本结构和实例

    WDM驱动的基本结构: WDM驱动模型是建立在NT式驱动程序模型基础之上的.对于WDM驱动程序来说,一般都是基于分层的,即完成一个设备的操作,至少要由两个驱动设备共同完成. 1)物理设备对象和功能设备 ...

随机推荐

  1. bugKu变量1

    重点:两个$$,这暗示着第二个$变量的值,作为第一个$的名称. 而且代码审计之后,发现只含有字母. 又暗示在变量中,那么猜想是在全局变量中,而php中全局变量是$GLOBALS.

  2. 6.Java方法

    一.什么是方法 方法:要去做某件事情,而采取的一些解决办法( Java 中的方法是完成某些事情的) System.out.println(); //类(系统类) 对象(标准输出对象) 方法(print ...

  3. python使用笔记003-文件操作(一)

    文件操作分为: 1.打开文件,如果文件在当前目录下直接写文件名,如果文件在其他目录下写绝对路径 2.读/写文件 3.关闭文件 一.文件打开模式 # 'r':只读,文件读取后,会有文件指针记录读取文件的 ...

  4. PYTHON 连接SQL2008 导出到EXCEL

    #import pymssql from datetime import datetime import pyodbc import os current_dir = os.path.abspath( ...

  5. [刘阳Java]_步步窥探JS变量作用域

    今天的这个文章题目名称甚是让人会突发异想.JS变量作用域是务必需要搞懂的,单从面试过程就会让面试者烧脑壳.所以,我们还是写一篇关于JS变量作用域的技术专题,让所有小伙伴能够借此文章去整理JS的基础学习 ...

  6. 一、Java预科学习

    1.1.什么是计算机 计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,可以进行数值计算,又可以进行逻辑计算,还具有存储记忆功能.是能够按照程序运行,自动.高速处理海量数据的现 ...

  7. 数据库连接异常 Caused by: java.sql.SQLException: Unknown system variable 'tx_isolation'

    1.错误截图 2.错误分析 数据库的版本比连接驱动的版本高很多. 3.解决方法 因此将mysql-connector-java升级到最新版本就解决了问题. 原本我的版本是mysql-connector ...

  8. 痞子衡嵌入式:i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计. 痞子衡之前两篇文章 <在SBL项目实战中妙用i ...

  9. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【二】

    HarmonyOS内核开发-信号量开发案例学习记录   一.LiteOS里面的任务管理介绍: 任务状态通常分为以下四种: 就绪(Ready):该任务在就绪列表中,只等待CPU. 运行(Running) ...

  10. ECShop 2.x/3.x SQL注入/任意代码执行漏洞

    poc地址:https://github.com/vulhub/vulhub/blob/master/ecshop/xianzhi-2017-02-82239600/README.zh-cn.md 生 ...