影者东升 发表于 2021-7-17 10:05:22

用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
https://img-my.csdn.net/uploads/201303/18/1363588183_8515.png

2.看见满目的驱动开发模板
https://img-my.csdn.net/uploads/201203/25/1332672925_8904.png
3.选择一个驱动模式,有内核模式与用户模式两种的驱动
https://img-my.csdn.net/uploads/201203/25/1332672975_9117.png
4.创建一个驱动程序,KMDF DriverMVP
https://img-my.csdn.net/uploads/201203/25/1332673034_9730.png
5.我们选择的是内核模式的驱动程序,下面是创建成功后的界面,分别是驱动程序本身,与驱动安装包
https://img-my.csdn.net/uploads/201203/25/1332673125_7838.png
6.按下F5,选择驱动编译,
https://img-my.csdn.net/uploads/201203/25/1332673197_9192.png


插入下列代码实现内核的进程创建
#include "ProcMon.h"
#include "../inc/ioctls.h"

//
//

//
//
// 全局变量
//

PDEVICE_OBJECTg_pDeviceObject;

//
//

//
//
// 函数实现
//

NTSTATUS
DriverEntry(
IN PDRIVER_OBJECTDriverObject,
IN PUNICODE_STRINGRegistryPath
)
{
NTSTATUSStatus = STATUS_SUCCESS;   
UNICODE_STRINGntDeviceName;
UNICODE_STRINGdosDeviceName;
UNICODE_STRINGProcessEventString;
PDEVICE_EXTENSIONdeviceExtension;
PDEVICE_OBJECTdeviceObject = NULL;

KdPrint((" 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//
);

if(!NT_SUCCESS(Status))
{
KdPrint((" 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((" IoCreateSymbolicLink Error Code = 0x%X\n", Status));

IoDeleteDevice(deviceObject);

return Status;
}

//
// 分发IRP
//
DriverObject->MajorFunction= ProcmonDispatchCreate;
DriverObject->MajorFunction= ProcmonDispatchClose;
DriverObject->MajorFunction= 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_OBJECTDeviceObject,
IN PIRPIrp
)
{
NTSTATUS Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

KdPrint((" IRP_MJ_CREATE\n"));

Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Status;
}

NTSTATUS
ProcmonDispatchClose(
IN PDEVICE_OBJECTDeviceObject,
IN PIRPIrp
)
{
NTSTATUS Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

KdPrint((" IRP_MJ_CLOSE\n"));

Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Status;
}

NTSTATUS
ProcmonDispatchDeviceControl(
IN PDEVICE_OBJECTDeviceObject,
IN PIRPIrp
)
{
NTSTATUSStatus = STATUS_SUCCESS;
PIO_STACK_LOCATIONirpStack;
PDEVICE_EXTENSIONdeviceExtension;
ULONGinBufLength, outBufLength;
ULONGioControlCode;
PCALLBACK_INFOpCallbackInfo;

// 获取当前设备栈
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((" 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((" 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_OBJECTDriverObject
)
{
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((" Unloaded"));
}

VOID
ProcessCallback(
IN HANDLEParentId,// 父进程ID
IN HANDLEProcessId,// 发生事件的进程ID
IN BOOLEANCreate// 进程是创建还是终止
)
{
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))
{
DWORDdwRet;
BOOLbRet;

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




文档来源:51CTO技术博客https://blog.51cto.com/u_9634496/3115122
页: [1]
查看完整版本: 用Visual studio2012在Windows8上开发内核驱动监视进程创建