在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. OpenCV2马拉松第12圈——直方图比較

    收入囊中 使用4种不同的方法进行直方图比較 葵花宝典 要比較两个直方图, 首先必需要选择一个衡量直方图相似度的对照标准.也就是先说明要在哪个方面做对照. 我们能够想出非常多办法,OpenCV採用了下面 ...

  2. Retrieving ST-Link/V2 Firmware from Update Utility

    http://www.taylorkillian.com/2013/01/retrieving-st-linkv2-firmware-from.html http://forum.easyelectr ...

  3. sessionid与cookie

    转自:http://smiky.iteye.com/blog/649164 发现自己真的是很笨,过去一直用jsp,从来不用怕心用户信息放在session里面会找不到,现在不用jsp,前台全用html, ...

  4. AC-PC线(前联合-后联合线)

    下面利用一张大脑矢状面(侧视图)来描述ac-pc的空间位置关系.前联合用红色点表示,后联合用黄色表示. 在Talairach 模板的官方文档中,AC-PC线从前联合AC的表面出发,延伸到后联合PC的中 ...

  5. 解决sqoop报错Invalid number; item = ITEM_UNICODE

    报错栈: java.sql.SQLException: Invalid number; item = ITEM_UNICODE at com.intersys.jdbc.SysList.getInt( ...

  6. 《Objective-C开发经典教程》

    <Objective-C开发经典教程> 基本信息 原书名:Beginning Objective-C 原出版社: Apress 作者: (美)James Dovey    Ash Furr ...

  7. Thymeleaf th:action

    th:attr 任何属性值 <form action="subscribe.html" th:attr="action=@{/subscribe}"> ...

  8. django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes');

    在使用utf8mb4字符集的情况下,如果列存在索引,那么varchar的最大长度是191 数据库版本: 在使用utf8字符集的情况下,如果列存在索引,那么varchar的最大长度是255. 在大字段上 ...

  9. 权限项目总结(四) shiro 授权

    概述 Authorization(授权):不难理解,授权就是用来控制当前訪问用户在訪问系统资源权限. 这个词也做证书的解释,从证书这个角度来讲,推断是否拥有对资源訪问的权限时.当前用户须要提供证书. ...

  10. java中 HashMap和Hashtable,list、set和map 的区别

    摘自: http://blog.chinaunix.net/uid-7374279-id-2057584.html HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Ma ...