How can i use kernel procees adress space at PFLT_PRE_OPERATION_CALLBACK ?

I want to track changes on volume in folowing way (file system minifilter):
I am initializing memory mapped file section view in driver entry and bitmap that is based on file mapped memory, in PFLT_PRE_OPERATION_CALLBACK on IRP_MJ_WRITE i write bits to that bitmap.

If i creating mapped view, bitmap and then write to bitmap in pre operation callback -all works, but if i initialize view and bitmap in driver entry os crash on RtlSetBits with SYSTEM_SERVICE_EXCEPTION (3b)
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s…

As i can see Driver Entry is called in Kernel process(System), so file is mapped to virtual memory of kernell process and PRE_OPERATION_CALLBACK is called in user process that caused IO, so virtual memory from kernel will be wrong for user process. Am i right?
How can i write to kernel adress space from PFLT_PRE_OPERATION_CALLBACK? What can you advice?

reduced code

typedef struct _FILEFILTER_DATA {
PFILE_OBJECT bitmapFileObject;
PVOID sectionBitmapAdr;
HANDLE bitmapFileHandle;
RTL_BITMAP volumeBitmap;
HANDLE sectionHandle;
PFLT_FILTER Filter;

} FILEFILTER_DATA, *PFILEFILTER_DATA;

AAFILEFILTER_DATA filterData;
LARGE_INTEGER MySize = { 0x9000 };
SIZE_T mappedSize = 0; // will receive the actual page-aligned size

DriverEntry (…)

{
status = FltRegisterFilter( DriverObject,
&FilterRegistration,
&filterData.Filter);

const UNICODE_STRING Filename = RTL_CONSTANT_STRING(L"\Device\HarddiskVolume1\temp\ChangesBitmap.txt");

InitializeObjectAttributes(&objectAttributes,
&Filename,
OBJ_KERNEL_HANDLE,
NULL,
NULL);

status = FltCreateFileEx(filterData.Filter,
NULL,
&filterData.bitmapFileHandle,
&filterData.bitmapFileObject,
FILE_WRITE_DATA | FILE_APPEND_DATA,
&objectAttributes,
&ioStatus,
(PLARGE_INTEGER)NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS,
(PVOID)NULL,
0L,
IO_IGNORE_SHARE_ACCESS_CHECK);

status = ZwCreateSection(&filterData.sectionHandle,

SECTION_ALL_ACCESS,
NULL,
&MySize, //Clusters in volume
PAGE_READWRITE,
SEC_COMMIT,
filterData.bitmapFileHandle);

status = ZwMapViewOfSection(filterData.sectionHandle,
ZwCurrentProcess(),
&filterData.sectionBitmapAdr,
0,
0,
0,
&mappedSize,
ViewUnmap,
0,
PAGE_READWRITE);

InitializeBitMap(&filterData.volumeBitmap, filterData.sectionBitmapAdr, (ULONG)mappedSize);

}

FLT_PREOP_CALLBACK_STATUS FileFilterPreOperation (…)
{
//If i move all initialization from Driver Entry Here - all works
RtlSetBits(&filterData.volumeBitmap, 0, 20);

}

ZwMapViewOfSection return mapping adress (filterData.sectionBitmapAdr) in user space, which is valid only in current process. you need map section in kernel space with MmMapViewInSystemSpace.

PVOID Section;
if (0 <= (status = ObReferenceObjectByHandle(filterData.sectionHandle, 0, 0, KernelMode, &Section, 0)))
{
filterData.sectionBitmapAdr = 0;
status = MmMapViewInSystemSpace(Section, &filterData.sectionBitmapAdr, mappedSize);
ObfDereferenceObject(Section);
}

Thank you! But MmMapViewInSystemSpace is not official supported, i read about problems and surprises with it on x64 platform… don’t think that this is good idea to use it in production…

Also… driver entry is called as System(Kernel) process does this mean that ZwMapViewOfSection in driver entry will do the same as MmMapViewInSystemSpace?

Is there some other choises… maybe MmGetSystemAddressForMdlSafe in some way?

MmMapViewInSystemSpace normal work both on x86 and x64 without any problems, only if you not mistake.

driver entry is called as System(Kernel) process does this mean that ZwMapViewOfSection in driver entry will do the same as MmMapViewInSystemSpace?

not of course. ZwMapViewOfSection map in user space of process. MmMapViewInSystemSpace map in kernel space. principal different.
http://msdn.microsoft.com/en-us/library/windows/hardware/hh439648(v=vs.85).aspx

maybe MmGetSystemAddressForMdlSafe
are you have/need Mdl for map ?

> I want to track changes on volume in folowing way (file system

minifilter):
I am initializing memory mapped file section view in driver entry and
bitmap that is based on file mapped memory, in PFLT_PRE_OPERATION_CALLBACK
on IRP_MJ_WRITE i write bits to that bitmap.

If i creating mapped view, bitmap and then write to bitmap in pre
operation callback -all works, but if i initialize view and bitmap in
driver entry os crash on RtlSetBits with SYSTEM_SERVICE_EXCEPTION (3b)
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx
referenced memory at 0x%08lx. The memory could not be %s…

As i can see Driver Entry is called in Kernel process(System), so file is
mapped to virtual memory of kernell process and PRE_OPERATION_CALLBACK is
called in user process that caused IO, so virtual memory from kernel will
be wrong for user process. Am i right?
How can i write to kernel adress space from PFLT_PRE_OPERATION_CALLBACK?
What can you advice?

The explanation is a bit confusing. I see no !analyze -v output or source
code here, making any suggestion a work of speculative fiction.
joe


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Based upon what you’ve answered subsequently, I suspect you are mapping something (in driver entry) into the system process context’s low address range. This is easily confirmed in the kernel debugger: look at the address you are getting back from whatever function you are calling. If this is a low address ( < MM_HIGHEST_USER_ADDRESS) then when you switch into a different process context (such as that in which you might be called in the pre operation callback) that address will be translated against the current set of page tables for the current process.

That’s the magic of the system address space: it’s the same in every process. But the “system process” is a process like any other and actually has it’s own “user address space”. You CAN use it, but you’d really best understand what you are doing.

Tony
OSR

MmMapViewInSystemSpace works. Thank you!