Secondary Categories: 02-Windows Kernel
There are many ways to interact with a Windows Kernel Driver. The most common way that user application can communicate with kernel drivers is via IRP. There are several very common IRP requests that we can see such as:
- IRP_MJ_CREATE
- IRP_MJ_CLOSE
- IRP_MJ_READ
- IRP_MJ_WRITE
- IRP_MJ_DEVICE_CONTROL
At minimum a driver needs to be able to support the create and close IRP. These allow the calling user client to open and close a handle to the driver.
The prototype for the dispatch routine is like so:
NTSTATUS SomeMethod(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp);
An example would look something like so:
NTSTATUS CreateClose(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
)
{
UNREFERENCED_PARAMETER(DeviceObject);
KdPrint(("[+] Hello from CreateClose\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
In our main.cpp
we need to create a symbolic link and new device object for user clients to interact with the driver and send IRP’s like so:
#include "driver.h"
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDriver");
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\MyDriver");
extern "C"
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject;
UNREFERENCED_PARAMETER(RegistryPath);
KdPrint(("[+] Hello from DriverEntry\n"));
DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = CreateClose;
DriverObject->DriverUnload = Cleanup;
// create device object
status = IoCreateDevice(
DriverObject,
0,
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject
);
if (!NT_SUCCESS(status)) {
KdPrint(("[!] IoCreateDevice failed: 0x%08X\n", status));
return status;
}
// create symlink
status = IoCreateSymbolicLink(
&symLink,
&deviceName);
if (!NT_SUCCESS(status)) {
KdPrint(("[!] IoCreateSymbolicLink failed: 0x%08X\n", status));
// delete device object before returning
IoDeleteDevice(deviceObject);
return status;
}
return STATUS_SUCCESS;
}
Notice that in the CreateClose
function matches the prototype and we also return a STATUS_SUCCESS
this is to ensure that we notify the driver that we are done and its memory can be cleaned up.
Resources:
Title | URL |
---|---|
PLACE | HOLDER |
Also Check Out:
- PLACE HOLDER