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

插入下列代码实现ring0层驱动监视创建线程,请见代码分析

  1. #include "ThreadMon.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      ThreadEventString;
  26. PDEVICE_EXTENSION   deviceExtension;
  27. PDEVICE_OBJECT      deviceObject = NULL;
  28. KdPrint(("[ThreadMon] DriverEntry: %wZ\n", RegistryPath));
  29. //
  30. // 创建设备对象
  31. //
  32. RtlInitUnicodeString(&ntDeviceName, THREADMON_DEVICE_NAME_W);
  33. Status = IoCreateDevice(
  34. DriverObject,
  35. sizeof(DEVICE_EXTENSION),       // DeviceExtensionSize
  36. &ntDeviceName,                  // DeviceName
  37. FILE_DEVICE_THREADMON,          // DeviceType
  38. 0,                              // DeviceCharacteristics
  39. TRUE,                           // Exclusive
  40. &deviceObject                   // [OUT]
  41. );
  42. if(!NT_SUCCESS(Status))
  43. {
  44. KdPrint(("[ThreadMon] 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, THREADMON_DOS_DEVICE_NAME_W);
  59. Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
  60. if(!NT_SUCCESS(Status))
  61. {
  62. KdPrint(("[ThreadMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
  63. IoDeleteDevice(deviceObject);
  64. return Status;
  65. }
  66. //
  67. // 分发IRP
  68. //
  69. DriverObject->MajorFunction[IRP_MJ_CREATE]           = ThreadMonDispatchCreate;
  70. DriverObject->MajorFunction[IRP_MJ_CLOSE]            = ThreadMonDispatchClose;
  71. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]   = ThreadMonDispatchDeviceControl;
  72. DriverObject->DriverUnload                           = ThreadMonUnload;
  73. //
  74. // 保存设备对象指针
  75. //
  76. g_pDeviceObject = deviceObject;
  77. //
  78. // 创建事件对象与应用层通信
  79. //
  80. RtlInitUnicodeString(&ThreadEventString, EVENT_NAME);
  81. deviceExtension->ThreadEvent = IoCreateNotificationEvent(&ThreadEventString, &deviceExtension->ThreadHandle);
  82. KeClearEvent(deviceExtension->ThreadEvent);          // 非受信状态
  83. //
  84. // 设置回调例程
  85. //
  86. Status = PsSetCreateThreadNotifyRoutine(ThreadCallback);
  87. return Status;
  88. }
  89. NTSTATUS
  90. ThreadMonDispatchCreate(
  91. IN PDEVICE_OBJECT       DeviceObject,
  92. IN PIRP                 Irp
  93. )
  94. {
  95. NTSTATUS Status = STATUS_SUCCESS;
  96. Irp->IoStatus.Information = 0;
  97. KdPrint(("[ThreadMon] IRP_MJ_CREATE\n"));
  98. Irp->IoStatus.Status = Status;
  99. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  100. return Status;
  101. }
  102. NTSTATUS
  103. ThreadMonDispatchClose(
  104. IN PDEVICE_OBJECT       DeviceObject,
  105. IN PIRP                 Irp
  106. )
  107. {
  108. NTSTATUS Status = STATUS_SUCCESS;
  109. Irp->IoStatus.Information = 0;
  110. KdPrint(("[ThreadMon] IRP_MJ_CLOSE\n"));
  111. Irp->IoStatus.Status = Status;
  112. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  113. return Status;
  114. }
  115. NTSTATUS
  116. ThreadMonDispatchDeviceControl(
  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_THREAD_MON:
  139. {
  140. KdPrint(("[ThreadMon] IOCTL: 0x%X", ioControlCode));
  141. if (outBufLength >= sizeof(PCALLBACK_INFO))
  142. {
  143. pCallbackInfo->ProcessId = deviceExtension->ProcessId;
  144. pCallbackInfo->ThreadId = deviceExtension->ThreadId;
  145. pCallbackInfo->Create = deviceExtension->Create;
  146. Irp->IoStatus.Information = outBufLength;
  147. }
  148. break;
  149. }
  150. default:
  151. {
  152. Status = STATUS_INVALID_PARAMETER;
  153. Irp->IoStatus.Information = 0;
  154. KdPrint(("[ThreadMon] 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. ThreadMonUnload(
  166. IN PDRIVER_OBJECT       DriverObject
  167. )
  168. {
  169. UNICODE_STRING dosDeviceName;
  170. //
  171. // Free any resources
  172. //
  173. // 卸载回调例程
  174. PsRemoveCreateThreadNotifyRoutine(ThreadCallback);
  175. //
  176. // Delete the symbolic link
  177. //
  178. RtlInitUnicodeString(&dosDeviceName, THREADMON_DEVICE_NAME_W);
  179. IoDeleteSymbolicLink(&dosDeviceName);
  180. //
  181. // Delete the device object
  182. //
  183. IoDeleteDevice(DriverObject->DeviceObject);
  184. KdPrint(("[ThreadMon] Unloaded"));
  185. }
  186. VOID
  187. ThreadCallback(
  188. IN HANDLE               ProcessId,          // 进程ID
  189. IN HANDLE               ThreadId,           // 线程ID
  190. IN BOOLEAN              Create              // 创建还是终止
  191. )
  192. {
  193. PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
  194. deviceExtension->ProcessId = ProcessId;
  195. deviceExtension->ThreadId = ThreadId;
  196. deviceExtension->Create = Create;
  197. // 触发事件,通知应用程序
  198. KeSetEvent(deviceExtension->ThreadEvent, 0, FALSE);
  199. KeClearEvent(deviceExtension->ThreadEvent);
  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 "\\\\.\\ThreadMon"
    6. int main()
    7. {
    8. CALLBACK_INFO cbkinfo, cbktemp = {0};
    9. // 打开驱动设备对象
    10. HANDLE hDriver = ::CreateFile(
    11. SYMBOL_LINK,
    12. GENERIC_READ | GENERIC_WRITE,
    13. 0,
    14. NULL,
    15. OPEN_EXISTING,
    16. FILE_ATTRIBUTE_NORMAL,
    17. NULL);
    18. if (hDriver == INVALID_HANDLE_VALUE)
    19. {
    20. printf("打开驱动设备对象失败!\n");
    21. return -1;
    22. }
    23. // 打开内核事件对象
    24. HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);
    25. while (::WaitForSingleObject(hProcessEvent, INFINITE))
    26. {
    27. DWORD   dwRet;
    28. BOOL    bRet;
    29. //      printf("收到事件通知!\n");
    30. bRet = ::DeviceIoControl(
    31. hDriver,
    32. IOCTL_THREAD_MON,
    33. NULL,
    34. 0,
    35. &cbkinfo,
    36. sizeof(cbkinfo),
    37. &dwRet,
    38. NULL);
    39. if (bRet)
    40. {
    41. if (cbkinfo.ProcessId != cbktemp.ProcessId || \
    42. cbkinfo.ThreadId != cbktemp.ThreadId || \
    43. cbkinfo.Create != cbktemp.Create)
    44. {
    45. if (cbkinfo.Create)
    46. {
    47. printf("有线程被创建,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
    48. }
    49. else
    50. {
    51. printf("有线程被终止,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
    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. 反汇编调试内核驱动 Oops提示【转】

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

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

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

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

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

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

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

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

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

  8. 在Visual Studio 2013 上开发Node.js程序

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

  9. Visual Studio上开发Python六大功能

    Visual Studio上开发Python六大功能 一.整合 Python 直译器 (Interpreter) & 互动视窗 (Interactive) Visual Studio 高度整合 ...

随机推荐

  1. Virtual Treeview - Paint cycles and stages

    The most complex process in Virtual Treeview is without doubts its painting. Read here what stages V ...

  2. TRF7970A IC Communication Interface

    General Introduction The communication interface to the reader can be configured in two ways: with a ...

  3. Digital Adjustment of DC-DC Converter Output Voltage 电阻选择

  4. GridView Item 大小可能不一样,如何保持同一行的Item 高度大小相同,且GridView高度自适应!

    昨天用到GridView,但是遇到几个问题,就是GridView默认的item其实大小是一致的,但是我们经常会遇到item大小不同,系统默认会留白的问题,很头疼!如下图这样的:      就会造成,右 ...

  5. 静态资源(StaticResource)和动态资源(DynamicResource)

    静态资源(StaticResource)和动态资源(DynamicResource) 资源可以作为静态资源或动态资源进行引用.这是通过使用 StaticResource 标记扩展或 DynamicRe ...

  6. Ext Connection

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  7. sql 循环插入某一条数据

    declare @i int set @i=1 while @i<(10000)begin INSERT INTO [Table]( [IDi] ,[IDo] ,[Synci] ) ( SELE ...

  8. idea的一些快捷键

    查找文本的出现位置就用Ctrl+F/Ctrl+Shift+F在当前窗口或全工程中查找,再配合F3/Shift+F3前后移动到下一匹配处Intellij的Ctrl+N/Ctrl+Shift+N可以打开类 ...

  9. C/C++下scanf的%匹配以及过滤字符串问题

    最近在写一个测试的小程序,由于用到了sscanf函数对字符串进行标准读入,而sscanf在很多方面都与scanf比较相像,于是对scanf进行了一番测试,遇到了一系列基础性的问题,恶补基础的同时也体现 ...

  10. session劫持技术

    目录: 0×00 应用程序认证设计背景0×01 常规攻击思路及缺陷0×02 利用应用程序设计缺陷进行Session劫持的攻击原理0×03 Session劫持的大致思路及意义0×04 如何防御这种攻击 ...