Windows内核-7-(IRP)I/O请求包
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请求包的更多相关文章
- 《天书夜读:从汇编语言到windows内核编程》六 驱动、设备、与请求
1)跳入到基础篇的内核编程第7章,驱动入口函数DriverEnter的返回值决定驱动程序是否加载成功,当打算反汇编阅读驱动内核程序时,可寻找该位置. 2)DRIVER_OBJECT下的派遣函数(分发函 ...
- Windows环境中,通过Charles工具,抓取安卓手机、苹果手机中APP应用的http、https请求包信息
Windows环境中,通过Charles工具,抓取安卓手机.苹果手机中APP应用的http.https请求包信息1.抓取安卓手机中APP应用的http请求包信息1)在电脑上操作,查看Windows机器 ...
- windows内核驱动内存管理之Lookaside使用
Windows内存管理中使用了类似于容器的东西,叫做Lookaside对象,每次程序员申请内存都会从Lookaside里面申请,只有不足的时候,Lookaside才会向内存又一次申请内存空间,这样减少 ...
- [14]Windows内核情景分析 --- 文件系统
文件系统 一台机器上可以安装很多物理介质来存放资料(如磁盘.光盘.软盘.U盘等).各种物理介质千差万别,都配备有各自的驱动程序,为了统一地访问这些物理介质,windows设计了文件系统机制.应用程序要 ...
- Windows内核原理-同步IO与异步IO
目录 Windows内核原理-同步IO与异步IO 背景 目的 I/O 同步I/O 异步I/O I/O完成通知 总结 参考文档 Windows内核原理-同步IO与异步IO 背景 在前段时间检查异常连接导 ...
- Windows驱动开发-IRP结构体
IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构. 上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的 ...
- Windows内核-7-IRP和派遣函数
Windows内核-7-IRP和派遣函数 IRP以及派遣函数是Windows中非常重要的概念.IRP 是I/O Request Pocket的简称,意思是I/O操作的请求包,Windows中所有Use ...
- 【windwos 操作系统】关键的Windows内核数据结构一览(下)
I/O管理器 nt!_IRP IRP表示一个I/O请求包结构体,它用来封装执行一个特定I/O操作所需要的所有参数以及I/O操作的状态.IRP的表现也类似于一个线程独立调用栈因此它可以从一个线程传递到另 ...
- Windows内核 WDM驱动程序的基本结构和实例
WDM驱动的基本结构: WDM驱动模型是建立在NT式驱动程序模型基础之上的.对于WDM驱动程序来说,一般都是基于分层的,即完成一个设备的操作,至少要由两个驱动设备共同完成. 1)物理设备对象和功能设备 ...
随机推荐
- BUU mrctf shit
吐槽:去年没写出的题,现在终于可以上手了,昂哥nb 动调发现直接卡着不动了,怀疑是反调试,果然有好几处反调试 这里选择就不先nop了,先让程序跑起来,然后attach,在输入函数下面下个断点,atta ...
- Centos7 yum安装 MySQL5.7.25
扩展:在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB. 1 下载并安装MySQL官方的 Yum ...
- nmon打开nmon文件出现 运行时错误13类型不匹配问题解决
根据nmon工具安装及nmon analyser的使用 - 空谷幽兰LDD - 博客园 (cnblogs.com)文中,用nmon_analyse去打开监控到的nmon文件,出几个报错. 1 用WPS ...
- git研究详解(官网文档)及总结
前言:git作为新一代的版本控制软件,说实话比svn好用多了,个人见解,关于git的详细介绍及研究,我推荐三个地方 1.git官网上的文档(推荐UC浏览器,比火狐多个英文翻译的功能) 地址为:http ...
- Qt5双缓冲机制与实例
1. 双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上. 在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时会产生闪烁的现象, ...
- python 构造函数 析构函数
#构造函数是在对象被创建是自动调用的方法,用来完成初始化操作class Test(object): def __init__(self, name): self.name = name print(' ...
- 替代Infinity绝佳的自主开发chrome插件
最近闲来无事在好朋(da)友(shen)的帮助下开发一个chrome插件,目的是为了替换infinity主页插件, 当然在此也推荐一波infinity确实不错,界面和易用性都是非常好用的水准了. 主页 ...
- python基础之面向对象OOP
#类(面向对象) PageObject设计模式 unittest 知识体系#函数式编程import datetimebook_info = { "title":"Pyth ...
- Beam Search快速理解及代码解析(上)
Beam Search 简单介绍一下在文本生成任务中常用的解码策略Beam Search(集束搜索). 生成式任务相比普通的分类.tagging等NLP任务会复杂不少.在生成的时候,模型的输出是一个时 ...
- [考试总结]noip模拟9
因为某些原因,咕掉了一段时间 所以现在才更新 T1 斐波那契 一看就是规律 然而我选择了暴力 其实完全可以打表去找规律. 然后就可以发现父亲的顺序也是斐波那契. 就这 #include<bits ...