zoukankan      html  css  js  c++  java
  • 驱动程序与驱动程序交互事件对象

    最近看张帆的《windows驱动技术开发详解》,看了一些东西通过写一些Demo来加深理解,这里把自己学习的东西和写的Demo记录下来,如有不妥,还请批评指正。

    8.5.5 驱动程序与驱动程序交互事件对象

    当我们在Ring0与Ring0交互的时候,类似于Ring0A与RingB各自的派遣函数要同步则我们要在这两者之间进行交互事件对象。

    这里的关键是,A与B的事件对象的问题,即如何让A获得B的事件对象,书中的方法是让B创建一个有“名字”的事件对象,让A根据这个“名字”来找事件对象的指针,

    在前面的章节中曾经提过IoCreateNotificationEvent和IoCreateSynchronizationEvent函数,前者创建“通知事件”对象,后者创建“同步事件”对象。主要的区别在8.5.3 内核模式下的事件对象中有讲,即如果创建的是通知事件,那么当事件对象变为激发态,程序员需要手动将其改为未激发态,如果创建的是同步事件,那么当事件处于激发态的时候,如果遇到KeWaitForxxxxx的函数的时候,事件对象则自动变回未激发态(这里有Demo,之后再说,虽然有一些问题和书上还有出入等解决在发出来)。

    这里我们取名字为:

    #define EVENT_NAME L"\BaseNamedObjects\ServerKernelEvent"

    我们都用UNICODE_STRING来描述内核事件对象的名字,然后使用IoCreateNotificationEvent,这个函数:如果内核中不存在指定名称的内核事件对象则创建该名称的内核事件对象,如果内核中存在指定名称的内核事件对象,则打开这个内核事件对象。

    测试的话,x86,x64都通过

    先上Server

    然后上Client

     最后记得要将两个驱动都卸载

     以上

    server

    1 #include <ntifs.h>
    2 
    3 #define EVENT_NAME  L"\BaseNamedObjects\ServerKernelEvent"
    4 
    5 
    6 void ThreadProc(PVOID ParameterData);
    7 
    8 
    9 VOID DriverUnload(PDRIVER_OBJECT DriverObject);
     1 #include "Ring0_Server.h"
     2 
     3 PKEVENT __KEvent;
     4 HANDLE  __EventHandle;
     5 
     6 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
     7 {
     8     NTSTATUS Status = STATUS_SUCCESS;
     9     PDEVICE_OBJECT  DeviceObject = NULL;
    10     UNICODE_STRING EventName;
    11     HANDLE ThreadHandle = NULL;
    12     CLIENT_ID ClientID = { 0 };
    13     DbgPrint("DriverEntry()
    ");
    14 
    15     DriverObject->DriverUnload = DriverUnload;
    16     
    17     RtlInitUnicodeString(&EventName, EVENT_NAME);
    18 
    19     __KEvent = IoCreateNotificationEvent(
    20         &EventName,
    21         &__EventHandle
    22     );//如果内核中不存在指定名称的内核事件对象则创建该名称的内核事件对象
    23     //如果内核中存在指定名称的内核事件对象,则打开这个内核事件对象
    24     
    25     KeResetEvent(__KEvent);
    26     
    27     Status = PsCreateSystemThread(
    28         &ThreadHandle, 
    29         0, 
    30         NULL, 
    31         NtCurrentProcess(),
    32         &ClientID,
    33         (PKSTART_ROUTINE)ThreadProc, 
    34         NULL);
    35 
    36     return Status;
    37 }
    38 
    39 void ThreadProc(PVOID ParameterData)
    40 {
    41     NTSTATUS Status;
    42 
    43     KeWaitForSingleObject(
    44         __KEvent, 
    45         Executive, 
    46         KernelMode, 
    47         FALSE, 
    48         NULL
    49     );
    50     
    51     DbgPrint("ThreadProcedure() Exit
    ");
    52     PsTerminateSystemThread(STATUS_SUCCESS);
    53 }
    54 
    55 
    56 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
    57 {
    58     DbgPrint("DriverUnload()
    ");
    59     //记得关闭
    60     if (__EventHandle != NULL)
    61     {
    62         KeClearEvent(__KEvent);
    63 
    64         ZwClose(__EventHandle);
    65 
    66         __EventHandle = NULL;
    67         __KEvent = NULL;
    68     }
    69 }
    Ring0_Server.c

    //client

    1 #include <ntifs.h>
    2 
    3 #define EVENT_NAME  L"\BaseNamedObjects\ServerKernelEvent"
    4 
    5 
    6 
    7 VOID DriverUnload(PDRIVER_OBJECT DriverObject);
    Ring0_Client.h
     1 #include "Ring0_Client.h"
     2 
     3 PKEVENT __KEvent;
     4 HANDLE  __EventHandle;
     5 
     6 
     7 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
     8 {
     9     NTSTATUS Status = STATUS_SUCCESS;
    10     PDEVICE_OBJECT  DeviceObject = NULL;
    11     UNICODE_STRING  EventName;
    12     DbgPrint("DriverEntry()
    ");
    13     DriverObject->DriverUnload = DriverUnload;
    14 
    15     RtlInitUnicodeString(&EventName, EVENT_NAME);
    16     __KEvent = IoCreateNotificationEvent(
    17         &EventName, 
    18         &__EventHandle
    19     );    
    20     KeSetEvent(__KEvent, IO_NO_INCREMENT, FALSE);
    21     return Status;
    22 }
    23 
    24 
    25 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
    26 {
    27     DbgPrint("DriverUnload()
    ");
    28 
    29     if (__EventHandle != NULL)
    30     {
    31         KeClearEvent(__KEvent);
    32         ZwClose(__EventHandle);
    33         __EventHandle = NULL;
    34         __KEvent = NULL;
    35     }
    36 
    37 }
    Ring0_Client.c
  • 相关阅读:
    玩转MySQL之Linux下的简单操作(服务启动与关闭、启动与关闭、查看版本)
    玩转MySQL之Linux下修改默认编码
    机器学习算法及应用领域相关的中国大牛
    [转载]Python 包管理工具解惑
    Vim常用操作和快捷键技巧总结
    [转载]那些C++牛人的博客
    [转载]学习c/c++的好网站
    [转载]C++内存管理
    [转载]SQL数据库如何加快查询速度
    [转载]Python3.x和Python2.x的区别
  • 原文地址:https://www.cnblogs.com/1228073191Blog/p/7342021.html
Copyright © 2011-2022 走看看