修改自: 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通信方式的更多相关文章

  1. ring0和ring3的区别

    现在探讨内核程序和应用程序之间的本质区别.除了能用WDK编写内核程序和阅读一部分Windows的内核代码之外,我们还需要了解它们的本质是什么,它们和我们熟悉的应用程序有什么区别. Intel的x86处 ...

  2. RING0到RING3

    在前一篇文章里面,我们将了CPU保护模式中的几种特权RING0,RING1,RING2,RING3!操作系统通常运行在RING0,应用程序通常运行在RING3. CPU如何从RING0到RING3 先 ...

  3. ring0 与 ring3 层之间的交互

    在进行Windows的ring0层开发时,必不可免的要与 ring3 层进行交互.进行数据间的相互传输.可用的方法有DeviceIoCntrol,ReadFile.我平常都是用的DeviceIoCon ...

  4. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)

    [0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...

  5. Ring3 和Ring0 解释

    这得从CPU指令系统(用于控制CPU完成各种功能的命令)的特权级别说起.在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃.比如:清内存.设置时钟等.如果所有的程序都能使用这些 ...

  6. RING0,RING1,RING2,RING3

    Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3.Windows只使用其中的两个级别RING0和RING3,RING0只给操作系统用,RING3谁都能用.如果普 ...

  7. Ring0创建事件Ring3设置事件

    同步事件(synchronizationEvent)当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则自动变回未激发态通知事件(NotificationEvent)当事件对象为激发 ...

  8. Ring3创建事件Ring0设置事件

    应用程序中创建的事件和在内核中创建的事件对象,本质上是同一个东西,在用户模式中,他用句柄表示,在内核模式下,他用KEVENT表示数据结构表示.在应用程序中,所有的内核对象都不会被用户看到,用户看到的知 ...

  9. 全虚拟化和半虚拟化的区别 cpu的ring0~ring3又是什么概念?

    ring0是指CPU的运行级别,ring0是最高级别,ring1次之,ring2更次之-- 拿Linux+x86来说, 操作系统(内核)的代码运行在最高运行级别ring0上,可以使用特权指令,控制中断 ...

随机推荐

  1. 配置STP、RSTP以及负载均衡

    生成树协议是一种二层管理协议,它通过有选择性地阻塞网络冗余链路来达到消除网络二层环路的目的,同时具备链路的备份功能. 每个VLAN都生成一棵树是一种比较直接,而且最简单的解决方法.它能够保证每一个VL ...

  2. [亲身实践]linux命令行下配置网路

    1.在命令行下输入setup, 2.之后出现下图,选择网络配置 4.配置IP地址,子网掩码,DNS 5.保存之后回到命令行模式下,输入service network restart,至此网络配置完成

  3. select 下拉选择自动到textarea框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. jmeter脚本录制与性能指标分析

    一.浏览器代理设置(猎豹) 1.打开猎豹浏览器,进行如下图操作 2.点击局域网设置 3.输入如下信息,注意端口不要重复 4.输入网址www.baidu.com,不能正常访问就是正确的 5.查看添加的端 ...

  5. Vue2.5学习路线及基础知识总结。

    在接触新技术不了解时,我喜欢去慕课网上看新手教程,在学习vue时,在慕课网上看了几个老师的视频,发现这挺好,讲到挺详细的,适合新手,有兴趣的可以先看一下,vue2.5入门教程. 然后在学习路上看见了一 ...

  6. C# 中String.Join()方法

    今天在工作中看到了组里一个大佬写的代码,感触颇多,同样实现一个需求,我写循环费了老大劲,代码又臭又长,大佬的代码简洁明了,三行搞定...不得不说,今天赚大了 简单总结一下今天赚到的知识 string里 ...

  7. android studio连接真机大概问题

    首先,确定手机Android的版本(最好用统一版本) 版本一样的话错误会少一点... 手机打开开发者选项(每个手机不同,百度可查) 开发者选项中打开USB调试 点击OK,可以进入Android mon ...

  8. synchronized各种使用场景

    synchronized属于JVM锁机制 一.使用场景 在并发量比较小的情况下访问公共资源,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重 二.应用场景:同步 ...

  9. java项目---用java实现二叉平衡树(AVL树)并打印结果(详)(3星)

    package Demo; public class AVLtree { private Node root; //首先定义根节点 private static class Node{ //定义Nod ...

  10. robot framework类型强制转换

    在测试过程中需要比较两个数值是否存在一定的关系 1.若新增一个数据,删除一个数据,判断他是否新增成功或者删除成功,除了判断本身数据成功显示与不显示之外,可以通过总数间接去判断是否成功 A)新增删除前获 ...