用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

用Visual studio2012在Windows8上开发内核驱动监视线程创建

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

用Visual studio2012在Windows8上开发内核驱动监视线程创建

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

用Visual studio2012在Windows8上开发内核驱动监视线程创建

 

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

用Visual studio2012在Windows8上开发内核驱动监视线程创建

 

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

用Visual studio2012在Windows8上开发内核驱动监视线程创建

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

 

用Visual studio2012在Windows8上开发内核驱动监视线程创建

 

插入下列代码实现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\n", 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\n", 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\n", 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\n"));  
  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\n"));  
  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("打开驱动设备对象失败!\n");  
    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("收到事件通知!\n");  
    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\n", cbkinfo.ProcessId, cbkinfo.ThreadId);  
    56.                 }   
    57.                 else  
    58.                 {  
    59.                     printf("有线程被终止,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);  
    60.                 }  
    61.                   
    62.                 cbktemp = cbkinfo;  
    63.             }  
    64.         }   
    65.         else  
    66.         {  
    67.             printf("\n获取进程信息失败!\n");  
    68.             break;  
    69.         }  
    70.     }  
    71.       
    72.     ::CloseHandle(hDriver);  
    73.       
    74.     return 0;  
    75. }