ring0与ring3通信方式
修改自: https://blog.csdn.net/wzsy/article/details/54929726
控制码方式详解: https://www.cnblogs.com/lsh123/p/7354573.html
0、应用程序与驱动程序通信方式据我所知,细分可以分4种,ReadFile,WirteFile方式的缓冲区设备读写,直接方式读写,和其他方式读写,Io设备控制操作.
1、缓冲区方式设备读写:
在创建Device后,须要指定方式为Device的Flags有 DO_BUFFERED_IO!通过应用层Api函数ReadFile,WriteFile,等函数,ntoskrnl.exe创建Irp 后,ReadFile和WriteFile参数的缓冲区就在irp->AssociatedIrp.Systembuffer,同时要求读写的偏移量,和长度都在PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp) 数据类型中的 stack->Parameters.Read.Length,stack->Parameters.Read.ByteOffset(该类型为Large_Interge类型),
2、直接方式读写
在创建Device后,须要指定方式为Device的Flags有 DO_DIRECT_IO!通过应用层APi函数ReadFile,WriteFile等函数,ntoskrnl.exe创建的Irp 后,ReadFile和WriteFile参数的缓冲区将被锁住,然后操作系统将这段缓冲区在内核模式地址再次映射一遍,这样应用层的缓冲区和内存层的就指向同一个物理内存!而内核模式用MDL数据结构记录这段内存,这个虚拟内存大小在 MmGetByteCount(pIrp->MdlAddress),首地址在 MmGetMdlVirtualAddress(pIrp->MdlAddress);偏移量为 MmGetMdlByteOffset(pIrp->MdlAddress)(这里的偏移量不是文件读写的偏移量,而是在MDL中的偏移量)然后文件的长度还是stack->Parameters.Read.Length,这个值和 MmGetByteCount(pIrp->MdlAddress)是一样的,要不然就出错了,而真正的读写偏移量还是在 stack->Parameters.Read.ByteOffset!这里无论是读还是写,都要得到MDL在内核模式下的映射,因此还要用 MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority)将其转化为内核模式,然后可以读写该地址,就会转化到应用层相应的内存!!
补充一点, pIrp->MdlAddress存储的就是用户态下的相关信息, MmGetMdlVirtualAddress 返回的就是用户模式下的虚拟内存地址, 驱动不能直接使用用户态下的地址, 要使用的话需要调用 MmGetSystemAddressForMdlSafe获取函数的返回地址
3、其他方式读写
这种方式很少用到,在创建Device后,Flags既不标志 DO_BUFFERED_IO也不标志DO_DIRECT_IO,ReadFile和WriteFile提供的缓冲区内存地址,可以再IRP的 pIrp->UserBuffer字段得到,而长度和偏移量还是在stack->Paameters.Read中,但是用这种方法须要注意的是ReadFile可能把空指针地址或者非法地址传递给驱动程序,因此驱动程序使用用户模式地址钱须要检查是否可读或者可写,可以用 ProbeForWrite或者ProbeForWrite函数和try模块。
4、Io设备控制方式(IOCTL)
这种通信方式是一种更灵活的通信方式, IRP类型是IRP_MJ_DEVICE_CONTROL, , 这个是作为以上3种数据传输方式的补充, 因为这种方式既可以跟前三种组合使用, 也可以提供其他的控制方式. 我们可以通过定义控制码的方式来提供ring3控制ring0的接口, 每一种接口通过控制码来标识, 如果不需要传输数据, 仅用一个控制码足够了, 如果还需要传输数据, 则需要与上面提到的3种基本通信方式进行组合使用.
ring0与ring3通信方式的更多相关文章
- ring0和ring3的区别
现在探讨内核程序和应用程序之间的本质区别.除了能用WDK编写内核程序和阅读一部分Windows的内核代码之外,我们还需要了解它们的本质是什么,它们和我们熟悉的应用程序有什么区别. Intel的x86处 ...
- RING0到RING3
在前一篇文章里面,我们将了CPU保护模式中的几种特权RING0,RING1,RING2,RING3!操作系统通常运行在RING0,应用程序通常运行在RING3. CPU如何从RING0到RING3 先 ...
- ring0 与 ring3 层之间的交互
在进行Windows的ring0层开发时,必不可免的要与 ring3 层进行交互.进行数据间的相互传输.可用的方法有DeviceIoCntrol,ReadFile.我平常都是用的DeviceIoCon ...
- 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
[0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...
- Ring3 和Ring0 解释
这得从CPU指令系统(用于控制CPU完成各种功能的命令)的特权级别说起.在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃.比如:清内存.设置时钟等.如果所有的程序都能使用这些 ...
- RING0,RING1,RING2,RING3
Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3.Windows只使用其中的两个级别RING0和RING3,RING0只给操作系统用,RING3谁都能用.如果普 ...
- Ring0创建事件Ring3设置事件
同步事件(synchronizationEvent)当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则自动变回未激发态通知事件(NotificationEvent)当事件对象为激发 ...
- Ring3创建事件Ring0设置事件
应用程序中创建的事件和在内核中创建的事件对象,本质上是同一个东西,在用户模式中,他用句柄表示,在内核模式下,他用KEVENT表示数据结构表示.在应用程序中,所有的内核对象都不会被用户看到,用户看到的知 ...
- 全虚拟化和半虚拟化的区别 cpu的ring0~ring3又是什么概念?
ring0是指CPU的运行级别,ring0是最高级别,ring1次之,ring2更次之-- 拿Linux+x86来说, 操作系统(内核)的代码运行在最高运行级别ring0上,可以使用特权指令,控制中断 ...
随机推荐
- 神州数码DEIGRP路由协议配置
实验要求:了解DEIGRP及其配置方法 拓扑如下 R1 enable 进入特权模式 config 进入全局模式 hostname R1 修改名称 interface l0 进入端口 ip addres ...
- Spring Boot的第一个程序
Spring boot是由Pivotal团队提供的全新框架,在设计之初,其目的是为了简化Spring应用的创建.运行.测试.调试.部署的过程.Spring Boot框架不仅简化了Spring的搭建过程 ...
- linux btrfs文件系统管理与应用
btrfs文件系统管理与应用 1.btrfs文件系统 基本介绍 btrfs文件系统在CentOS7.x上属于技术预览版 btrfs文件系统英文名:B-tree FileSystem或者Butter ...
- JavaScript权威指南--数组Array
什么是数组 数组是值的有序集合.每一个值叫做元素,每一个元素在数组中有一个位置,用数字表示,称为索引.js数组是无类型的.动态的,也可能是稀疏的.每个数组都有length属性.数组最大能容纳42949 ...
- register form code(2nd week blog)
register form code(2nd week blog) 注册 用户名: 密码: 确认密码: 邮箱: 电话: 性别: 男 女
- html中头meta信息
一.页面关键字 网站关键字:用户通过搜索引擎能搜到该网站的词汇.最好控制在10个以内. 基本语法: <meta name="keywords" content="具 ...
- delphi的流操作的语法
Delphi在这两方面都做的相当出色.在Delphi的早期版本Turbo Pascal 中就曾有流(Stream).群(Collection)和资源(Resource)等专门用于对象式数据管理的类.在 ...
- 368. Largest Divisible Subset
class Solution { public: vector<int> largestDivisibleSubset(vector<int>& nums) { vec ...
- Oracle使用外部表批量创建用户
整体思路:通过使用外部表将用户名导入Oracle的表中,然后通过PL/SQL遍历数据表,批量创建用户. 具体步骤如下: 1.在安装数据库的服务器的C盘根目录创建一个User List.txt文件,内容 ...
- 使用redis作为Return存储方式
Return组件可以理解为SaltStack系统对执行Minion返回后的数据进行存储或者返回给其他程序,它支持多种存储方式,比如MySQL.Redis.Memcache等,通过Return我们可以对 ...