Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Last active April 26, 2024 10:36
Show Gist options
  • Save hasherezade/ee1a1914dfa2920c77e82fd52717a8fb to your computer and use it in GitHub Desktop.
Save hasherezade/ee1a1914dfa2920c77e82fd52717a8fb to your computer and use it in GitHub Desktop.
HelloWorld driver
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:00000008
// Sample "Hello World" driver
// creates a HelloDev, that expects one IOCTL
#include <ntddk.h>
#define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
#define DOS_DEV_NAME L"\\DosDevices\\HelloDev"
#define DEV_NAME L"\\Device\\HelloDev"
/// <summary>
/// IRP Not Implemented Handler
/// </summary>
/// <param name="DeviceObject">The pointer to DEVICE_OBJECT</param>
/// <param name="Irp">The pointer to IRP</param>
/// <returns>NTSTATUS</returns>
NTSTATUS IrpNotImplementedHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
UNREFERENCED_PARAMETER(DeviceObject);
PAGED_CODE();
// Complete the request
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_SUPPORTED;
}
/// <summary>
/// IRP Create Close Handler
/// </summary>
/// <param name="DeviceObject">The pointer to DEVICE_OBJECT</param>
/// <param name="Irp">The pointer to IRP</param>
/// <returns>NTSTATUS</returns>
NTSTATUS IrpCreateCloseHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER(DeviceObject);
PAGED_CODE();
// Complete the request
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
/// <summary>
/// IRP Unload Handler
/// </summary>
/// <param name="DeviceObject">The pointer to DEVICE_OBJECT</param>
/// <returns>NTSTATUS</returns>
VOID IrpUnloadHandler(IN PDRIVER_OBJECT DriverObject) {
UNICODE_STRING DosDeviceName = { 0 };
PAGED_CODE();
RtlInitUnicodeString(&DosDeviceName, DOS_DEV_NAME);
// Delete the symbolic link
IoDeleteSymbolicLink(&DosDeviceName);
// Delete the device
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("[!] Hello Driver Unloaded\n");
}
/// <summary>
/// IRP Device IoCtl Handler
/// </summary>
/// <param name="DeviceObject">The pointer to DEVICE_OBJECT</param>
/// <param name="Irp">The pointer to IRP</param>
/// <returns>NTSTATUS</returns>
NTSTATUS IrpDeviceIoCtlHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
ULONG IoControlCode = 0;
PIO_STACK_LOCATION IrpSp = NULL;
NTSTATUS Status = STATUS_NOT_SUPPORTED;
UNREFERENCED_PARAMETER(DeviceObject);
PAGED_CODE();
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
if (IrpSp) {
switch (IoControlCode) {
case HELLO_DRV_IOCTL:
DbgPrint("[< HelloDriver >] Hello from the Driver!\n");
break;
default:
DbgPrint("[-] Invalid IOCTL Code: 0x%X\n", IoControlCode);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
// Complete the request
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
UINT32 i = 0;
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING DeviceName, DosDeviceName = { 0 };
UNREFERENCED_PARAMETER(RegistryPath);
PAGED_CODE();
RtlInitUnicodeString(&DeviceName, DEV_NAME);
RtlInitUnicodeString(&DosDeviceName, DOS_DEV_NAME);
DbgPrint("[*] In DriverEntry\n");
// Create the device
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status)) {
if (DeviceObject) {
// Delete the device
IoDeleteDevice(DeviceObject);
}
DbgPrint("[-] Error Initializing HelloDriver\n");
return Status;
}
// Assign the IRP handlers
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
// Disable the Compiler Warning: 28169
#pragma warning(push)
#pragma warning(disable : 28169)
DriverObject->MajorFunction[i] = IrpNotImplementedHandler;
#pragma warning(pop)
}
// Assign the IRP handlers for Create, Close and Device Control
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreateCloseHandler;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpCreateCloseHandler;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceIoCtlHandler;
// Assign the driver Unload routine
DriverObject->DriverUnload = IrpUnloadHandler;
// Set the flags
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
// Create the symbolic link
Status = IoCreateSymbolicLink(&DosDeviceName, &DeviceName);
// Show the banner
DbgPrint("[!] HelloDriver Loaded\n");
return Status;
}
// Sample app that talks with the HelloDev (Hello World driver)
#include <stdio.h>
#include <windows.h>
#define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
const char kDevName[] = "\\\\.\\HelloDev";
HANDLE open_device(const char* device_name)
{
HANDLE device = CreateFileA(device_name,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
NULL
);
return device;
}
void close_device(HANDLE device)
{
CloseHandle(device);
}
BOOL send_ioctl(HANDLE device, DWORD ioctl_code)
{
//prepare input buffer:
DWORD bufSize = 0x4;
BYTE* inBuffer = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize);
//fill the buffer with some content:
RtlFillMemory(inBuffer, bufSize, 'A');
DWORD size_returned = 0;
BOOL is_ok = DeviceIoControl(device,
ioctl_code,
inBuffer,
bufSize,
NULL, //outBuffer -> None
0, //outBuffer size -> 0
&size_returned,
NULL
);
//release the input bufffer:
HeapFree(GetProcessHeap(), 0, (LPVOID)inBuffer);
return is_ok;
}
int main()
{
HANDLE dev = open_device(kDevName);
if (dev == INVALID_HANDLE_VALUE) {
printf("Failed!\n");
system("pause");
return -1;
}
send_ioctl(dev, HELLO_DRV_IOCTL);
close_device(dev);
system("pause");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment