在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,选择驱动编译,

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

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

ring3实现应用层的调用,搞定进程创建的监视

    1. #include "windows.h"
    2. #include "winioctl.h"
    3. #include "stdio.h"
    4. #include "../inc/ioctls.h"
    5. #define SYMBOL_LINK "\\\\.\\ProcMon"
    6. //#define SYMBOL_LINK "\\\\.\\slNTProcDrv"
    7. int main()
    8. {
    9. CALLBACK_INFO cbkinfo, cbktemp = {0};
    10. // 打开驱动设备对象
    11. HANDLE hDriver = ::CreateFile(
    12. SYMBOL_LINK,
    13. GENERIC_READ | GENERIC_WRITE,
    14. 0,
    15. NULL,
    16. OPEN_EXISTING,
    17. FILE_ATTRIBUTE_NORMAL,
    18. NULL);
    19. if (hDriver == INVALID_HANDLE_VALUE)
    20. {
    21. printf("打开驱动设备对象失败!\n");
    22. return -1;
    23. }
    24. // 打开内核事件对象
    25. HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);
    26. while (::WaitForSingleObject(hProcessEvent, INFINITE))
    27. {
    28. DWORD   dwRet;
    29. BOOL    bRet;
    30. bRet = ::DeviceIoControl(
    31. hDriver,
    32. IOCTL_PROC_MON,
    33. NULL,
    34. 0,
    35. &cbkinfo,
    36. sizeof(cbkinfo),
    37. &dwRet,
    38. NULL);
    39. if (bRet)
    40. {
    41. if (cbkinfo.hParentId != cbktemp.hParentId || \
    42. cbkinfo.hProcessId != cbktemp.hProcessId || \
    43. cbkinfo.bCreate != cbktemp.bCreate)
    44. {
    45. if (cbkinfo.bCreate)
    46. {
    47. printf("有进程被创建,PID = %d\n", cbkinfo.hProcessId);
    48. }
    49. else
    50. {
    51. printf("有进程被终止,PID = %d\n", cbkinfo.hProcessId);
    52. }
    53. cbktemp = cbkinfo;
    54. }
    55. }
    56. else
    57. {
    58. printf("\n获取进程信息失败!\n");
    59. break;
    60. }
    61. }
    62. ::CloseHandle(hDriver);
    63. return 0;
    64. }

最新文章

  1. Android—自定义标题栏的实现及遇见的问题解决
  2. Knockout.js随手记(1)
  3. Oracle逻辑备份与恢复
  4. javase基础复习攻略《八》
  5. 利用jsp和servlet,MySQL实现简易报表
  6. 区别assign VS weak,__block VS __weak
  7. centos6.4下没有heartbeat包解决办法
  8. 移动app的一些心得
  9. JavaScript(7)——事件2.0
  10. Oracle数据库概念和一些基本的SQL语句
  11. mkyaffs2image制作根文件系统、使用NFS挂载虚拟机目录(2)
  12. Java复习2.程序内存管理
  13. mybatis一对一 和 一对多 嵌套查询
  14. 前端js 实现文件下载
  15. PythonStudy——高级语言 High-level programming language
  16. Swift 通过运行时获取属性名列表
  17. 阮一峰大神的快排?刚才还在纠结sort()的我!真是个小傻瓜
  18. SQL GROUP BY对多个字段进行分组
  19. MFC宏
  20. 深入__proto__和prototype的区别和联系

热门文章

  1. SQL Server性能调优:资源管理之内存管理篇(上)
  2. MYSQL SSL
  3. Sublime的中文GBK显示乱码的解决方法
  4. 【资料】wod旗帜,纹章
  5. Java Simon--性能瓶颈分析工具
  6. 支持向量机通俗导论(理解SVM的三层境界) by v_JULY_v
  7. MFC 获取DC和输出文字、获取指定区域
  8. 解决win8/8.1系统安装.net framework 3.5出现0x800F0906代码错误
  9. Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
  10. 运行Hadoop的示例程序WordCount-Running Hadoop Example