zoukankan      html  css  js  c++  java
  • use Visual studio2012 developing kernel driver monitor thread creation on Windows8

    In Windows NT, the 80386 protected mode "protection" is more robust than Windows 95, the "gilded cage" more solid, more difficult to break. In Windows 95, at least the application I / O operation is unrestricted, Windows NT application even this permission are deprived. Less likely to enter in the NT almost real ring0 layer.
    In Windows NT, there are three Device Driver:
      1. "Virtual device Driver" (VDD). VDD, 16-bit applications, such as DOS and Win16 applications can access specific I / O ports (Note, not direct access, but to VDD to access).
      2. "GDI Driver", display and print the necessary GDI functions.
      3. "Kernel Mode Driver", the operation of specific hardware, for example, CreateFile, CloseHandle (file object), ReadFile, WriteFile, the DeviceIoControl other operations. "Kernel Mode Driver" Windows NT hardware interrupt and DMA operation Driver. SCSI port driver and NIC NDIS driver Kernel Mode Driver is a special form.
     
     
    Visual studio2012 Windows8 bring new experience exceptionally different
     
    1.Start Vs2012




    2. Seen everywhere driven development template




    3.Select a drive mode, there are two types of kernel mode and user mode driver




     
    4 Create a driver, KMDF DriverMVP




     

    We choose a kernel mode driver Below is created after the success of the interface are the driver, and the driver installation package




    Insert the following code to create a thread ring0 layer drive monitoring, see Code Analysis


    #include "ThreadMon.h"  
    #include "../inc/ioctls.h"  
      
    //  
    //////////////////////////////////////////////////////////////////////////  
      
    //////////////////////////////////////////////////////////////////////////  
    //  
    // 全局变量  
    //  
      
    PDEVICE_OBJECT  g_pDeviceObject;  
      
    //  
    //////////////////////////////////////////////////////////////////////////  
      
    //////////////////////////////////////////////////////////////////////////  
    //  
    // 函数实现  
    //  
      
    NTSTATUS  
    DriverEntry(  
        IN PDRIVER_OBJECT       DriverObject,  
        IN PUNICODE_STRING      RegistryPath  
    )  
    {  
        NTSTATUS            Status = STATUS_SUCCESS;      
        UNICODE_STRING      ntDeviceName;  
        UNICODE_STRING      dosDeviceName;  
        UNICODE_STRING      ThreadEventString;  
        PDEVICE_EXTENSION   deviceExtension;  
        PDEVICE_OBJECT      deviceObject = NULL;  
          
        KdPrint(("[ThreadMon] DriverEntry: %wZ\n", RegistryPath));  
          
        //  
        // 创建设备对象  
        //  
        RtlInitUnicodeString(&ntDeviceName, THREADMON_DEVICE_NAME_W);  
          
        Status = IoCreateDevice(  
                            DriverObject,   
                            sizeof(DEVICE_EXTENSION),       // DeviceExtensionSize  
                            &ntDeviceName,                  // DeviceName  
                            FILE_DEVICE_THREADMON,          // DeviceType  
                            0,                              // DeviceCharacteristics  
                            TRUE,                           // Exclusive  
                            &deviceObject                   // [OUT]  
                            );  
      
        if(!NT_SUCCESS(Status))  
        {  
            KdPrint(("[ThreadMon] IoCreateDevice Error Code = 0x%X\n", Status));  
              
            return Status;  
        }  
          
        //  
        // 设置扩展结构  
        //  
        deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;  
          
        //  
        // Set up synchronization objects, state info,, etc.  
        //  
        deviceObject->Flags |= DO_BUFFERED_IO;  
          
        //  
        // 创建符号链接  
        //  
        RtlInitUnicodeString(&dosDeviceName, THREADMON_DOS_DEVICE_NAME_W);  
          
        Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);  
          
        if(!NT_SUCCESS(Status))  
        {  
            KdPrint(("[ThreadMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));  
      
            IoDeleteDevice(deviceObject);  
              
            return Status;  
        }  
          
        //  
        // 分发IRP  
        //  
        DriverObject->MajorFunction[IRP_MJ_CREATE]           = ThreadMonDispatchCreate;  
        DriverObject->MajorFunction[IRP_MJ_CLOSE]            = ThreadMonDispatchClose;  
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]   = ThreadMonDispatchDeviceControl;  
        DriverObject->DriverUnload                           = ThreadMonUnload;  
          
        //  
        // 保存设备对象指针  
        //  
        g_pDeviceObject = deviceObject;  
      
        //  
        // 创建事件对象与应用层通信  
        //  
        RtlInitUnicodeString(&ThreadEventString, EVENT_NAME);  
          
        deviceExtension->ThreadEvent = IoCreateNotificationEvent(&ThreadEventString, &deviceExtension->ThreadHandle);  
        KeClearEvent(deviceExtension->ThreadEvent);          // 非受信状态  
      
        //  
        // 设置回调例程  
        //  
        Status = PsSetCreateThreadNotifyRoutine(ThreadCallback);  
      
        return Status;  
    }  
      
    NTSTATUS  
    ThreadMonDispatchCreate(  
        IN PDEVICE_OBJECT       DeviceObject,  
        IN PIRP                 Irp  
    )  
    {  
        NTSTATUS Status = STATUS_SUCCESS;  
          
        Irp->IoStatus.Information = 0;  
          
        KdPrint(("[ThreadMon] IRP_MJ_CREATE\n"));  
          
        Irp->IoStatus.Status = Status;  
        IoCompleteRequest(Irp, IO_NO_INCREMENT);  
          
        return Status;  
    }  
      
    NTSTATUS  
    ThreadMonDispatchClose(  
        IN PDEVICE_OBJECT       DeviceObject,  
        IN PIRP                 Irp  
    )  
    {  
        NTSTATUS Status = STATUS_SUCCESS;  
          
        Irp->IoStatus.Information = 0;  
          
        KdPrint(("[ThreadMon] IRP_MJ_CLOSE\n"));  
          
        Irp->IoStatus.Status = Status;  
        IoCompleteRequest(Irp, IO_NO_INCREMENT);  
          
        return Status;  
    }  
      
    NTSTATUS  
    ThreadMonDispatchDeviceControl(  
        IN PDEVICE_OBJECT       DeviceObject,  
        IN PIRP                 Irp  
    )  
    {  
        NTSTATUS            Status = STATUS_SUCCESS;  
        PIO_STACK_LOCATION  irpStack;  
        PDEVICE_EXTENSION   deviceExtension;  
        ULONG               inBufLength, outBufLength;  
        ULONG               ioControlCode;  
        PCALLBACK_INFO      pCallbackInfo;  
          
        // 获取当前设备栈  
        irpStack = IoGetCurrentIrpStackLocation(Irp);  
        deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;  
          
        // 提取信息  
        pCallbackInfo = Irp->AssociatedIrp.SystemBuffer;  
        inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;  
        outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;  
        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;  
      
        // 处理不同的IOCTL  
        switch (ioControlCode)  
        {  
        case IOCTL_THREAD_MON:  
            {  
                KdPrint(("[ThreadMon] IOCTL: 0x%X", ioControlCode));  
      
                if (outBufLength >= sizeof(PCALLBACK_INFO))  
                {  
                    pCallbackInfo->ProcessId = deviceExtension->ProcessId;  
                    pCallbackInfo->ThreadId = deviceExtension->ThreadId;  
                    pCallbackInfo->Create = deviceExtension->Create;  
      
                    Irp->IoStatus.Information = outBufLength;  
                }   
                break;  
            }  
              
        default:  
            {  
                Status = STATUS_INVALID_PARAMETER;  
                Irp->IoStatus.Information = 0;  
                  
                KdPrint(("[ThreadMon] Unknown IOCTL: 0x%X (%04X,%04X)", \  
                        ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), \  
                        IoGetFunctionCodeFromCtlCode(ioControlCode)));  
                  
                break;  
            }  
        }  
          
        Irp->IoStatus.Status = Status;  
        IoCompleteRequest(Irp, IO_NO_INCREMENT);      
          
        return Status;  
    }  
      
    VOID  
    ThreadMonUnload(  
        IN PDRIVER_OBJECT       DriverObject  
    )  
    {  
        UNICODE_STRING dosDeviceName;  
          
        //  
        // Free any resources  
        //  
      
        // 卸载回调例程  
        PsRemoveCreateThreadNotifyRoutine(ThreadCallback);  
          
        //  
        // Delete the symbolic link  
        //  
          
        RtlInitUnicodeString(&dosDeviceName, THREADMON_DEVICE_NAME_W);  
          
        IoDeleteSymbolicLink(&dosDeviceName);  
          
        //  
        // Delete the device object  
        //  
          
        IoDeleteDevice(DriverObject->DeviceObject);  
          
        KdPrint(("[ThreadMon] Unloaded"));  
    }  
      
    VOID  
    ThreadCallback(  
        IN HANDLE               ProcessId,          // 进程ID  
        IN HANDLE               ThreadId,           // 线程ID  
        IN BOOLEAN              Create              // 创建还是终止  
    )  
    {  
        PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;  
      
        deviceExtension->ProcessId = ProcessId;  
        deviceExtension->ThreadId = ThreadId;  
        deviceExtension->Create = Create;  
      
        // 触发事件,通知应用程序  
        KeSetEvent(deviceExtension->ThreadEvent, 0, FALSE);  
        KeClearEvent(deviceExtension->ThreadEvent);  
    }  
      
    //  
    /////////////////////////////////////////////////////////////////////////


    ring3 layer following the calling code

    #include "windows.h"  
    #include "winioctl.h"  
    #include "stdio.h"  
    #include "../inc/ioctls.h"  
      
    #define SYMBOL_LINK "\\\\.\\ThreadMon"  
      
    int main()  
    {  
        CALLBACK_INFO cbkinfo, cbktemp = {0};  
          
        // 打开驱动设备对象  
        HANDLE hDriver = ::CreateFile(  
                                    SYMBOL_LINK,  
                                    GENERIC_READ | GENERIC_WRITE,  
                                    0,  
                                    NULL,  
                                    OPEN_EXISTING,  
                                    FILE_ATTRIBUTE_NORMAL,  
                                    NULL);  
        if (hDriver == INVALID_HANDLE_VALUE)  
        {  
            printf("打开驱动设备对象失败!\n");  
              
            return -1;  
        }  
          
        // 打开内核事件对象  
        HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);  
          
        while (::WaitForSingleObject(hProcessEvent, INFINITE))  
        {  
            DWORD   dwRet;  
            BOOL    bRet;  
              
    //      printf("收到事件通知!\n");  
            bRet = ::DeviceIoControl(  
                                    hDriver,  
                                    IOCTL_THREAD_MON,  
                                    NULL,  
                                    0,  
                                    &cbkinfo,  
                                    sizeof(cbkinfo),  
                                    &dwRet,  
                                    NULL);  
              
            if (bRet)  
            {  
                if (cbkinfo.ProcessId != cbktemp.ProcessId || \  
                    cbkinfo.ThreadId != cbktemp.ThreadId || \  
                    cbkinfo.Create != cbktemp.Create)  
                {  
                    if (cbkinfo.Create)  
                    {  
                        printf("有线程被创建,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);  
                    }   
                    else  
                    {  
                        printf("有线程被终止,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);  
                    }  
                      
                    cbktemp = cbkinfo;  
                }  
            }   
            else  
            {  
                printf("\n获取进程信息失败!\n");  
                break;  
            }  
        }  
          
        ::CloseHandle(hDriver);  
          
        return 0;  
    }  









  • 相关阅读:
    vue中$refs、$slot、$nextTick相关的语法
    js中hash、hashchange事件
    js中filter的用法
    ES6新特性-函数的简写(箭头函数)
    js中把ajax获取的数据转化成树状结构(并做成多级联动效果)
    jq中get()和eq()的区别
    new Date() 日期格式处理
    微信小程序 加载图片时,先拉长,再恢复正常
    一个例子理解ES6的yield关键字
    eclipse在光标停留在同一对象的背景色提示,开启与关闭
  • 原文地址:https://www.cnblogs.com/new0801/p/6177613.html
Copyright © 2011-2022 走看看