修改自: 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. easyui获取选中行上一行的数据

    text: 'XX',            iconCls: 'icon-ok',            handler: function () {                var rowI ...

  2. swagger2常用注解

    常用注解: @Api()用于类: 表示标识这个类是swagger的资源 @ApiOperation()用于方法: 表示一个http请求的操作 @ApiParam()用于方法,参数,字段说明: 表示对参 ...

  3. Web测试常见问题点汇总

    UI测试 [目标] 确保用户可以访问产品所提供的浏览功能.符合企业或行业标准,包含用户易用性,友好性.可操作性等 [关注点] 菜单.对话框以及上边的文字.按钮.错误提示.帮助信息.图标.位置等. [常 ...

  4. JavaScript 之 预编译 作用域,作用域链

    第一次写博客,本来是学习jQuery遇到闭包问题,发现并没有理解闭包,发现闭包牵扯的知识点太多.复习了一遍(发现自己该记住的全忘了)写在博客里,自己也是小白,希望大神们指点迷津,必将感激不尽. 我们知 ...

  5. Java面试3

    反射的定义: 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取它所有的成员变量和方法并且显示出来. 反射机制的 ...

  6. 一个简单的定向python爬虫爬取指定页面的jpg图片

    import requests as r import re resul=r.get("http://www.imooc.com/course/list") urlinfo=re. ...

  7. tornado--输入和输出

    tornado--输入和输出 tornado的self.write只接受byte,Unicode,dict三种格式的对象. self.write会存在一个缓冲区,当不强制断开缓冲的时候,它会把当前函数 ...

  8. js cookie 操作 封装

    pCookie.js (function(){ var PotatogCookie = {}; //设置cookie PotatogCookie.set = function(key, value, ...

  9. Go语言极速入门手册.go

    Github: https://github.com/coderzh/CodeTips /* gotips_test.go: Golang速学速查速用代码手册 Source: github.com/c ...

  10. pymongo中的连接操作:Connection()与MongoClient()

    class MongoClient(pymongo.common.BaseObject) Connection to MongoDB. Method resolution order: MongoCl ...