I am trying to do kernel-user communication using shared memory - section objects. I created a section object in my minifilter driver with ZwCreateSection and then mapped a view of it into a virtual address using ZwMapViewOfSection. I have given it full read/write permissions everywhere. In order to access it in an arbitrary user process, I need to get the system address for the buffer - MmGetSystemAddressForMdlSafe. I call MmProbeAndLockPages before calling MmGetSystemAddressForMdlSafe to make sure that the buffer is resident in memory.
The MmProbeAndLockPages call always results in a STATUS_ACCESS_VIOLATION exception no matter what I do. I haven’t got a great deal of experience in writing windows drivers; so I think I must be missing something pretty basic. Here’s the code:
NTSTATUS DriverEntry(
__in PDRIVER_OBJECT DrvObj,
__in PUNICODE_STRING RegPath
)
{
NTSTATUS status;
UNICODE_STRING tmpstr;
OBJECT_ATTRIBUTES objattr;
LARGE_INTEGER secsize;
SIZE_T viewsize;
UNICODE_STRING DeviceName;
UNICODE_STRING SymName;
PDEVICE_OBJECT deviceObject = NULL;
SECURITY_DESCRIPTOR sd;
num_file_ops = 0;
status = FltRegisterFilter( DrvObj, ®struct, &flthandle );
if(!NT_SUCCESS(status))
return status;
RtlInitUnicodeString(&tmpstr, L"\BaseNamedObjects\HwmfilterMemSect");
status = RtlCreateSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION );
if(!NT_SUCCESS(status))
return status;
status = RtlSetDaclSecurityDescriptor( &sd, TRUE, NULL, FALSE );
if(!NT_SUCCESS(status))
{
//Free Security Descriptor
return status;
}
InitializeObjectAttributes(
&objattr,
&tmpstr,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
&sd
);
secsize.QuadPart = 0x10000;
status = ZwCreateSection(
&sechandle,
SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_QUERY,
&objattr,
&secsize,
PAGE_READWRITE,
SEC_COMMIT,
NULL
);
sharedmem = NULL;
viewsize = PAGE_SIZE;
status = ZwMapViewOfSection(
sechandle,
(HANDLE)-1,
&sharedmem,
0L,
PAGE_SIZE,
NULL,
&viewsize,
ViewShare,
0,
PAGE_READWRITE
);
*(PULONG)sharedmem = 99; // ** Succeeds without any problem
if(!MmIsAddressValid(sharedmem))
DbgPrint(“ZwMapViewOfSection failed silently!!\n”);
.
.
.
}
NTSTATUS modifySharedBuf(const void *dataToWrite, long dataLength)
{
NTSTATUS status = STATUS_SUCCESS;
//make these params global or #defined
mdl = IoAllocateMdl(sharedmem, PAGE_SIZE, FALSE, FALSE, NULL);
if(!mdl)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
try
{
MmProbeAndLockPages(mdl, KernelMode, IoModifyAccess);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
IoFreeMdl(mdl);
return status;
}
shmbuf = MmGetSystemAddressForMdlSafe(mdl ,NormalPagePriority);
if(!shmbuf)
{
DbgPrint(“Failed to create systemwide address\n”);
MmUnlockPages(mdl);
IoFreeMdl(mdl);
return STATUS_INSUFFICIENT_RESOURCES;
}
//Now modify the shared buffer and then free it later
RtlCopyMemory(shmbuf, dataToWrite, dataLength);
MmUnlockPages(mdl);
IoFreeMdl(mdl);
return status;
}
I’ve already got a version of the driver working with the port based user-kernel communication model described in the minifilter documentation. I just want to try this out so that I can do a performance comparison with my specific application scenario. Any help would be greatly appreciated.