用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上开发内核驱动监视进程创建_第1张图片

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

用Visual studio2012在Windows8上开发内核驱动监视进程创建_第2张图片

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

用Visual studio2012在Windows8上开发内核驱动监视进程创建_第3张图片

 

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

用Visual studio2012在Windows8上开发内核驱动监视进程创建_第4张图片

 

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

用Visual studio2012在Windows8上开发内核驱动监视进程创建_第5张图片

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

 

用Visual studio2012在Windows8上开发内核驱动监视进程创建_第6张图片

 

插入下列代码实现内核的进程创建

 

[cpp] view plaincopy
 
  1. #include "ProcMon.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      ProcessEventString;  
  32.     PDEVICE_EXTENSION   deviceExtension;  
  33.     PDEVICE_OBJECT      deviceObject = NULL;  
  34.       
  35.     KdPrint(("[ProcMon] DriverEntry: %wZ\n", RegistryPath));  
  36.       
  37.     //  
  38.     // 创建设备对象  
  39.     //  
  40.     RtlInitUnicodeString(&ntDeviceName, PROCMON_DEVICE_NAME_W);  
  41.       
  42.     Status = IoCreateDevice(  
  43.                         DriverObject,   
  44.                         sizeof(DEVICE_EXTENSION),       // DeviceExtensionSize  
  45.                         &ntDeviceName,                  // DeviceName  
  46.                         FILE_DEVICE_PROCMON,            // DeviceType  
  47.                         0,                              // DeviceCharacteristics  
  48.                         TRUE,                           // Exclusive  
  49.                         &deviceObject                   // [OUT]  
  50.                         );  
  51.   
  52.     if(!NT_SUCCESS(Status))  
  53.     {  
  54.         KdPrint(("[ProcMon] 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, PROCMON_DOS_DEVICE_NAME_W);  
  73.       
  74.     Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);  
  75.       
  76.     if(!NT_SUCCESS(Status))  
  77.     {  
  78.         KdPrint(("[ProcMon] 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]           = ProcmonDispatchCreate;  
  89.     DriverObject->MajorFunction[IRP_MJ_CLOSE]            = ProcmonDispatchClose;  
  90.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]   = ProcmonDispatchDeviceControl;  
  91.     DriverObject->DriverUnload                           = ProcmonUnload;  
  92.       
  93.     //  
  94.     // 保存设备对象指针  
  95.     //  
  96.     g_pDeviceObject = deviceObject;  
  97.   
  98.     //  
  99.     // 创建事件对象与应用层通信  
  100.     //  
  101.     RtlInitUnicodeString(&ProcessEventString, EVENT_NAME);  
  102.       
  103.     deviceExtension->ProcessEvent = IoCreateNotificationEvent(&ProcessEventString, &deviceExtension->hProcessHandle);  
  104.     KeClearEvent(deviceExtension->ProcessEvent);         // 非受信状态  
  105.   
  106.     //  
  107.     // 设置回调例程  
  108.     //  
  109.     Status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);  
  110.   
  111.     return Status;  
  112. }  
  113.   
  114. NTSTATUS  
  115. ProcmonDispatchCreate(  
  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(("[ProcMon] 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. ProcmonDispatchClose(  
  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(("[ProcMon] 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. ProcmonDispatchDeviceControl(  
  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_PROC_MON:  
  177.         {  
  178.             KdPrint(("[ProcMon] IOCTL: 0x%X", ioControlCode));  
  179.   
  180.             if (outBufLength >= sizeof(PCALLBACK_INFO))  
  181.             {  
  182.                 pCallbackInfo->hParentId = deviceExtension->hParentId;  
  183.                 pCallbackInfo->hProcessId = deviceExtension->hProcessId;  
  184.                 pCallbackInfo->bCreate = deviceExtension->bCreate;  
  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(("[ProcMon] 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. ProcmonUnload(  
  212.     IN PDRIVER_OBJECT       DriverObject  
  213. )  
  214. {  
  215.     UNICODE_STRING dosDeviceName;  
  216.       
  217.     //  
  218.     // Free any resources  
  219.     //  
  220.   
  221.     // 卸载回调例程  
  222.     PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);  
  223.       
  224.     //  
  225.     // Delete the symbolic link  
  226.     //  
  227.       
  228.     RtlInitUnicodeString(&dosDeviceName, PROCMON_DOS_DEVICE_NAME_W);  
  229.       
  230.     IoDeleteSymbolicLink(&dosDeviceName);  
  231.       
  232.     //  
  233.     // Delete the device object  
  234.     //  
  235.       
  236.     IoDeleteDevice(DriverObject->DeviceObject);  
  237.       
  238.     KdPrint(("[ProcMon] Unloaded"));  
  239. }  
  240.   
  241. VOID  
  242. ProcessCallback(  
  243.     IN HANDLE               ParentId,           // 父进程ID  
  244.     IN HANDLE               ProcessId,          // 发生事件的进程ID  
  245.     IN BOOLEAN              Create              // 进程是创建还是终止  
  246. )  
  247. {  
  248.     PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;  
  249.   
  250.     deviceExtension->hParentId = ParentId;  
  251.     deviceExtension->hProcessId = ProcessId;  
  252.     deviceExtension->bCreate = Create;  
  253.   
  254.     // 触发事件,通知应用程序  
  255.     KeSetEvent(deviceExtension->ProcessEvent, 0, FALSE);  
  256.     KeClearEvent(deviceExtension->ProcessEvent);  
  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 "\\\\.\\ProcMon"  
    7. //#define SYMBOL_LINK "\\\\.\\slNTProcDrv"  
    8.   
    9. int main()  
    10. {  
    11.     CALLBACK_INFO cbkinfo, cbktemp = {0};  
    12.   
    13.     // 打开驱动设备对象  
    14.     HANDLE hDriver = ::CreateFile(  
    15.                             SYMBOL_LINK,  
    16.                             GENERIC_READ | GENERIC_WRITE,  
    17.                             0,  
    18.                             NULL,  
    19.                             OPEN_EXISTING,  
    20.                             FILE_ATTRIBUTE_NORMAL,  
    21.                             NULL);  
    22.     if (hDriver == INVALID_HANDLE_VALUE)  
    23.     {  
    24.         printf("打开驱动设备对象失败!\n");  
    25.   
    26.         return -1;  
    27.     }  
    28.       
    29.     // 打开内核事件对象  
    30.     HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);  
    31.   
    32.     while (::WaitForSingleObject(hProcessEvent, INFINITE))  
    33.     {  
    34.         DWORD   dwRet;  
    35.         BOOL    bRet;  
    36.   
    37.         bRet = ::DeviceIoControl(  
    38.                             hDriver,  
    39.                             IOCTL_PROC_MON,  
    40.                             NULL,  
    41.                             0,  
    42.                             &cbkinfo,  
    43.                             sizeof(cbkinfo),  
    44.                             &dwRet,  
    45.                             NULL);  
    46.   
    47.         if (bRet)  
    48.         {  
    49.             if (cbkinfo.hParentId != cbktemp.hParentId || \  
    50.                 cbkinfo.hProcessId != cbktemp.hProcessId || \  
    51.                 cbkinfo.bCreate != cbktemp.bCreate)  
    52.             {  
    53.                 if (cbkinfo.bCreate)  
    54.                 {  
    55.                     printf("有进程被创建,PID = %d\n", cbkinfo.hProcessId);  
    56.                 }   
    57.                 else  
    58.                 {  
    59.                     printf("有进程被终止,PID = %d\n", cbkinfo.hProcessId);  
    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. }  

 

 

 

你可能感兴趣的:(windows)