博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ring3创建事件Ring0设置事件
阅读量:5290 次
发布时间:2019-06-14

本文共 9731 字,大约阅读时间需要 32 分钟。

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

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

 

Ring0(设置事件).h

1 #include 
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             NULL154         );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 
6 #include
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 INFINITE139 );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 }

 

转载于:https://www.cnblogs.com/1228073191Blog/p/7497938.html

你可能感兴趣的文章
蓝牙的几种应用层协议作用
查看>>
《Akka应用模式:分布式应用程序设计实践指南》读书笔记8
查看>>
jQuery垂直滑动切换焦点图
查看>>
Python-S9-Day127-Scrapy爬虫框架2
查看>>
模运算
查看>>
python多线程的使用
查看>>
团队编程项目作业1-成员简介及分工
查看>>
使用Chrome(PC)调试移动设备上的网页
查看>>
UI基础--手写代码实现汤姆猫动画
查看>>
Python+pytesseract+Tesseract-OCR图片文字识别(只适合新手)
查看>>
使用gitbash来链接mysql
查看>>
docker镜像管理基础
查看>>
黑盒测试和百合测试的优缺点对比
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
装饰者模式
查看>>
右侧导航栏(动态添加数据到list)
查看>>
用Nginx+Lua(OpenResty)开发高性能Web应用
查看>>
81、iOS本地推送与远程推送详解
查看>>
Sharepoint online 如何使用asp.net开发项目!!!
查看>>
C#基础_注释和VS常用快捷键(一)
查看>>