• 驱动层和应用层的同步通信


    首先是同步问题,通过Ring3创建事件,并将该事件传递给Ring0,同时Ring3创建监控线程,等待Ring0发起事件。

                                               监控到事件(通知)

    Ring0(监控)----------------------------------------------------------------> Ring3  

    应用层得到事件通知后,向驱动层发起数据获取请求。由Ring3主动发起,Ring0被动接受。

                                              询问(CTL_CODE)

    Ring3     ---------------------------------------------------------------- >     Ring0  

                                            回答(通过OUT参数)

    Ring3     <----------------------------------------------------------------       Ring0  

     

    具体实现:

    应用层:

    HANDLE hDevice = CreateFile("\\\\.\\PRMonitor",
                                    GENERIC_READ|GENERIC_WRITE,
                                    0,
                                    NULL,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_SYSTEM,
                                    NULL);   //打开设备
        if(hDevice==INVALID_HANDLE_VALUE)
        {
            printf("Failed to obtain device with error code: %d\n",GetLastError());
            getchar();
            return;
        }
    
        
        DWORD dwOutput;
        char* OutputBuffer[256];
        HANDLE m_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);  //创建事件
        DeviceIoControl(hDevice,IOCTL_STARTHOOK,&m_hEvent,sizeof(HANDLE),NULL,0,&dwOutput,NULL); //发事件给ring0
        
        printf("IoControl code sent\n");
        while(true)
        {
    
            WaitForSingleObject(m_hEvent,INFINITE);  //等待ring0事件通知
            DeviceIoControl(hDevice,IOCTL_GETINFO,NULL,0,&OutputBuffer,256,&dwOutput,NULL);  //获取数据
            printf("%s\n",OutputBuffer);
            ResetEvent(m_hEvent);  //重置事件
        }
     
    驱动层:

    PRKEVENT gpEventObject;
    POBJECT_HANDLE_INFORMATION objHandleInfo;

     
    NTSTATUS DevDispatch(PDEVICE_OBJECT  DeviceObject,PIRP  Irp)
    {
        PVOID pInBuffer;
        ULONG pInbufferSize;
        PVOID pOutBuffer;
        ULONG pOutbufferSize;
        NTSTATUS status;
        PIO_STACK_LOCATION ps = IoGetCurrentIrpStackLocation(Irp);
                
        switch(ps->Parameters.DeviceIoControl.IoControlCode)
        {
        case IOCTL_STARTHOOK:  //传送事件
            if(!bProcMon)
            {
                ……
                pInBuffer = Irp->AssociatedIrp.SystemBuffer;
                pInbufferSize = ps->Parameters.DeviceIoControl.InputBufferLength;
                if(pInBuffer == NULL || pInbufferSize < sizeof(HANDLE))
                {
                    KdPrint(("Set Event Error\n"));
                    status = STATUS_INVALID_BUFFER_SIZE;
                    break;
                }
                hEvent = *(HANDLE*)pInBuffer;
    
                status = ObReferenceObjectByHandle(hEvent,
                    GENERIC_ALL,
                    NULL,
                    KernelMode,
                    &gpEventObject,
                    &objHandleInfo);
                KdPrint(("gpEventObject: %x\n",gpEventObject));
                
                
            }
            
            break;
    
        case IOCTL_GETINFO:    //传送数据
            pOutBuffer = Irp->AssociatedIrp.SystemBuffer;
            pOutbufferSize = ps->Parameters.DeviceIoControl.OutputBufferLength;
            RtlCopyMemory(pOutBuffer,output,sizeof(output));
            
            Irp->IoStatus.Information = pOutbufferSize; 
            
            break;
        }
        //////////////////////////////////////////////////////////////////////////
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
     
    在需要通知应用层事件的地方(比如监控到某一事件时)加上这一句
    KeSetEvent(gpEventObject,0,FALSE);  
    这时应用层程序就会通过DeviceIoControl向驱动层请求数据。
     
     
     
     

    在一般情况下,某事物个体发生具有其特有属性的负面现象,且无法以科学的角度得到合理有效的解释。我们通常称此类现象为“人品问题”(RPWT)。
                                                   ——摘自《辞海》第314页

  • 相关阅读:
    ansible-handlers
    LNMP
    编译安装sshpass
    cadence-irun(xrun) 增量编译
    sva 基础语法
    bsub && lsf 介绍
    Perl 输出内容到 excel
    Perl sendmail
    dlopen与dlsym用法
    perl在linux下通过date获取当前时间
  • 原文地址:https://www.cnblogs.com/dflower/p/1438066.html
Copyright © 2020-2023  润新知