Добавил:
Kaz
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include <ntddk.h>
#define FILE_DEVICE_UNKNOWN 0x00000022
#define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN
#define IOCTL_PROCOBSRV_ACTIVATE_MONITORING \//создан собственный IOCTL запрос при помощи макроса CTL_CODE:
CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_PROCOBSRV_GET_PROCINFO \
CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
void UnloadDriver(
PDRIVER_OBJECT DriverObject
);
NTSTATUS DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS DispatchIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
//
// Process function callback
VOID ProcessCallback(
IN HANDLE hParentId,
IN HANDLE hProcessId,
IN BOOLEAN bCreate
);
//
// Structure for holding info about activating/deactivating the driver
typedef struct _ActivateInfo
{
BOOLEAN bActivated;
} ACTIVATE_INFO, *PACTIVATE_INFO;
//
// Structure for process callback information
typedef struct _ProcessCallbackInfo
{
HANDLE hParentId;
HANDLE hProcessId;
BOOLEAN bCreate;
} PROCESS_CALLBACK_INFO, *PPROCESS_CALLBACK_INFO;
//
// Private storage for process retreiving
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject;
//
// Shared section
HANDLE hProcessId;
//
// Process section data
PKEVENT ProcessEvent;
HANDLE hParentId;
BOOLEAN bCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
//
// Global variables
PDEVICE_OBJECT g_pDeviceObject;
ACTIVATE_INFO g_ActivateInfo;
//
// The main entry point of the driver module
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
UNICODE_STRING uszDriverString;
UNICODE_STRING uszDeviceString;
UNICODE_STRING uszProcessEventString;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_EXTENSION extension;
HANDLE hProcessHandle;
//
// Point uszDriverString at the driver name
//Начнем с определения структур UNICODE_STRING, описывающих имя устройства и символьной ссылки. Как я уже говорил в третьей части, ядро любит работать со строками именно в этом формате.
RtlInitUnicodeString(&uszDriverString, L"\\Device\\ProcObsrv");// Задача функции RtlInitUnicodeString измерить unicode-строку и заполнить
//
// Create and initialize device object
ntStatus = IoCreateDevice(//Для создания девайсов в Windows Kernel имеется всем известная API: IoCreateDevice(..., DEVICE_TYPE,...);
DriverObject,
sizeof(DEVICE_EXTENSION),
&uszDriverString,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDeviceObject
);
if(ntStatus != STATUS_SUCCESS)
return ntStatus;
//
// Assign extension variable
extension = pDeviceObject->DeviceExtension;
//
// Point uszDeviceString at the device name
RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\ProcObsrv");
//
// Create symbolic link to the user-visible name
ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);
if(ntStatus != STATUS_SUCCESS)
{
//
// Delete device object if not successful
IoDeleteDevice(pDeviceObject);
return ntStatus;
}
//
// Assign global pointer to the device object for use by the callback functions
g_pDeviceObject = pDeviceObject;
//
// Setup initial state
g_ActivateInfo.bActivated = FALSE;
//
// Load structure to point to IRP handlers
DriverObject->DriverUnload = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
//
// Create event for user-mode processes to monitor
RtlInitUnicodeString(
&uszProcessEventString,
L"\\BaseNamedObjects\\ProcObsrvProcessEvent"
);
extension->ProcessEvent = IoCreateNotificationEvent(
&uszProcessEventString,
&hProcessHandle
);
//
// Clear it out
//
KeClearEvent(extension->ProcessEvent);
//
// Return success
return ntStatus;
}
//
// Create and close routine
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;//// Возращаемое значение - ошибка или нормальное. При нормальном завершении - будет передан HANDLE на устройство, в нашем случае на драйвер.
Irp->IoStatus.Information = 0;//// Количество переданных вверх байт - в нашем случае 0 потому как нет передаваемых параметров.
IoCompleteRequest(Irp, IO_NO_INCREMENT);//// Завершение работы. Вызов функции IofCompleteRequest инициирует операцию завершения ввода-вывода (I/O completion).
return STATUS_SUCCESS;
}
//
// Process function callback
VOID ProcessCallback(
IN HANDLE hParentId,
IN HANDLE hProcessId,
IN BOOLEAN bCreate
)
{
PDEVICE_EXTENSION extension;
//
// Assign extension variable
extension = g_pDeviceObject->DeviceExtension;
//
// Assign current values into device extension.
// User-mode apps will pick it up using DeviceIoControl calls.
extension->hParentId = hParentId;
extension->hProcessId = hProcessId;
extension->bCreate = bCreate;
//
// Signal the event thus the user-mode apps listening will be aware
// that something interesting has happened.
KeSetEvent(extension->ProcessEvent, 0, FALSE);
KeClearEvent(extension->ProcessEvent);
}
//
// IOCTL handler for setting the callback
NTSTATUS ActivateMonitoringHanlder(
IN PIRP Irp
)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PACTIVATE_INFO pActivateInfo;
if (irpStack->Parameters.DeviceIoControl.InputBufferLength >=
sizeof(ACTIVATE_INFO))
{
pActivateInfo = Irp->AssociatedIrp.SystemBuffer;
if (g_ActivateInfo.bActivated != pActivateInfo->bActivated)
{
if (pActivateInfo->bActivated)
{
//
// Set up callback routines
/*
Добавляет/удаляет в системный список вызовов указатель на процедуру, которая будет вызываться всегда при создании или удалении процесса в системе. Первый параметр - указатель на процеду -обработчик, второй типа bool определяет, удаляется или добавляется обработчик.
*/
ntStatus = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
if (ntStatus != STATUS_SUCCESS)
{
return ntStatus;
}
//
// Setup the global data structure
g_ActivateInfo.bActivated = pActivateInfo->bActivated;
} // if
else
{
//
// restore the call back routine, thus givinig chance to the
// user mode application to unload dynamically the driver
ntStatus = PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
if (ntStatus != STATUS_SUCCESS)
return ntStatus;
else
g_ActivateInfo.bActivated = FALSE;
}
ntStatus = STATUS_SUCCESS;
}
}
return ntStatus;
}
//
// The dispatch routine
NTSTATUS DispatchIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);//получения указателя на стек IRP пакета используется функция:
PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
PPROCESS_CALLBACK_INFO pProcCallbackInfo;
//
// These IOCTL handlers are the set and get interfaces between
// the driver and the user mode app
switch(irpStack->Parameters.DeviceIoControl.IoControlCode)//получение управляющего IOCTL кода;
{
case IOCTL_PROCOBSRV_ACTIVATE_MONITORING:
{
ntStatus = ActivateMonitoringHanlder( Irp );
break;
}
case IOCTL_PROCOBSRV_GET_PROCINFO:
{
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >=// получение размера буфера которое ожидает приложение
sizeof(PROCESS_CALLBACK_INFO))
{
pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;//получение переданного буфера
pProcCallbackInfo->hParentId = extension->hParentId;
pProcCallbackInfo->hProcessId = extension->hProcessId;
pProcCallbackInfo->bCreate = extension->bCreate;
ntStatus = STATUS_SUCCESS;
}
break;
}
default:
break;
}
Irp->IoStatus.Status = ntStatus;
//
// Set number of bytes to copy back to user-mode
if(ntStatus == STATUS_SUCCESS)
Irp->IoStatus.Information = //количество переданных байт.
irpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
//
// Driver unload routine
void UnloadDriver(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING uszDeviceString;
//
// By default the I/O device is configured incorrectly or the
// configuration parameters to the driver are incorrect.
NTSTATUS ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
if (g_ActivateInfo.bActivated)
//
// restore the call back routine, thus givinig chance to the
// user mode application to unload dynamically the driver
ntStatus = PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
IoDeleteDevice(DriverObject->DeviceObject);
RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\ProcObsrv");
IoDeleteSymbolicLink(&uszDeviceString);
}
//----------------------------End of the file -------------------------------
Соседние файлы в папке ProcObsrv