zoukankan      html  css  js  c++  java
  • 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()
    ");
     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
    ");
    103         KeSetEvent(__KernelEvent[0], IO_NO_INCREMENT, FALSE);
    104 
    105         DbgPrint("Ring0等待
    ");
    106         Status = KeWaitForSingleObject(__KernelEvent[1],
    107             Executive, KernelMode, FALSE, NULL);    //注意这里的最后一个参数NULL 是永久等待
    108 
    109         DbgPrint("Ring3触发Ring0
    ");
    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()
    ");
    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("先卸载驱动
    ");
    125     printf("Input AnyKey To Exit
    ");
    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 }
  • 相关阅读:
    textarea内容随高度自适应
    2017年7月19日面试后记
    如何在django中设置用邮箱也可以登录?
    新闻网站项目笔记
    新闻网站项目django+rest framework api+vue.js+reqwest
    关于js的一些基本概念
    新闻网站项目django--个人资料页
    新闻网站项目django--注册页
    新闻网站项目django--登录页
    新网网站项目django--详情页
  • 原文地址:https://www.cnblogs.com/1228073191Blog/p/7497938.html
Copyright © 2011-2022 走看看