用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,选择驱动编译,
插入下列代码实现内核的进程创建
- #include "ProcMon.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 ProcessEventString;
- PDEVICE_EXTENSION deviceExtension;
- PDEVICE_OBJECT deviceObject = NULL;
- KdPrint(("[ProcMon] DriverEntry: %wZ\n", RegistryPath));
- //
- // 创建设备对象
- //
- RtlInitUnicodeString(&ntDeviceName, PROCMON_DEVICE_NAME_W);
- Status = IoCreateDevice(
- DriverObject,
- sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
- &ntDeviceName, // DeviceName
- FILE_DEVICE_PROCMON, // DeviceType
- 0, // DeviceCharacteristics
- TRUE, // Exclusive
- &deviceObject // [OUT]
- );
- if(!NT_SUCCESS(Status))
- {
- KdPrint(("[ProcMon] 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, PROCMON_DOS_DEVICE_NAME_W);
- Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
- if(!NT_SUCCESS(Status))
- {
- KdPrint(("[ProcMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
- IoDeleteDevice(deviceObject);
- return Status;
- }
- //
- // 分发IRP
- //
- DriverObject->MajorFunction[IRP_MJ_CREATE] = ProcmonDispatchCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = ProcmonDispatchClose;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ProcmonDispatchDeviceControl;
- DriverObject->DriverUnload = ProcmonUnload;
- //
- // 保存设备对象指针
- //
- g_pDeviceObject = deviceObject;
- //
- // 创建事件对象与应用层通信
- //
- RtlInitUnicodeString(&ProcessEventString, EVENT_NAME);
- deviceExtension->ProcessEvent = IoCreateNotificationEvent(&ProcessEventString, &deviceExtension->hProcessHandle);
- KeClearEvent(deviceExtension->ProcessEvent); // 非受信状态
- //
- // 设置回调例程
- //
- Status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
- return Status;
- }
- NTSTATUS
- ProcmonDispatchCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ProcMon] IRP_MJ_CREATE\n"));
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- NTSTATUS
- ProcmonDispatchClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- NTSTATUS Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ProcMon] IRP_MJ_CLOSE\n"));
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- NTSTATUS
- ProcmonDispatchDeviceControl(
- 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_PROC_MON:
- {
- KdPrint(("[ProcMon] IOCTL: 0x%X", ioControlCode));
- if (outBufLength >= sizeof(PCALLBACK_INFO))
- {
- pCallbackInfo->hParentId = deviceExtension->hParentId;
- pCallbackInfo->hProcessId = deviceExtension->hProcessId;
- pCallbackInfo->bCreate = deviceExtension->bCreate;
- Irp->IoStatus.Information = outBufLength;
- }
- break;
- }
- default:
- {
- Status = STATUS_INVALID_PARAMETER;
- Irp->IoStatus.Information = 0;
- KdPrint(("[ProcMon] 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
- ProcmonUnload(
- IN PDRIVER_OBJECT DriverObject
- )
- {
- UNICODE_STRING dosDeviceName;
- //
- // Free any resources
- //
- // 卸载回调例程
- PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
- //
- // Delete the symbolic link
- //
- RtlInitUnicodeString(&dosDeviceName, PROCMON_DOS_DEVICE_NAME_W);
- IoDeleteSymbolicLink(&dosDeviceName);
- //
- // Delete the device object
- //
- IoDeleteDevice(DriverObject->DeviceObject);
- KdPrint(("[ProcMon] Unloaded"));
- }
- VOID
- ProcessCallback(
- IN HANDLE ParentId, // 父进程ID
- IN HANDLE ProcessId, // 发生事件的进程ID
- IN BOOLEAN Create // 进程是创建还是终止
- )
- {
- PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
- deviceExtension->hParentId = ParentId;
- deviceExtension->hProcessId = ProcessId;
- deviceExtension->bCreate = Create;
- // 触发事件,通知应用程序
- KeSetEvent(deviceExtension->ProcessEvent, 0, FALSE);
- KeClearEvent(deviceExtension->ProcessEvent);
- }
- //
- //////////////////////////////////////////////////////////////////////////
ring3实现应用层的调用,搞定进程创建的监视
- #include "windows.h"
- #include "winioctl.h"
- #include "stdio.h"
- #include "../inc/ioctls.h"
- #define SYMBOL_LINK "\\\\.\\ProcMon"
- //#define SYMBOL_LINK "\\\\.\\slNTProcDrv"
- 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;
- bRet = ::DeviceIoControl(
- hDriver,
- IOCTL_PROC_MON,
- NULL,
- 0,
- &cbkinfo,
- sizeof(cbkinfo),
- &dwRet,
- NULL);
- if (bRet)
- {
- if (cbkinfo.hParentId != cbktemp.hParentId || \
- cbkinfo.hProcessId != cbktemp.hProcessId || \
- cbkinfo.bCreate != cbktemp.bCreate)
- {
- if (cbkinfo.bCreate)
- {
- printf("有进程被创建,PID = %d\n", cbkinfo.hProcessId);
- }
- else
- {
- printf("有进程被终止,PID = %d\n", cbkinfo.hProcessId);
- }
- cbktemp = cbkinfo;
- }
- }
- else
- {
- printf("\n获取进程信息失败!\n");
- break;
- }
- }
- ::CloseHandle(hDriver);
- return 0;
- }
最新文章
- Android—自定义标题栏的实现及遇见的问题解决
- Knockout.js随手记(1)
- Oracle逻辑备份与恢复
- javase基础复习攻略《八》
- 利用jsp和servlet,MySQL实现简易报表
- 区别assign VS weak,__block VS __weak
- centos6.4下没有heartbeat包解决办法
- 移动app的一些心得
- JavaScript(7)——事件2.0
- Oracle数据库概念和一些基本的SQL语句
- mkyaffs2image制作根文件系统、使用NFS挂载虚拟机目录(2)
- Java复习2.程序内存管理
- mybatis一对一 和 一对多 嵌套查询
- 前端js 实现文件下载
- PythonStudy——高级语言 High-level programming language
- Swift 通过运行时获取属性名列表
- 阮一峰大神的快排?刚才还在纠结sort()的我!真是个小傻瓜
- SQL GROUP BY对多个字段进行分组
- MFC宏
- 深入__proto__和prototype的区别和联系
热门文章
- SQL Server性能调优:资源管理之内存管理篇(上)
- MYSQL SSL
- Sublime的中文GBK显示乱码的解决方法
- 【资料】wod旗帜,纹章
- Java Simon--性能瓶颈分析工具
- 支持向量机通俗导论(理解SVM的三层境界) by v_JULY_v
- MFC 获取DC和输出文字、获取指定区域
- 解决win8/8.1系统安装.net framework 3.5出现0x800F0906代码错误
- Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
- 运行Hadoop的示例程序WordCount-Running Hadoop Example