zoukankan      html  css  js  c++  java
  • 用Visual studio2012在Windows8上开发内核驱动监视线程创建

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破。在Windows 95中,至少应用程序I/O操作是不受限制的,而在Windows NT中,我们的应用程序连这点权限都被剥夺了。在NT中几乎不太可能进入真正的ring0层。 
    在Windows NT中,存在三种Device Driver:

      1.“Virtual device Driver” (VDD)。通过VDD,16位应用程序,如DOS 和Win16应用程序可以访问特定的I/O端口(注意,不是直接访问,而是要通过VDD来实现访问)。

      2.“GDI Driver”,提供显示和打印所需的GDI函数。

      3.“Kernel Mode Driver”,实现对特定硬件的操作,比如说CreateFile, CloseHandle (对于文件对象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”还是Windows NT中唯一可以对硬件中断和DMA进行操作的Driver。SCSI 小端口驱动和 网卡NDIS 驱动都是Kernel Mode Driver的一种特殊形式。

     

     

    Visual studio2012与Windows8带来格外不同的新体验

     

    1.启动Vs2012

    2.看见满目的驱动开发模板

    3.选择一个驱动模式,有内核模式与用户模式两种的驱动

     

    4.创建一个驱动程序,KMDF DriverMVP

     

    5.我们选择的是内核模式的驱动程序,下面是创建成功后的界面,分别是驱动程序本身,与驱动安装包

    6.按下F5,选择驱动编译,

     

    插入下列代码实现ring0层驱动监视创建线程,请见代码分析

     

     

    [cpp] view plaincopy
     
    1. #include "ThreadMon.h"  
    2. #include "../inc/ioctls.h"  
    3.   
    4. //  
    5. //////////////////////////////////////////////////////////////////////////  
    6.   
    7. //////////////////////////////////////////////////////////////////////////  
    8. //  
    9. // 全局变量  
    10. //  
    11.   
    12. PDEVICE_OBJECT  g_pDeviceObject;  
    13.   
    14. //  
    15. //////////////////////////////////////////////////////////////////////////  
    16.   
    17. //////////////////////////////////////////////////////////////////////////  
    18. //  
    19. // 函数实现  
    20. //  
    21.   
    22. NTSTATUS  
    23. DriverEntry(  
    24.     IN PDRIVER_OBJECT       DriverObject,  
    25.     IN PUNICODE_STRING      RegistryPath  
    26. )  
    27. {  
    28.     NTSTATUS            Status = STATUS_SUCCESS;      
    29.     UNICODE_STRING      ntDeviceName;  
    30.     UNICODE_STRING      dosDeviceName;  
    31.     UNICODE_STRING      ThreadEventString;  
    32.     PDEVICE_EXTENSION   deviceExtension;  
    33.     PDEVICE_OBJECT      deviceObject = NULL;  
    34.       
    35.     KdPrint(("[ThreadMon] DriverEntry: %wZ ", RegistryPath));  
    36.       
    37.     //  
    38.     // 创建设备对象  
    39.     //  
    40.     RtlInitUnicodeString(&ntDeviceName, THREADMON_DEVICE_NAME_W);  
    41.       
    42.     Status = IoCreateDevice(  
    43.                         DriverObject,   
    44.                         sizeof(DEVICE_EXTENSION),       // DeviceExtensionSize  
    45.                         &ntDeviceName,                  // DeviceName  
    46.                         FILE_DEVICE_THREADMON,          // DeviceType  
    47.                         0,                              // DeviceCharacteristics  
    48.                         TRUE,                           // Exclusive  
    49.                         &deviceObject                   // [OUT]  
    50.                         );  
    51.   
    52.     if(!NT_SUCCESS(Status))  
    53.     {  
    54.         KdPrint(("[ThreadMon] IoCreateDevice Error Code = 0x%X ", Status));  
    55.           
    56.         return Status;  
    57.     }  
    58.       
    59.     //  
    60.     // 设置扩展结构  
    61.     //  
    62.     deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;  
    63.       
    64.     //  
    65.     // Set up synchronization objects, state info,, etc.  
    66.     //  
    67.     deviceObject->Flags |= DO_BUFFERED_IO;  
    68.       
    69.     //  
    70.     // 创建符号链接  
    71.     //  
    72.     RtlInitUnicodeString(&dosDeviceName, THREADMON_DOS_DEVICE_NAME_W);  
    73.       
    74.     Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);  
    75.       
    76.     if(!NT_SUCCESS(Status))  
    77.     {  
    78.         KdPrint(("[ThreadMon] IoCreateSymbolicLink Error Code = 0x%X ", Status));  
    79.   
    80.         IoDeleteDevice(deviceObject);  
    81.           
    82.         return Status;  
    83.     }  
    84.       
    85.     //  
    86.     // 分发IRP  
    87.     //  
    88.     DriverObject->MajorFunction[IRP_MJ_CREATE]           = ThreadMonDispatchCreate;  
    89.     DriverObject->MajorFunction[IRP_MJ_CLOSE]            = ThreadMonDispatchClose;  
    90.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]   = ThreadMonDispatchDeviceControl;  
    91.     DriverObject->DriverUnload                           = ThreadMonUnload;  
    92.       
    93.     //  
    94.     // 保存设备对象指针  
    95.     //  
    96.     g_pDeviceObject = deviceObject;  
    97.   
    98.     //  
    99.     // 创建事件对象与应用层通信  
    100.     //  
    101.     RtlInitUnicodeString(&ThreadEventString, EVENT_NAME);  
    102.       
    103.     deviceExtension->ThreadEvent = IoCreateNotificationEvent(&ThreadEventString, &deviceExtension->ThreadHandle);  
    104.     KeClearEvent(deviceExtension->ThreadEvent);          // 非受信状态  
    105.   
    106.     //  
    107.     // 设置回调例程  
    108.     //  
    109.     Status = PsSetCreateThreadNotifyRoutine(ThreadCallback);  
    110.   
    111.     return Status;  
    112. }  
    113.   
    114. NTSTATUS  
    115. ThreadMonDispatchCreate(  
    116.     IN PDEVICE_OBJECT       DeviceObject,  
    117.     IN PIRP                 Irp  
    118. )  
    119. {  
    120.     NTSTATUS Status = STATUS_SUCCESS;  
    121.       
    122.     Irp->IoStatus.Information = 0;  
    123.       
    124.     KdPrint(("[ThreadMon] IRP_MJ_CREATE "));  
    125.       
    126.     Irp->IoStatus.Status = Status;  
    127.     IoCompleteRequest(Irp, IO_NO_INCREMENT);  
    128.       
    129.     return Status;  
    130. }  
    131.   
    132. NTSTATUS  
    133. ThreadMonDispatchClose(  
    134.     IN PDEVICE_OBJECT       DeviceObject,  
    135.     IN PIRP                 Irp  
    136. )  
    137. {  
    138.     NTSTATUS Status = STATUS_SUCCESS;  
    139.       
    140.     Irp->IoStatus.Information = 0;  
    141.       
    142.     KdPrint(("[ThreadMon] IRP_MJ_CLOSE "));  
    143.       
    144.     Irp->IoStatus.Status = Status;  
    145.     IoCompleteRequest(Irp, IO_NO_INCREMENT);  
    146.       
    147.     return Status;  
    148. }  
    149.   
    150. NTSTATUS  
    151. ThreadMonDispatchDeviceControl(  
    152.     IN PDEVICE_OBJECT       DeviceObject,  
    153.     IN PIRP                 Irp  
    154. )  
    155. {  
    156.     NTSTATUS            Status = STATUS_SUCCESS;  
    157.     PIO_STACK_LOCATION  irpStack;  
    158.     PDEVICE_EXTENSION   deviceExtension;  
    159.     ULONG               inBufLength, outBufLength;  
    160.     ULONG               ioControlCode;  
    161.     PCALLBACK_INFO      pCallbackInfo;  
    162.       
    163.     // 获取当前设备栈  
    164.     irpStack = IoGetCurrentIrpStackLocation(Irp);  
    165.     deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;  
    166.       
    167.     // 提取信息  
    168.     pCallbackInfo = Irp->AssociatedIrp.SystemBuffer;  
    169.     inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;  
    170.     outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;  
    171.     ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;  
    172.   
    173.     // 处理不同的IOCTL  
    174.     switch (ioControlCode)  
    175.     {  
    176.     case IOCTL_THREAD_MON:  
    177.         {  
    178.             KdPrint(("[ThreadMon] IOCTL: 0x%X", ioControlCode));  
    179.   
    180.             if (outBufLength >= sizeof(PCALLBACK_INFO))  
    181.             {  
    182.                 pCallbackInfo->ProcessId = deviceExtension->ProcessId;  
    183.                 pCallbackInfo->ThreadId = deviceExtension->ThreadId;  
    184.                 pCallbackInfo->Create = deviceExtension->Create;  
    185.   
    186.                 Irp->IoStatus.Information = outBufLength;  
    187.             }   
    188.             break;  
    189.         }  
    190.           
    191.     default:  
    192.         {  
    193.             Status = STATUS_INVALID_PARAMETER;  
    194.             Irp->IoStatus.Information = 0;  
    195.               
    196.             KdPrint(("[ThreadMon] Unknown IOCTL: 0x%X (%04X,%04X)",   
    197.                     ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode),   
    198.                     IoGetFunctionCodeFromCtlCode(ioControlCode)));  
    199.               
    200.             break;  
    201.         }  
    202.     }  
    203.       
    204.     Irp->IoStatus.Status = Status;  
    205.     IoCompleteRequest(Irp, IO_NO_INCREMENT);      
    206.       
    207.     return Status;  
    208. }  
    209.   
    210. VOID  
    211. ThreadMonUnload(  
    212.     IN PDRIVER_OBJECT       DriverObject  
    213. )  
    214. {  
    215.     UNICODE_STRING dosDeviceName;  
    216.       
    217.     //  
    218.     // Free any resources  
    219.     //  
    220.   
    221.     // 卸载回调例程  
    222.     PsRemoveCreateThreadNotifyRoutine(ThreadCallback);  
    223.       
    224.     //  
    225.     // Delete the symbolic link  
    226.     //  
    227.       
    228.     RtlInitUnicodeString(&dosDeviceName, THREADMON_DEVICE_NAME_W);  
    229.       
    230.     IoDeleteSymbolicLink(&dosDeviceName);  
    231.       
    232.     //  
    233.     // Delete the device object  
    234.     //  
    235.       
    236.     IoDeleteDevice(DriverObject->DeviceObject);  
    237.       
    238.     KdPrint(("[ThreadMon] Unloaded"));  
    239. }  
    240.   
    241. VOID  
    242. ThreadCallback(  
    243.     IN HANDLE               ProcessId,          // 进程ID  
    244.     IN HANDLE               ThreadId,           // 线程ID  
    245.     IN BOOLEAN              Create              // 创建还是终止  
    246. )  
    247. {  
    248.     PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;  
    249.   
    250.     deviceExtension->ProcessId = ProcessId;  
    251.     deviceExtension->ThreadId = ThreadId;  
    252.     deviceExtension->Create = Create;  
    253.   
    254.     // 触发事件,通知应用程序  
    255.     KeSetEvent(deviceExtension->ThreadEvent, 0, FALSE);  
    256.     KeClearEvent(deviceExtension->ThreadEvent);  
    257. }  
    258.   
    259. //  
    260. //////////////////////////////////////////////////////////////////////////  



     

    ring3层调用代码如下

     

    [cpp] view plaincopy
     
      1. #include "windows.h"  
      2. #include "winioctl.h"  
      3. #include "stdio.h"  
      4. #include "../inc/ioctls.h"  
      5.   
      6. #define SYMBOL_LINK "\\.\ThreadMon"  
      7.   
      8. int main()  
      9. {  
      10.     CALLBACK_INFO cbkinfo, cbktemp = {0};  
      11.       
      12.     // 打开驱动设备对象  
      13.     HANDLE hDriver = ::CreateFile(  
      14.                                 SYMBOL_LINK,  
      15.                                 GENERIC_READ | GENERIC_WRITE,  
      16.                                 0,  
      17.                                 NULL,  
      18.                                 OPEN_EXISTING,  
      19.                                 FILE_ATTRIBUTE_NORMAL,  
      20.                                 NULL);  
      21.     if (hDriver == INVALID_HANDLE_VALUE)  
      22.     {  
      23.         printf("打开驱动设备对象失败! ");  
      24.           
      25.         return -1;  
      26.     }  
      27.       
      28.     // 打开内核事件对象  
      29.     HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);  
      30.       
      31.     while (::WaitForSingleObject(hProcessEvent, INFINITE))  
      32.     {  
      33.         DWORD   dwRet;  
      34.         BOOL    bRet;  
      35.           
      36. //      printf("收到事件通知! ");  
      37.         bRet = ::DeviceIoControl(  
      38.                                 hDriver,  
      39.                                 IOCTL_THREAD_MON,  
      40.                                 NULL,  
      41.                                 0,  
      42.                                 &cbkinfo,  
      43.                                 sizeof(cbkinfo),  
      44.                                 &dwRet,  
      45.                                 NULL);  
      46.           
      47.         if (bRet)  
      48.         {  
      49.             if (cbkinfo.ProcessId != cbktemp.ProcessId ||   
      50.                 cbkinfo.ThreadId != cbktemp.ThreadId ||   
      51.                 cbkinfo.Create != cbktemp.Create)  
      52.             {  
      53.                 if (cbkinfo.Create)  
      54.                 {  
      55.                     printf("有线程被创建,PID = %d,TID = %d ", cbkinfo.ProcessId, cbkinfo.ThreadId);  
      56.                 }   
      57.                 else  
      58.                 {  
      59.                     printf("有线程被终止,PID = %d,TID = %d ", cbkinfo.ProcessId, cbkinfo.ThreadId);  
      60.                 }  
      61.                   
      62.                 cbktemp = cbkinfo;  
      63.             }  
      64.         }   
      65.         else  
      66.         {  
      67.             printf(" 获取进程信息失败! ");  
      68.             break;  
      69.         }  
      70.     }  
      71.       
      72.     ::CloseHandle(hDriver);  
      73.       
      74.     return 0;  
      75. }  
  • 相关阅读:
    day11.初识函数
    day10.文件操作
    类,对象相关的部分系统函数
    网络资源
    mysql 设置默认时间为now()
    Meta http-equiv属性详解
    php 验证码
    php 图片上传 并返回上传文件位置 支持多文件上传
    图片懒加载
    mysqy 特别小点
  • 原文地址:https://www.cnblogs.com/huhu0013/p/3336548.html
Copyright © 2011-2022 走看看