Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Создание драйвера для Windows NT: отслеживание запуска и остановки процессов

Delphi , ОС и Железо , Драйвера

Communication between Delphi Application and Windows NT System Driver

Introduction

In this article, we will explore how to create a simple driver for Windows NT that registers the "PsSetCreateProcessNotifyRoutine" and notifies a Win32 application about started and stopped processes. We will use Delphi to create the application and communicate with the driver using IOCTL (Input/Output Control).

Building a Simple Driver

First, let's create a simple driver using the DriverEntry and DriverUnload functions. You can use the Windows Driver Kit (WDK) to compile the driver.

  1. Create a new project in WDK and select "Kernel-Mode Driver" as the project template.
  2. Implement the DriverEntry and DriverUnload functions in the driver source file.

Here's a basic example of the driver source code:

#include <ntddk.h>

NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
)
{
    UNREFERENCED_PARAMETER(RegistryPath);

    DbgPrint("DriverEntry called\n");

    DriverObject->DriverUnload = UnloadDriver;

    return STATUS_SUCCESS;
}

VOID UnloadDriver(_In_ PDRIVER_OBJECT DriverObject)
{
    UNREFERENCED_PARAMETER(DriverObject);

    DbgPrint("UnloadDriver called\n");
}

Implementing Communication with IOCTL

To communicate with the driver, we'll use IOCTL. Here's how to implement it in both the driver and the Delphi application.

Driver-side IOCTL

  1. Define an IOCTL code in the driver source file. For example:
#define IOCTL_MY_DRIVER CTL_CODE(FILE_DEVICE_MY_DRIVER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
  1. Implement the IOCTL handling in the DriverEntry function:
NTSTATUS DriverEntry(
    // ...
)
{
    // ...

    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;

    // ...
}

NTSTATUS DeviceControl(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PDEVICE_OBJECT DeviceObject,
    _Inout_ PIRP Irp
)
{
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    ULONG controlCode = stack->Parameters.DeviceIoControl.IoControlCode;
    PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer;
    PVOID outputBuffer = inputBuffer;
    ULONG inputBufferLength = stack->Parameters.DeviceIoControl.InputBufferLength;
    ULONG outputBufferLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
    NTSTATUS status;

    if (controlCode == IOCTL_MY_DRIVER) {
        // Process the IOCTL request here
        // ...
    } else {
        status = Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
    }

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

    return status;
}

Delphi Application-side IOCTL

  1. Define the IOCTL code in the Delphi application. You can use the JclWindows unit from JEDI to define the IOCTL code:
uses
  JclWindows;

const
  IOCTL_MY_DRIVER = $800;

type
  TMyDriverIoctl = record
    // Define the input and output data structures here
  end;
  1. Use the DeviceIoControl function to send the IOCTL request to the driver:
uses
  // ...

procedure SendIoctlRequest(DriverHandle: THandle; IoctlCode: DWORD; InputBuffer: Pointer; InputBufferSize: DWORD; OutputBuffer: Pointer; OutputBufferSize: PDWORD);
var
  IoctlResult: DWORD;
begin
  IoctlResult := DeviceIoControl(DriverHandle, IoctlCode, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, nil, nil);
  if IoctlResult = 0 then
    raise Exception.Create('DeviceIoControl failed');
end;

var
  DriverHandle: THandle;
  IoctlInput: TMyDriverIoctl;
  IoctlOutput: TMyDriverIoctl;
begin
  DriverHandle := CreateFile('\\.\MyDriver', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  try
    // Prepare the input data
    // ...

    // Send the IOCTL request
    SendIoctlRequest(DriverHandle, IOCTL_MY_DRIVER, @IoctlInput, SizeOf(IoctlInput), @IoctlOutput, SizeOf(IoctlOutput));

    // Process the output data
    // ...
  finally
    CloseHandle(DriverHandle);
  end;
end;

Alternative Communication Methods

While IOCTL is a common method for communicating with drivers, there are other ways to achieve the same goal. One alternative is using the Windows Management Instrumentation (WMI) to detect when a process starts or stops, as suggested in the StackOverflow comment by RRUZ. This approach doesn't require creating a driver and can be more lightweight.

Conclusion

In this article, we've explored how to create a simple driver for Windows NT that communicates with a Delphi application using IOCTL. We've also discussed an alternative approach using WMI. By following the guidelines provided, you should be able to create a driver that notifies your application about started and stopped processes. Keep in mind that working with drivers requires a good understanding of Windows internals and can be complex, so always refer to the official documentation and resources when needed.

References

Создано по материалам из источника по ссылке.

Статья о создании драйвера для Windows NT и коммуникации между ним и приложением на Delphi с использованием IOCTL.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Драйвера ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 05:49:24/0.0033779144287109/0