您的位置:首页 > 其它

用Visual studio2012在Windows8上开发内核驱动监视进程创建

2013-09-24 11:26 375 查看
在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,选择驱动编译,



插入下列代码实现内核的进程创建

[cpp] view plaincopy

#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实现应用层的调用,搞定进程创建的监视

[cpp] view plaincopy

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: