Ring3创建事件Ring0设置事件

应用程序中创建的事件和在内核中创建的事件对象,本质上是同一个东西,在用户模式中,他用句柄表示,在内核模式下,他用KEVENT表示数据结构表示。在应用程序中,所有的内核对象都不会被用户看到,用户看到的知识代表内核对象的对象句柄。
这个代码就是要在Ring3与RIng0之间用一个事件对象。
解决的第一个问题就是如何将Ring3创建的事件传递给驱动:
使用DeviceIoControl,在Ring3中创建一个同步事件,然后用DeviceIoControl将事件句柄传递给驱动程序。需要指出的是句柄和进程是相关的,也就是说一个进程的句柄只有在这个进程中有效。句柄相当于事件对象在进程中的索引,通过这个索引操作系统就可以得到事件对象的指针:ObReferenceObjectByHandle,函数返回一个状态值,表示是否成功获得指针
这个函数在得到指针的同时,会为对象的指针维护一个计数,没记调用的时候会使计数+1。因此为了计数平衡,在使用玩ObReferenceObjectByHandle之后要调用ObDereferenceObject函数,它使计数-1

Ring0(设置事件).h

 1 #include <ntifs.h>
 2
 3 #define CTL_EVENT  4     CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)
 5 #define CTL_SET_EVENT  6     CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS)
 7
 8 #define DEVICE_OBJECT_NAME  L"\\Device\\Ring0DeviceObjectName"
 9
10 #define DEVICE_LINK_NAME    L"\\DosDevices\\Ring0DeviceLinkName"
11
12
13
14
15
16
17 NTSTATUS PassThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp);
18
19 NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp);
20
21 NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount);
22
23
24 VOID DriverUnload(PDRIVER_OBJECT DriverObject);

Ring0(设置事件).c

  1 #include "Ring0(设置事件).h"
  2
  3 PKEVENT  __KernelEvent[20] = { 0 };
  4 ULONG_PTR __KernelEventCount = 0;
  5
  6 extern
  7 POBJECT_TYPE* ExEventObjectType;
  8
  9 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
 10 {
 11     NTSTATUS Status = STATUS_SUCCESS;
 12     PDEVICE_OBJECT  DeviceObject = NULL;
 13     UNICODE_STRING  DeviceObjectName;
 14     UNICODE_STRING  DeviceLinkName;
 15
 16
 17     DbgPrint("DriverEntry()\r\n");
 18     DriverObject->DriverUnload = DriverUnload;
 19
 20     RtlInitUnicodeString(&DeviceObjectName, DEVICE_OBJECT_NAME);
 21
 22     Status = IoCreateDevice(
 23         DriverObject,
 24         NULL,
 25         &DeviceObjectName,
 26         FILE_DEVICE_UNKNOWN,
 27         0,
 28         FALSE,
 29         &DeviceObject
 30     );
 31     if (!NT_SUCCESS(Status))
 32     {
 33         return Status;
 34     }
 35
 36     //创建设备连接名称
 37     RtlInitUnicodeString(&DeviceLinkName, DEVICE_LINK_NAME);
 38
 39     //将设备连接名称与设备名称关联
 40     Status = IoCreateSymbolicLink(&DeviceLinkName, &DeviceObjectName);
 41     if (!NT_SUCCESS(Status))
 42     {
 43         IoDeleteDevice(DeviceObject);
 44         return Status;
 45     }
 46
 47     //我们要的派遣函数
 48     for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
 49     {
 50         DriverObject->MajorFunction[i] = PassThroughDispatch;
 51     }
 52     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlThroughDispatch;
 53
 54
 55
 56     return Status;
 57 }
 58
 59
 60
 61
 62
 63
 64 NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp)
 65 {
 66     NTSTATUS Status = STATUS_UNSUCCESSFUL;
 67     ULONG_PTR Information = 0;
 68     PVOID InputData = NULL;
 69     ULONG InputDataLength = 0;
 70     PVOID OutputData = NULL;
 71     ULONG OutputDataLength = 0;
 72     ULONG IoControlCode = 0;
 73     PEPROCESS EProcess = NULL;
 74     PIO_STACK_LOCATION  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);  //Irp堆栈
 75     IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
 76     InputData = Irp->AssociatedIrp.SystemBuffer;
 77     OutputData = Irp->AssociatedIrp.SystemBuffer;
 78     InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
 79     OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
 80     switch (IoControlCode)
 81     {
 82     case CTL_EVENT:
 83     {
 84
 85         if (InputData != NULL&&InputDataLength == sizeof(HANDLE) * 2)
 86         {
 87
 88             Status = Ring3EventHandleToRing0KernelEvent((HANDLE*)InputData, InputDataLength / sizeof(HANDLE));
 89
 90         }
 91
 92
 93         Information = 0;
 94
 95         break;
 96
 97     }
 98
 99     case CTL_SET_EVENT:
100     {
101
102         DbgPrint("Ring0触发Ring3\r\n");
103         KeSetEvent(__KernelEvent[0], IO_NO_INCREMENT, FALSE);
104
105         DbgPrint("Ring0等待\r\n");
106         Status = KeWaitForSingleObject(__KernelEvent[1],
107             Executive, KernelMode, FALSE, NULL);    //注意这里的最后一个参数NULL 是永久等待
108
109         DbgPrint("Ring3触发Ring0\r\n");
110
111         Information = 0;
112         break;
113
114     }
115
116     default:
117     {
118
119         Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
120         Irp->IoStatus.Information = 0;
121
122
123
124         break;
125     }
126     }
127
128     Irp->IoStatus.Status = Status;
129     Irp->IoStatus.Information = Information;
130     IoCompleteRequest(Irp, IO_NO_INCREMENT);
131     return Status;
132 }
133
134 NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount)
135 {
136     NTSTATUS   Status = STATUS_SUCCESS;
137     PULONG_PTR HandleArray = NULL;
138     ULONG i = 0;
139
140     if (EventHandle == NULL)
141     {
142         return STATUS_UNSUCCESSFUL;
143     }
144     __KernelEventCount = EventHandleCount;
145
146     for (i = 0; i < EventHandleCount; i++)
147     {
148         Status = ObReferenceObjectByHandle((HANDLE)EventHandle[i],
149             SYNCHRONIZE,
150             *ExEventObjectType,
151             KernelMode,
152             &__KernelEvent[i],
153             NULL
154         );
155         if (!NT_SUCCESS(Status))
156         {
157             break;
158         }
159     }
160
161     if (Status != STATUS_SUCCESS)
162     {
163         for (i = 0; i < EventHandleCount; i++)
164         {
165             if (__KernelEvent[i] != NULL)
166             {
167                 ObDereferenceObject(__KernelEvent[i]);
168
169                 __KernelEvent[i] = NULL;
170             }
171         }
172     }
173     return Status;
174 }
175
176 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
177 {
178
179     DbgPrint("DriverUnload()\r\n");
180 }
181
182
183
184
185
186 NTSTATUS PassThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp)
187 {
188     Irp->IoStatus.Status = STATUS_SUCCESS;     //LastError()
189     Irp->IoStatus.Information = 0;             //ReturnLength
190     IoCompleteRequest(Irp, IO_NO_INCREMENT);   //将Irp返回给Io管理器
191     return STATUS_SUCCESS;
192 }

Ring3(创建事件).cpp

  1 // Ring3(创建事件).cpp : 定义控制台应用程序的入口点。
  2 //
  3
  4 #include "stdafx.h"
  5 #include <windows.h>
  6 #include <iostream>
  7
  8 using namespace std;
  9
 10 #define CTL_EVENT  11     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS)
 12
 13 #define CTL_SET_EVENT  14     CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS)
 15
 16 #define DeviceLinkName L"\\\\.\\Ring0DeviceLinkName"
 17
 18
 19 DWORD WINAPI ThreadProc(LPVOID ParameterData);
 20
 21 int main()
 22 {
 23     HANDLE DeviceHandle = CreateFile(
 24         DeviceLinkName,
 25         GENERIC_READ | GENERIC_WRITE,
 26         FILE_SHARE_READ | FILE_SHARE_WRITE,
 27         NULL,
 28         OPEN_EXISTING,
 29         FILE_ATTRIBUTE_NORMAL,
 30         NULL);
 31
 32
 33     if (DeviceHandle == INVALID_HANDLE_VALUE)
 34     {
 35         cout << "CreateFile FAIL  " << GetLastError() << endl;
 36         return 0;
 37     }
 38
 39     HANDLE EventHandle[3];
 40     for (int i = 0; i < 3; i++)
 41     {
 42         //用户模式同步事件
 43         EventHandle[i] = CreateEvent(
 44             NULL,
 45             FALSE,
 46             FALSE,
 47             NULL
 48         );
 49     }
 50     BOOL IsOK = FALSE;
 51
 52     DWORD ReturnLength = 0;
 53
 54     IsOK = DeviceIoControl(
 55         DeviceHandle,
 56         CTL_EVENT,
 57         EventHandle,
 58         sizeof(HANDLE)*2,
 59         NULL,
 60         0,
 61         &ReturnLength,
 62         NULL
 63     );
 64
 65     if (IsOK == FALSE)
 66     {
 67         goto Final;
 68     }
 69     //辅助线程
 70     HANDLE ThreadHandle = CreateThread(
 71         NULL,
 72         0,
 73         (LPTHREAD_START_ROUTINE)ThreadProc,
 74         (LPVOID)EventHandle,
 75         0,
 76         NULL
 77     );
 78
 79     IsOK = DeviceIoControl(
 80         DeviceHandle,
 81         CTL_SET_EVENT,
 82         NULL,
 83         0,
 84         NULL,
 85         0,
 86         &ReturnLength,
 87         NULL);
 88
 89     if (IsOK == FALSE)
 90     {
 91         cout << "Send IoCode Error" << endl;
 92         SetEvent(EventHandle[2]);
 93         WaitForSingleObject(ThreadHandle, INFINITE);
 94         goto Final;
 95     }
 96
 97
 98     WaitForSingleObject(ThreadHandle, INFINITE);
 99
100
101 Final:
102     {
103         for (int i = 0; i < 3; i++)
104         {
105             if (EventHandle[i] != NULL)
106             {
107                 CloseHandle(EventHandle[i]);
108                 EventHandle[i] = NULL;
109             }
110         }
111         if (ThreadHandle != NULL)
112         {
113             CloseHandle(ThreadHandle);
114             ThreadHandle = NULL;
115         }
116         if (DeviceHandle != NULL)
117         {
118             CloseHandle(DeviceHandle);
119             DeviceHandle = NULL;
120         }
121
122     }
123
124     printf("先卸载驱动\r\n");
125     printf("Input AnyKey To Exit\r\n");
126
127     getchar();
128     return 0;
129 }
130
131 DWORD WINAPI ThreadProc(LPVOID ParameterData)
132 {
133     cout << "Ring3 等啊等" << endl;
134     DWORD Index = WaitForMultipleObjects(
135         3,
136         (HANDLE*)ParameterData,
137         FALSE,
138         INFINITE
139     );
140
141     if (Index == 2)
142     {
143         cout << "ThreadProc EXIT " << endl;
144         return 0;
145     }
146     cout << "Ring0触发Ring3" << endl;
147
148     cout << "put any key Ring3 触发Ring0" << endl;
149
150     getchar();
151     getchar();
152
153
154     SetEvent(((HANDLE*)ParameterData)[1]);
155     cout << "ThreadProc EXIT" << endl;
156     return 0;
157
158
159
160
161 }
时间: 2024-11-09 01:02:16

Ring3创建事件Ring0设置事件的相关文章

Ring0创建事件Ring3设置事件

同步事件(synchronizationEvent)当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则自动变回未激发态通知事件(NotificationEvent)当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则不会自动变回未激发态 Ring0(创建事件).h 1 #include <ntifs.h> 2 3 4 #define EVENT_NAME L"\\BaseNamedObjects\\Ring0KernelEvent" 5

android之onclick事件及为adapter设置事件监听器

Android 的onclik事件的实现有三种写法: 1 package com.example.oncliek; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.view.View; 9 import

JS(原生)事件委托:为动态创建的节点绑定事件

项目开发中经常需要为动态创建的节点绑定事件, 比如需要创建一个动态列表:在li的数量非常少的时候,为每一个li绑定事件不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(假设),为每个li绑定事件就会对页面性能产生很大的影响.当有大量元素需要绑定相同事件的时候可采用事件委托,将在目标元素上要处理的事件委托给父元素或者祖先元素 优点    事件委托对于web应用程序的性能有如下几个优点:    1.需要管理的函数变少了    2.占用的内存少了    3.javascrip

asp.net 微信企业号办公系统-流程设计--流程步骤设置-事件设置

事件设置是设置当前步骤在提交前后或退回前后要执行的一些操作(该事件为服务器事件). 事件格式为:dll名称.命名空间名称.类名.方法名,这里不需要写括号和参数,处理时会自动带上当前流程实例的相关参数. 参数为:RoadFlow.Data.Model.WorkFlowCustomEventParams类的实例,里面包含当前流程步骤的相关信息. FlowID:当前流程ID. StepID:当前步骤ID. GroupID:当前流程实例的分组ID,一个流程实例的分组ID相同,此ID是为了区分一个流程的不

给js动态创建的对象绑定事件

1.使用原生JS动态为动态创建的对象绑定事件 1-1.创建一个function,用来兼容IE8以下浏览器添加事件 function addEvent(el, type, fn) {  if(el.addEventListener){ el.addEventListener(type,fn,false) }else if(el.attachEvent()){ el.attachEvent('on' + type,fn,false) }else{ return false }} 1-2.使用JS创建

.NET开源工作流RoadFlow-流程设计-流程步骤设置-事件设置

事件设置是设置当前步骤在提交前后或退回前后要执行的一些操作(该事件为服务器事件). 事件格式为:dll名称.命名空间名称.类名.方法名,这里不需要写括号和参数,处理时会自动带上当前流程实例的相关参数. 参数为:RoadFlow.Data.Model.WorkFlowCustomEventParams类的实例,里面包含当前流程步骤的相关信息. FlowID:当前流程ID. StepID:当前步骤ID. GroupID:当前流程实例的分组ID,一个流程实例的分组ID相同,此ID是为了区分一个流程的不

js原生创建模拟事件和自定义事件的方法

让我万万没想到的是,原来<JavaScript高级程序设计(第3版)>里面提到的方法已经是过时的了.后来我查看了MDN,才找到了最新的方法. 1. 模拟鼠标事件 MDN上已经说得很清楚,尽管为了保持向后兼容MouseEvent.initMouseEvent()仍然可用,但是呢,我们应该使用MouseEvent().我们使用如下页面做测试 1 <!DOCTYPE html> 2 <html> 3 <head lang="zh-CN"> 4

基于OpenGL编写一个简易的2D渲染框架-07 鼠标事件和键盘事件

这次为程序添加鼠标事件和键盘事件 当检测到鼠标事件和键盘事件的信息时,捕获其信息并将信息传送到需要信息的对象处理.为此,需要一个可以分派信息的对象,这个对象能够正确的把信息交到正确的对象. 实现思路: 要实现以上的功能,需要几个对象: 事件分派器:EventDispatcher,负责将 BaseEvent 分派给 EventListener 对象 事件监听器:EventListener,这只是一个接口类,接受 BaseEvent 的对象,真正的处理在它的子类中实现 事件:BaseEvent,储存

焦点 、event对象、事件冒泡、事件绑定、AJAX知识点备忘

焦点:使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 设置焦点的几种方式: 1.点击 2.TAB键 3.JS onfocus   onblur 属性 var oinp=document.getElementById('shuru') oinp.onfocus=function(){ if(oinp.value=='请输入'){ oinp.value='' } } oinp.onblur=function(){ if(oinp.value==''){ oinp