用Visual studio2012在Windows8上开发内核驱动监视线程创建
在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层驱动监视创建线程,请见代码分析
- #include "ThreadMon.h"
- #include "../inc/ioctls.h"
- //
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //
- // 全局变量
- //
- PDEVICE_OBJECT g_pDeviceObject;
- //
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //
- // 函数实现
- //
- NTSTATUS
- DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- UNICODE_STRING ntDeviceName;
- UNICODE_STRING dosDeviceName;
- UNICODE_STRING ThreadEventString;
- PDEVICE_EXTENSION deviceExtension;
- PDEVICE_OBJECT deviceObject = NULL;
- KdPrint(("[ThreadMon] DriverEntry: %wZ\n", RegistryPath));
- //
- // 创建设备对象
- //
- RtlInitUnicodeString(&ntDeviceName, THREADMON_DEVICE_NAME_W);
- Status = IoCreateDevice(
- DriverObject,
- sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
- &ntDeviceName, // DeviceName
- FILE_DEVICE_THREADMON, // DeviceType
- 0, // DeviceCharacteristics
- TRUE, // Exclusive
- &deviceObject // [OUT]
- );
- if(!NT_SUCCESS(Status))
- {
- KdPrint(("[ThreadMon] IoCreateDevice Error Code = 0x%X\n", Status));
- return Status;
- }
- //
- // 设置扩展结构
- //
- deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
- //
- // Set up synchronization objects, state info,, etc.
- //
- deviceObject->Flags |= DO_BUFFERED_IO;
- //
- // 创建符号链接
- //
- RtlInitUnicodeString(&dosDeviceName, THREADMON_DOS_DEVICE_NAME_W);
- Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
- if(!NT_SUCCESS(Status))
- {
- KdPrint(("[ThreadMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
- IoDeleteDevice(deviceObject);
- return Status;
- }
- //
- // 分发IRP
- //
- DriverObject->MajorFunction[IRP_MJ_CREATE] = ThreadMonDispatchCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = ThreadMonDispatchClose;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ThreadMonDispatchDeviceControl;
- DriverObject->DriverUnload = ThreadMonUnload;
- //
- // 保存设备对象指针
- //
- g_pDeviceObject = deviceObject;
- //
- // 创建事件对象与应用层通信
- //
- RtlInitUnicodeString(&ThreadEventString, EVENT_NAME);
- deviceExtension->ThreadEvent = IoCreateNotificationEvent(&ThreadEventString, &deviceExtension->ThreadHandle);
- KeClearEvent(deviceExtension->ThreadEvent); // 非受信状态
- //
- // 设置回调例程
- //
- Status = PsSetCreateThreadNotifyRoutine(ThreadCallback);
- return Status;
- }
- NTSTATUS
- ThreadMonDispatchCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ThreadMon] IRP_MJ_CREATE\n"));
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- NTSTATUS
- ThreadMonDispatchClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ThreadMon] IRP_MJ_CLOSE\n"));
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- NTSTATUS
- ThreadMonDispatchDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- PIO_STACK_LOCATION irpStack;
- PDEVICE_EXTENSION deviceExtension;
- ULONG inBufLength, outBufLength;
- ULONG ioControlCode;
- PCALLBACK_INFO pCallbackInfo;
- // 获取当前设备栈
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- // 提取信息
- pCallbackInfo = Irp->AssociatedIrp.SystemBuffer;
- inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
- outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
- ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
- // 处理不同的IOCTL
- switch (ioControlCode)
- {
- case IOCTL_THREAD_MON:
- {
- KdPrint(("[ThreadMon] IOCTL: 0x%X", ioControlCode));
- if (outBufLength >= sizeof(PCALLBACK_INFO))
- {
- pCallbackInfo->ProcessId = deviceExtension->ProcessId;
- pCallbackInfo->ThreadId = deviceExtension->ThreadId;
- pCallbackInfo->Create = deviceExtension->Create;
- Irp->IoStatus.Information = outBufLength;
- }
- break;
- }
- default:
- {
- Status = STATUS_INVALID_PARAMETER;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ThreadMon] Unknown IOCTL: 0x%X (%04X,%04X)", \
- ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), \
- IoGetFunctionCodeFromCtlCode(ioControlCode)));
- break;
- }
- }
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- VOID
- ThreadMonUnload(
- IN PDRIVER_OBJECT DriverObject
- )
- {
- UNICODE_STRING dosDeviceName;
- //
- // Free any resources
- //
- // 卸载回调例程
- PsRemoveCreateThreadNotifyRoutine(ThreadCallback);
- //
- // Delete the symbolic link
- //
- RtlInitUnicodeString(&dosDeviceName, THREADMON_DEVICE_NAME_W);
- IoDeleteSymbolicLink(&dosDeviceName);
- //
- // Delete the device object
- //
- IoDeleteDevice(DriverObject->DeviceObject);
- KdPrint(("[ThreadMon] Unloaded"));
- }
- VOID
- ThreadCallback(
- IN HANDLE ProcessId, // 进程ID
- IN HANDLE ThreadId, // 线程ID
- IN BOOLEAN Create // 创建还是终止
- )
- {
- PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
- deviceExtension->ProcessId = ProcessId;
- deviceExtension->ThreadId = ThreadId;
- deviceExtension->Create = Create;
- // 触发事件,通知应用程序
- KeSetEvent(deviceExtension->ThreadEvent, 0, FALSE);
- KeClearEvent(deviceExtension->ThreadEvent);
- }
- //
- //////////////////////////////////////////////////////////////////////////
ring3层调用代码如下
- #include "windows.h"
- #include "winioctl.h"
- #include "stdio.h"
- #include "../inc/ioctls.h"
- #define SYMBOL_LINK "\\\\.\\ThreadMon"
- int main()
- {
- CALLBACK_INFO cbkinfo, cbktemp = {0};
- // 打开驱动设备对象
- HANDLE hDriver = ::CreateFile(
- SYMBOL_LINK,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDriver == INVALID_HANDLE_VALUE)
- {
- printf("打开驱动设备对象失败!\n");
- return -1;
- }
- // 打开内核事件对象
- HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);
- while (::WaitForSingleObject(hProcessEvent, INFINITE))
- {
- DWORD dwRet;
- BOOL bRet;
- // printf("收到事件通知!\n");
- bRet = ::DeviceIoControl(
- hDriver,
- IOCTL_THREAD_MON,
- NULL,
- 0,
- &cbkinfo,
- sizeof(cbkinfo),
- &dwRet,
- NULL);
- if (bRet)
- {
- if (cbkinfo.ProcessId != cbktemp.ProcessId || \
- cbkinfo.ThreadId != cbktemp.ThreadId || \
- cbkinfo.Create != cbktemp.Create)
- {
- if (cbkinfo.Create)
- {
- printf("有线程被创建,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
- }
- else
- {
- printf("有线程被终止,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
- }
- cbktemp = cbkinfo;
- }
- }
- else
- {
- printf("\n获取进程信息失败!\n");
- break;
- }
- }
- ::CloseHandle(hDriver);
- return 0;
- }
用Visual studio2012在Windows8上开发内核驱动监视线程创建的更多相关文章
- 用Visual studio2012在Windows8上开发内核驱动监视进程创建
在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...
- 用Visual studio11在Windows8上开发驱动实现注册表监控和过滤
在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...
- 反汇编调试内核驱动 Oops提示【转】
以下部分内容转自:https://blog.csdn.net/jiatingqiang/article/details/7481497 反汇编调试内核驱动 arm-none-linux-gnueabi ...
- 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure
[题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...
- 在Visual Studio上开发Node.js程序
[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...
- Smobiler 4.4 更新预告 Part 2(Smobiler能让你在Visual Studio上开发APP)
Hello Everybody,在Smobiler 4.4中,也为大家带来了新增功能和插件(重点,敲黑板). 新增功能: 1, 企业认证用户可设置路由(即客户端可根据不同的IP地址访问不同的服务器组) ...
- Smobiler 4.4 更新预告 Part 1(Smobiler能让你在Visual Studio上开发APP)
在4.4版本中,大家对产品优化的一些建议和意见进行了相应的优化和修复,同时,还新增了一些令人激动的功能和插件. 下面先为大家介绍4.4版本中Smobiler的优化和修复: 优化 1, PageView ...
- 在Visual Studio 2013 上开发Node.js程序
[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...
- Visual Studio上开发Python六大功能
Visual Studio上开发Python六大功能 一.整合 Python 直译器 (Interpreter) & 互动视窗 (Interactive) Visual Studio 高度整合 ...
随机推荐
- JavaScript面向对象编程指南(第2版)》读书笔记
一.对象 1.1 获取属性值的方式 water = { down: false } console.log(water.down) // false console.log(water['down'] ...
- iptables学习与研究(使用LOG记录失败日志)
原文地址: http://blog.csdn.net/fafa211/article/details/2307581 通常情况下,iptables的默认政策为DROP,不匹配的数据包将被直接丢弃.但在 ...
- cocos2d-x 中文乱码问题解决方案
在windows环境下使用visual studio 开发cocos2d-x,由于visual studio 默认编码为GBK 格式,而cocos2d-x引擎默认编码为UTF-8, 如果有用到中文,在 ...
- EF DBContext中DbSet中Hashset添加对象后,DataGrid UI没有刷新的问题
使用EF4/5添加数据库视图生成DBContext,如果数据表/对象之间有M-N对应关系,EF对自动添加引用类集合,是Hashset类型.由于不是ObservableCellection类型,在引用类 ...
- HSSFWorkbook 创建Excel文件
1.项目代码实例 @Override public OutputStream exportAucLotData(String id, String password, OutputStream out ...
- C++中函数调用时的三种参数传递方式详解
在C++中,参数传递的方式是“实虚结合”. 按值传递(pass by value) 地址传递(pass by pointer) 引用传递(pass by reference) 按值传递的过程为:首先计 ...
- JQuery中简约的进度条插件推荐
JQuery Progress Bar是基于JQuery开发的进度条插件,秉承了JQuery的简约哲学.不仅容易使用,而且可以轻松定制外观.对于使用了JQuery框架的项目来说,需要使用进度条控件时这 ...
- .NET中的六个重要概念
内容导读 概述 当你声明一个变量背后发生了什么? 堆和栈 值类型和引用类型 哪些是值类型,哪些是引用类型? 装箱和拆箱 装箱和拆箱的性能问题 一.概述 本文会阐述六个重要的概念:堆.栈.值类型.引用类 ...
- C#中 父类与子类相互强制转换之实验
MSDN是很好,不过,有时需要自己动手实践一下,才能更好的理解和记住一些东西. 我看过很多技术文章,结果到用时,仍然是下不了手.似是而非的. 像上次写的“四舍六入五成双/四舍六入五留双/四舍六入五单双 ...
- [Python爬虫] 之三:Selenium 调用IEDriverServer 抓取数据
接着上一遍,在用Selenium+phantomjs 抓取数据过程中发现,有时候抓取不到,所以又测试了用Selenium+浏览器驱动的方式:具体代码如下: #coding=utf-8import os ...