在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. POJ 1293 - Duty Free Shop 01背包记录所选物品

    裸的01背包.dp[x]只要是bool型记录当前空间是否可用.. 而为了找到用了哪些物品..dp[x]设置为int型..进行记录.. Program: #include<iostream> ...

  2. 重装Windows系统后,Mysql的恢复

    在原地直接恢复MySQL的自动启动的数据库服务,操作如下. (1)环境变量里配置一下Mysql的bin目录 (2)管理员方式启动cmd,运行命令mysqld –install (3)启动Mysql服务 ...

  3. CentOS6.5使用yum命令方便快捷安装Nginx与卸载

    原文:https://my.oschina.net/ramboo/blog/223408 当然,首先要求是可以联网的CentOS系统,因为yum安装需要互联网连接. 卸载命令:yum remove n ...

  4. SLF4J和Logback日志框架详解

    SLF4J和Logback日志框架详解 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 本文讲述SLF4J和Logback日志框架.   SLF4J是一套 ...

  5. 3月题外:关于JS实现图片缩略图效果的一个小问题

    由于3月可能要结束实习,所以应该不会有特别固定的主题,另外我会在月初陆续补上上个月的番外篇Projection和TMS,作为介绍性的内容对矢量切片部分进行补充,剩下时间不定期写一些杂烩. 最近两天在做 ...

  6. Git使用教程(转载)

    Git使用教程 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是 ...

  7. 深度学习Deep learning

    In the last chapter we learned that deep neural networks are often much harder to train than shallow ...

  8. Glide Picasso Fresco UIL 图片框架 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. 【帧动画总结】AnimationDrawable Frame

    Drawable Animation 开发者文档 位置:/sdk/docs/guide/topics/graphics/drawable-animation.html Drawable animati ...

  10. Webview 支持文件上传

    默认情况下情况下,在一个带有input tpye=file标签的Html页面,使用Android的WebView是不能够支持上传文件的(在iOS和微信上完全正常工作).而这个,也是在我们的前端工程师告 ...