Windows驱动
+ -

Ring0内核层创建事件,Ring3应用层接收

2022-09-02 288 0
原文转自:http://t.zoukankan.com/kekoukele987-p-7342105.html

在学习驱动过程中,一个很重要的内容就是Ring3层与Ring0层的通信,方法有很多种,互斥体,信号量,文件等等,用的比较普遍的,还是事件。所以在学习的过程中,做了一个简单的Demo,主要是体会一下方法。

在驱动程序下,首先要定义一个事件名,前面的一部分必须是BaseNamedObjects,这其实就是一个目录,后面的部分可以自己起,但不要太过简单和普遍,以免与现有的冲突。

  1. #define EVENT_NAME L"\\BaseNamedObjects\\Ring0Event"

定义两个全局变量

  1. PKEVENT g_Event;
  2. HANDLE g_EventHandle;
  3. NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
  4. {
  5. NTSTATUS Status = STATUS_SUCCESS;
  6. PDEVICE_OBJECT DeviceObject = NULL;
  7. UNICODE_STRING EventName;
  8. RtlInitUnicodeString(&EventName, EVENT_NAME); //需要UNICODE_STRING型,所以用RtlInitUnicodeString转换一下
  9. DriverObject->DriverUnload = DriverUnload;
  10. //IoCreateNotificationEvent例程创建或打开一个命名的通知事件,用来通知一个或多个线程执行一个事件发生。
  11. g_Event = IoCreateNotificationEvent(&EventName, &g_EventHandle); //1参数输入,2参数输出
  12. return Status;
  13. }
  14. VOID DriverUnload(PDRIVER_OBJECT DriverObject)
  15. {
  16. DbgPrint("DriverUnload()\r\n");
  17. if (g_EventHandle != NULL)
  18. {
  19. KeClearEvent(g_Event);
  20. ZwClose(g_EventHandle); //销毁资源
  21. g_EventHandle = NULL;
  22. g_Event = NULL;
  23. }
  24. }

应用层代码

  1. #include <windows.h>
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. HANDLE EventHandle = NULL;
  7. while (TRUE)
  8. {
  9. //事件名必须与驱动的相同
  10. EventHandle = OpenEvent(SYNCHRONIZE, FALSE, L"Global\\Ring0Event");
  11. if (EventHandle == NULL)
  12. {
  13. continue;
  14. }
  15. break;
  16. }
  17. //授信之后输出
  18. cout << "Ring3等待" << endl;
  19. while (TRUE)
  20. {
  21. int Index = WaitForSingleObject(EventHandle, 3000);
  22. Index = Index - WAIT_OBJECT_0;
  23. if (Index == WAIT_TIMEOUT) //超时
  24. {
  25. //注意这里当驱动卸载并关闭事件时事件对象是不能够得到及时的销毁 因为应用层占用了该对象
  26. //所以我们长时间等待不到授信 就关闭并重新打开
  27. if (EventHandle != NULL)
  28. {
  29. CloseHandle(EventHandle);
  30. EventHandle = NULL;
  31. EventHandle = OpenEvent(SYNCHRONIZE, FALSE, L"Global\\Ring0Event"); //第一参数为访问的事件对象,第二参数为是否继承,名字必须与驱动相同
  32. if (EventHandle == NULL)
  33. {
  34. cout << "对象已经不存在" << endl;
  35. break;
  36. }
  37. }
  38. continue;
  39. }
  40. if (Index == 0) //成功
  41. {
  42. cout << "Ring0触发Ring3" << endl;
  43. }
  44. if (Index == WAIT_FAILED)
  45. {
  46. break;
  47. }
  48. Sleep(1);
  49. }
  50. if (EventHandle != NULL)
  51. {
  52. CloseHandle(EventHandle);
  53. EventHandle = NULL;
  54. }
  55. getchar();
  56. return 0;
  57. }

上述代码在win7 x86 和win7 x64 的虚拟机下测试成功。

0 篇笔记 写笔记

内核事件等待KeWaitForSingleObject超时处理和IPR的完成例程
Windows内核中通过KeWaitForSingleObject等待事件完成,并且设置IPR的完成例程NTSTATUSIrpCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, ......
Windows应用层写数据到驱动
应用层传入信息的时候,可以使用WriteFile,也可以使用DeviceIoControl。DeviceIoControl是双向的,在读取设备的信息也可以使用。因此本书以DeviceIoControl为例子进行说明。DeviceIoControl称为设备控制接口。其特点是可以发送一个带有特定控制码的......
Windows内核事件Event
一些读者可能熟悉“事件驱动”编程技术。但是这里的“事件”与之不同。内核中的事件是一个数据结构。这个结构的指针可以当作一个参数传入一个等待函数中。如果这个事件不被“设置”,则这个等待函数不会返回,这个线程被阻塞。如果这个事件被“设置”,则等待结束,可以继续下去。这常常用于多个线程之间的同步。如果一个......
ASIO 应用层函数分类大全
初始化/终止ASIOError ASIOInit(ASIODriverInfo *info);ASIOError ASIOExit(void);开始、停止ASIOError ASIOStart(void);ASIOError ASIOStop(void);查询方法和抽样率ASIOError ......
ASIO 应用层C++类声明
class AsioDriver {public:AsioDriver(); ~AsioDriver();ASIOBool init(void *);void getDriverName(char *name);long getDriverVersion();void getErrorM......
ASIO 应用层工程组成
ASIO工程目录如下:asio:工程文件目录。asio.slncommon: asiosample.dll和hostsample.exe工程使用的公共文件 driver: asiosample文件目录host: hostsample文件目录ASIO应用层由asiosample工程和hostsa......
Ring0内核层创建事件,Ring3应用层接收
在学习驱动过程中,一个很重要的内容就是Ring3层与Ring0层的通信,方法有很多种,互斥体,信号量,文件等等,用的比较普遍的,还是事件。所以在学习的过程中,做了一个简单的Demo,主要是体会一下方法。在驱动程序下,首先要定义一个事件名,前面的一部分必须是BaseNamedObjects,这其实就......
Windows应用层创建共享内存,内核层使用ZwOpenSection打开
应用层创建共享内存,并使用RefreshBuffer通知内核层刷新数据:typedef struct __SHAREDBUFFER_HEADER { DWORD dwFrameType; /* compression hex (Data1 part......
Windows监则目录文件变化事件响应
////unsigned long __stdcall notificationThread(void* parameter)//{// char buff[100] = { 0 };// HANDLE notificationHandle = FindFirstChangeNo......
从内核调用应用层方式
从内核调用应用层有三种方式:1.APC - ntdll!KiUserApcDispatcher2.异常,其实和APC一样,只是回到应用层的入口函数不一样 ntdll!KiUserExceptionDispatcher3.内核回调内核回调APC、异常相对于内核回调,其回调到应用层的入口比较单一,而内......
使用管道PIPE在内核与应用层通讯
什么是PIPE管道?在Windows编程中,数据重定向需要用到管道PIPE,管道是一种用于在进程间共享数据的机制,通常由两端组成,数据从一端流入则必须从令一端流出,也就是一读一写,利用这种机制即可实现进程间直接通信。管道的本质其实是一段共享内存区域,多数情况下管道是用于应用层之间的数据交换的,其实驱......
PNP管理器事件
当设备管理器有动作时,使用PiInsertEventInQueue创建一个相关的事件动作,并挂入相应全局动作队列中,然后启用WorkItem来执行该动作。事件动作定义为:typedef struct _PNP_DEVICE_EVENT_ENTRY { LIST_ENTRY ......
Windows10应用层音频框架及模块关系图
在 Windows 操作系统中,处理音频缓冲的主要组件包括以下几个:其中各个模块的DLL依赖关系如下:音频各个模块之间的关系图如下: 核心音频 API 包括在 Audioses.dll 和 Mmdevapi.dll 用户模式系统模块中实现的 MMDevice API、WASAPI、DeviceTo......
QT控件事件事件响应函数关联
我们在上面的代码中,本来相对QLabel标签加一个点击事件了,但发现标签没有点击事件。差评,MFC就是可以的。所以,我们只能引入QPushButton控件来实现了。#include "mainwindow.h"#include
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!