A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #32925  by freesauce
 Sat May 18, 2019 9:19 pm
I have recently started with WDM kernel development and I am currently just trying to do some basic Direct I/O IRP handling from example code. In my MJ_WRITE dispatch function, I am attempting to map the MdlAddress via MmGetSystemAddressForMdlSafe to later access the buffer, however, the function freezes my VM and a bugcheck is hit in WinDbg. This seemed weird to me, as it was my understanding that the Safe-variant did not bugcheck, but rather should have returned NULL on failure. After wrapping the call in a try/except block, I got STATUS_ACCESS_VIOLATION from SEH.

VM OS: Windows 10 64-bit Version 1809

DriverEntry:
Code: Select all
	DriverObject->Flags |= DO_DIRECT_IO;
	DriverObject->Flags &= (~DO_DEVICE_INITIALIZING);

	DriverObject->DriverUnload = Prefix_Unload;

	DriverObject->MajorFunction[IRP_MJ_CREATE] = Prefix_Create;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = Prefix_Close;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Prefix_DeviceControl;
	DriverObject->MajorFunction[IRP_MJ_READ] = NULL;
	DriverObject->MajorFunction[IRP_MJ_WRITE] = Prefix_Write;
Prefix_Write:
Code: Select all
        NTSTATUS Status = STATUS_SUCCESS;
	UNREFERENCED_PARAMETER(DeviceObject);

	PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);

	if (!StackLocation)
	{
		Status = STATUS_INVALID_PARAMETER;
		Irp->IoStatus.Information = 0;
		KdPrint(("We done goofed...\r\n"));
		goto Done;
	}
        // try/except just to get the error code. Obviously it should not be needed at all.
	__try
	{
		MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); // Fails
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		Status = GetExceptionCode();
		Irp->IoStatus.Information = 0;
		goto Done;
	}

	Irp->IoStatus.Status = Status;
	Irp->IoStatus.Information = StackLocation->Parameters.Write.Length;

Done:
	KdPrint(("Status: %lu ...\r\n", (unsigned long)Status));
	Irp->IoStatus.Status = Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return Status;
Usermode:
Code: Select all
buf[] = "Hello from user mode";
WriteFile(file, buf, sizeof(buf), &nbRead, NULL);
The MSDN docs mention that the function is not available for drivers written for WDM 1.0, so I did specify KMDF version 1.25 as the intended version in the VS:Driver Settings, even though I doubt that the two are related. Needless to say, that did not help either. What am I missing?
 #32927  by freesauce
 Sun May 19, 2019 11:51 am
Turned out to be my blunder. I was trying to access Irp->MdlAddress without successfully setting the direct I/O flag.
freesauce wrote: Sat May 18, 2019 9:19 pm DriverEntry:
Code: Select all
	DriverObject->Flags |= DO_DIRECT_IO;
	DriverObject->Flags &= (~DO_DEVICE_INITIALIZING);
This should have been DeviceObject's flags.
Code: Select all
	DeviceObject->Flags |= DO_DIRECT_IO;
	DeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
Sadly it took me 2 days to see... Apologies to anyone who I may have confused.