?? procdrv.cpp
字號(hào):
//////////////////////////////////////////////////
// ProcDrv.cpp文件
extern "C"
{
#include <ntddk.h>
}
#include <devioctl.h>
#include "ProcDrv.h"
// 自定義函數(shù)的聲明
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
void DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate);
// 驅(qū)動(dòng)內(nèi)部名稱、符號(hào)連接名稱、事件對(duì)象名稱
#define DEVICE_NAME L"\\Device\\devNTProcDrv"
#define LINK_NAME L"\\DosDevices\\slNTProcDrv"
#define EVENT_NAME L"\\BaseNamedObjects\\NTProcDrvProcessEvent"
typedef struct _DEVICE_EXTENSION // 設(shè)備對(duì)象的私有存儲(chǔ)
{
HANDLE hProcessHandle; // 事件對(duì)象句柄
PKEVENT ProcessEvent; // 用戶和內(nèi)核通信的事件對(duì)象指針
HANDLE hPParentId; // 在回調(diào)函數(shù)中保存進(jìn)程信息,當(dāng)用戶程序請求時(shí),傳遞過去
HANDLE hPProcessId;
BOOLEAN bPCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
PDEVICE_OBJECT g_pDeviceObject;
// 驅(qū)動(dòng)程序加載時(shí)調(diào)用DriverEntry例程
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
// 初始化各個(gè)派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
// 創(chuàng)建、初始化設(shè)備對(duì)象
// 設(shè)備名稱
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
// 創(chuàng)建設(shè)備對(duì)象
PDEVICE_OBJECT pDevObj;
status = IoCreateDevice(pDriverObj,
sizeof(DEVICE_EXTENSION), // 為設(shè)備擴(kuò)展結(jié)構(gòu)申請空間
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status))
{
return status;
}
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 創(chuàng)建符號(hào)連接名稱
// 符號(hào)連接名稱
UNICODE_STRING ustrLinkName;
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
// 創(chuàng)建關(guān)聯(lián)
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
// 保存到設(shè)備對(duì)象的指針,下面在進(jìn)程回調(diào)函數(shù)中還要使用
g_pDeviceObject = pDevObj;
// 為了用戶模式進(jìn)程能夠監(jiān)視,創(chuàng)建事件對(duì)象
UNICODE_STRING uszProcessEventString;
RtlInitUnicodeString(&uszProcessEventString, EVENT_NAME);
pDevExt->ProcessEvent = IoCreateNotificationEvent(&uszProcessEventString, &pDevExt->hProcessHandle);
// 設(shè)置它為非受信狀態(tài)
KeClearEvent(pDevExt->ProcessEvent);
// 設(shè)置回調(diào)例程
status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
return status;
}
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
// 移除進(jìn)程回調(diào)例程
PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
// 刪除符號(hào)連接名稱
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
// 刪除設(shè)備對(duì)象
IoDeleteDevice(pDriverObj->DeviceObject);
}
// 處理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代碼
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 完成此請求
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint(" ProcDrv: DispatchIoctl... \n");
// 假設(shè)失敗
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
// 取得此IRP(pIrp)的I/O堆棧指針
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 取得設(shè)備擴(kuò)展結(jié)構(gòu)指針
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 取得I/O控制代碼
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O緩沖區(qū)指針和它的長度
PCALLBACK_INFO pCallbackInfo = (PCALLBACK_INFO)pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_NTPROCDRV_GET_PROCINFO: // 向用戶程序返回有事件發(fā)生的進(jìn)程的信息
{
if(uOutSize >= sizeof(CALLBACK_INFO))
{
pCallbackInfo->hParentId = pDevExt->hPParentId;
pCallbackInfo->hProcessId = pDevExt->hPProcessId;
pCallbackInfo->bCreate = pDevExt->bPCreate;
status = STATUS_SUCCESS;
}
}
break;
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
// 完成請求
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
// 進(jìn)程回調(diào)函數(shù)
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate)
{
// 得到設(shè)備擴(kuò)展結(jié)構(gòu)的指針
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
// 安排當(dāng)前值到設(shè)備擴(kuò)展結(jié)構(gòu)
// 用戶模式應(yīng)用程序?qū)⑹褂肈eviceIoControl調(diào)用把它取出
pDevExt->hPParentId = hParentId;
pDevExt->hPProcessId = hProcessId;
pDevExt->bPCreate = bCreate;
// 觸發(fā)這個(gè)事件,以便任何正在監(jiān)聽的用戶程序知道有事情發(fā)生了。
// 用戶模式下的應(yīng)用程序不能重置KM事件,所以我們要在這里觸發(fā)它
KeSetEvent(pDevExt->ProcessEvent, 0, FALSE);
KeClearEvent(pDevExt->ProcessEvent);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -