在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. }

用Visual studio2012在Windows8上开发内核驱动监视进程创建的更多相关文章

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

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...

  2. 用Visual studio11在Windows8上开发驱动实现注册表监控和过滤

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...

  3. linux内核学习之六 进程创建过程学习

    一 关于linux进程概念的补充 关于进程的基本概念这里不多说,把自己的学习所得作一些补充: 1. 在linux内核中,系统最多可以有64个进程同时存在. 2.linux进程包含的关键要素:一段可执行 ...

  4. 反汇编调试内核驱动 Oops提示【转】

    以下部分内容转自:https://blog.csdn.net/jiatingqiang/article/details/7481497 反汇编调试内核驱动 arm-none-linux-gnueabi ...

  5. linux 用户态和内核态以及进程上下文、中断上下文 内核空间用户空间理解

    1.特权级         Intel x86架构的cpu一共有0-4四个特权级,0级最高,3级最低,ARM架构也有不同的特权级,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查.硬件已经提 ...

  6. 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

    [题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...

  7. 在Visual Studio上开发Node.js程序

    [题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...

  8. Smobiler 4.4 更新预告 Part 2(Smobiler能让你在Visual Studio上开发APP)

    Hello Everybody,在Smobiler 4.4中,也为大家带来了新增功能和插件(重点,敲黑板). 新增功能: 1, 企业认证用户可设置路由(即客户端可根据不同的IP地址访问不同的服务器组) ...

  9. Smobiler 4.4 更新预告 Part 1(Smobiler能让你在Visual Studio上开发APP)

    在4.4版本中,大家对产品优化的一些建议和意见进行了相应的优化和修复,同时,还新增了一些令人激动的功能和插件. 下面先为大家介绍4.4版本中Smobiler的优化和修复: 优化 1, PageView ...

随机推荐

  1. 原生JavaScript---正则表达式

    JavaScript 中正则的性能比想象中的低很多.能用字符串方法搞定的,尽量别用正则.------玉伯 抛开性能不谈,一起来看看正则表达式怎么用吧! 先看看JavaScript正则表达式中一些特殊字 ...

  2. Intent 的Flag属性(Activity在栈位置的主宰者)

    Intent 的Flag属性可用来控制Activity在栈中的排列位置,本文列举了常见的Flag. 例--(以无动画方式启动ActivityB): Intent intent=new Intent(A ...

  3. jsp:include 动作指令 与 include 指令

    include动作指令可以在JSP页面中动态包含一个文件,这与include指令不同,前者可以动态包含一个文件,文件的内容可以是静态的文件也可以是动态的脚本,而且当包含的动态文件被修改的时候JSP引擎 ...

  4. Unity3D如何减少安装包大小

    译官方文档:http://docs.unity3d.com/Manual/ReducingFilesize.html PDF文档:http://www.rukawa.cn/Uploads/Attach ...

  5. 如何从MATLAB里面保存出分辨率高的图形

    MATLAB堪称科技工作者的倚天屠龙,其科学计算,简洁的编程风格,友好的图形界面等等,都使得它颇受欢迎.MATLAB作图相当简单,而且美观,但是,缺点是分辨率低,一直没有发现,直到最近一期刊编辑告诉我 ...

  6. windows安装dcm4chee 出错 check file system group LOSSY_STORAGE for deletion

    错误情景: 解决方法: 更改服务的监听端口(参考DICOM:Ubuntu14环境下安装dcm4chee+oviyam2.1)

  7. vue中的css作用域、vue中的scoped坑点

    一.css作用域 之前一直很困扰css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的.导致在css中需要加上对应模块的html的id/class ...

  8. 【3】利用Word模板生成文档的总结

    阅读目录 Word二次开发概况 使用DsoFramer进行开发 使用Interop进行开发 打开.关闭和写入操作 批量替换文本 遍历段落替换文本 查找后逐个替换文本 结论 在各类应用系统开发中,和Wo ...

  9. [Functional Programming] Capture Side Effects in a Task / Async

    We examine the data structure Task, see some constructors, familiar methods, and finally how it capt ...

  10. 【Python】nvshens按目录批量下载图片爬虫1.00(单线程版)

    # nvshens按目录批量下载图片爬虫1.00(单线程版) from bs4 import BeautifulSoup import requests import datetime import ...