Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

irp->UserBuffer always Empty for IRP_MJ_DEVICE_CONTROL

NtKernelMCNtKernelMC Member Posts: 4

I have two macroes for IO calls

define IOCTL_GET_PROCID CTL_CODE(0x00008000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)

define IOCTL_INJECT_DLL CTL_CODE(0x00008000, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)

and also have pDriverObject->Flags |= DO_BUFFERED_IO; in Driver entry
but still my user buffer is empty when i call DeviceIoControl from my app.
Full source of driver

include <ntifs.h>

include <ntddk.h>

include <wdf.h>

include <wdm.h>

include <windef.h>

include <ntdef.h>

include <parallel.h>

include <initguid.h>

include <wdmguid.h>

include <stdio.h>

include <stdlib.h>

pragma warning (disable: 4189)

pragma warning (disable: 4100)

pragma warning (disable: 4995)

pragma warning (disable: 4101)

define IOCTL_GET_PROCID CTL_CODE(0x00008000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)

define IOCTL_INJECT_DLL CTL_CODE(0x00008000, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)

define DRIVER_FUNC_INSTALL 0x01

define DRIVER_FUNC_REMOVE 0x02

define DRIVER_NAME "KernelFucker"

define NT_DEVICE_NAME L"\Device\KernelFucker"

define DOS_DEVICE_NAME L"\DosDevices\KernelFucker"

DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD UnloadRoutine;
NTSTATUS CreateController(IN PDEVICE_OBJECT fdo, IN PIRP irp);
NTSTATUS WriteController(IN PDEVICE_OBJECT fdo, IN PIRP irp);
NTSTATUS CloseController(IN PDEVICE_OBJECT fdo, IN PIRP irp);
NTSTATUS DeviceController(IN PDEVICE_OBJECT fdo, IN PIRP irp);

pragma alloc_text (INIT, DriverEntry)

pragma alloc_text(PAGE, CreateController)

pragma alloc_text(PAGE, WriteController)

pragma alloc_text(PAGE, CloseController)

pragma alloc_text(PAGE, DeviceController)

pragma alloc_text(PAGE, UnloadRoutine)

//typedef NTSTATUS(PLDR_LOAD_DLL)(PWSTR, PULONG, PUNICODE_STRING, PVOID);
void UnloadRoutine(struct _DRIVER_OBJECT *DriverObject)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Unloaded Routine!\n");
PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
UNICODE_STRING uniWin32NameString;
PAGED_CODE();
RtlInitUnicodeString(&uniWin32NameString, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&uniWin32NameString);
if (deviceObject != NULL)
{
IoDeleteDevice(deviceObject);
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "I\O unhooked.\n");
}
NTSTATUS CreateController(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Created Dispatcher!\r\n");
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS WriteController(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Write Dispatcher!\r\n");
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS CloseController(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Closed Dispatcher!\r\n");
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DeviceController(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
PVOID pBuffer = NULL; static char RetBuffer[] = { "[Ring-0]: Complete!" };
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(irp);
ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
pBuffer = irp->UserBuffer; static char DllPath[256]; static DWORD ProcID;
switch (ControlCode)
{
case IOCTL_GET_PROCID:
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IO Dispatcher called!\r\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Control Code: %d | IOCTL_GET_PROCID\r\n", ControlCode);
ProcID = atoi(pBuffer);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcID: %d\r\n", ProcID);
RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, &RetBuffer, InputLength);
break;
case IOCTL_INJECT_DLL:
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IO Dispatcher called!\r\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Control Code: %d | IOCTL_INJECT_DLL\r\n", ControlCode);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Inc Buffer Size: %d\r\n", InputLength);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Out Buffer Size: %d\r\n", OutputLength);
memcpy(DllPath, pBuffer, sizeof(DllPath));
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "DLL Path: %s\r\n", DllPath);
RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, &RetBuffer, InputLength);
break;
}
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = InputLength;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return irp->IoStatus.Status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegistryPath)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "DriverEntry Called \r\n");
//MmGetSystemRoutineAddress()
NTSTATUS ntStatus;
UNICODE_STRING ntUnicodeString;
UNICODE_STRING ntWin32NameString;
PDEVICE_OBJECT deviceObject = NULL;
UNREFERENCED_PARAMETER(RegistryPath);
pDriverObject->MajorFunction[IRP_MJ_CREATE] = CreateController;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = WriteController;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseController;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceController;
pDriverObject->DriverUnload = UnloadRoutine;
RtlInitUnicodeString(&ntUnicodeString, NT_DEVICE_NAME);
ntStatus = IoCreateDevice(pDriverObject, 0, &ntUnicodeString,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject);
if (!NT_SUCCESS(ntStatus))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Couldn't create the device object\n");
return ntStatus;
}
RtlInitUnicodeString(&ntWin32NameString, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&ntWin32NameString, &ntUnicodeString);
if (!NT_SUCCESS(ntStatus))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Couldn't create symbolic link\n");
IoDeleteDevice(deviceObject);
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Major hooks placed!\n");
pDriverObject->Flags &= ~DO_DEVICE_INITIALIZING;
pDriverObject->Flags |= DO_BUFFERED_IO;
return STATUS_SUCCESS;
}

Comments

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 6,836

    The pointer to your data buffer isn't in Irp->UserBuffer for buffered I/O... it's in Irp->AssociatedIrp.SystemBuffeer

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • NtKernelMCNtKernelMC Member Posts: 4

    @Peter_Viscarola said:
    The pointer to your data buffer isn't in Irp->UserBuffer for buffered I/O... it's in Irp->AssociatedIrp.SystemBuffeer

    Peter

    But in SystemBuffer pointer to incoming buffer, okay i just need to send in my driver a string. Where my mistake?

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 6,836

    But in SystemBuffer pointer to incoming buffer, okay i just need to send in my driver a string. Where my mistake?

    Sorry... I don't understand your question.

    The data sent to your driver, both the Input and Output buffers, is located at Irp->AssociatedIrp.SystemBuffer. See the section "METHOD_BUFFERED" in MSDN here.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,277

    I lost interest at 'define DRIVER_NAME "KernelFucker"'

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 6,836

    @Mark_Roddy said:
    I lost interest at 'define DRIVER_NAME "KernelFucker"'

    >

    Ah! You READ his code! A step that I bypassed.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • NtKernelMCNtKernelMC Member Posts: 4

    @Mark_Roddy said:
    I lost interest at 'define DRIVER_NAME "KernelFucker"'

    Sorry for that, forgot to rename :cold_sweat: It`s just a name and nothing more)

    @Peter_Viscarola said:

    But in SystemBuffer pointer to incoming buffer, okay i just need to send in my driver a string. Where my mistake?

    Sorry... I don't understand your question.

    The data sent to your driver, both the Input and Output buffers, is located at Irp->AssociatedIrp.SystemBuffer. See the section "METHOD_BUFFERED" in MSDN here.

    Peter

    When i try to read the output buffer i get empty string. As far as i know - output buffer is irp->UserBuffer and incoming buffer is as you sayed - SystemBuffer yeah but i need only outcoming. Cant understand why its always empty like i pointer NULL when calling DeviceIoControl but it`s not, so problem in my driver code. I read many articles about buffered method and not find answer to my question.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 6,836

    As far as i know - output buffer is irp->UserBuffer and incoming buffer is as you sayed - SystemBuffer

    Nope. It’s awlays irp->AssociatedIrp.SystemBuffer. Read the docs I pointed you to. It’s very clear. Irp->UserBuffer is not used in Buffered I/O.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • NtKernelMCNtKernelMC Member Posts: 4

    @Peter_Viscarola said:

    As far as i know - output buffer is irp->UserBuffer and incoming buffer is as you sayed - SystemBuffer

    Nope. It’s awlays irp->AssociatedIrp.SystemBuffer. Read the docs I pointed you to. It’s very clear. Irp->UserBuffer is not used in Buffered I/O.

    Peter

    Thanks! I killed two days for this )

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!