用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\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. }  

 

 

 

posted @ 2013-09-24 11:28  huhu0013  阅读(1134)  评论(0编辑  收藏  举报