Hello,
I have a problem with sharing memory, which is bigger than one page (4 kBytes), between driver and user space application.
In a driver I have allocated static global variable
char myTable[sizeof(__int64)*2044]; //size of it is 16352 bytes
and initialized it with simple loop:
__int64* initPtr = (__int64*)myTable;
for (__int64 i=0; i intPtr[i]=i;
Next I’ve tried to share this table with user mode application. I’ve achieved this by execution of the following code:
void getSharedMemory(void* pVA)
{
HANDLE physicalMemorySectionHandle;
UNICODE_STRING physicalMemorySectionUnicodeString;
OBJECT_ATTRIBUTES physicalMemoryObjectAttributes;
PVOID physicalMemorySection = NULL;
PHYSICAL_ADDRESS physicalAddressBase;
PHYSICAL_ADDRESS viewBase;
NTSTATUS status;
PVOID mappedVirtualAddress;
HANDLE processHandle = ZwCurrentProcess();
if (NULL == pVA)
return;
/* Mapping memmory to user space /
RtlInitUnicodeString (&physicalMemorySectionUnicodeString, L"\Device\PhysicalMemory");
InitializeObjectAttributes (&physicalMemoryObjectAttributes,
&physicalMemorySectionUnicodeString,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL);
status = ZwOpenSection (&physicalMemorySectionHandle, SECTION_ALL_ACCESS, &physicalMemoryObjectAttributes);
if (!NT_SUCCESS(status))
{
((PVOID)pVA) = NULL;
return;
}
status = ObReferenceObjectByHandle (physicalMemorySectionHandle,
SECTION_MAP_READ,
(POBJECT_TYPE) NULL,
KernelMode,
&physicalMemorySection,
(POBJECT_HANDLE_INFORMATION) NULL);
if (!NT_SUCCESS(status))
{
((PVOID)pVA) = NULL;
ZwClose(physicalMemorySectionHandle);
return;
}
/ convert kernel va to real phisical address /
physicalAddressBase = MmGetPhysicalAddress(myTable);
viewBase = physicalAddressBase;
mappedVirtualAddress = NULL;
ULONG size = sizeof(__int64)2044; //size of global static table
status = ZwMapViewOfSection (physicalMemorySectionHandle,
processHandle,
&mappedVirtualAddress,
0L,
size,
&viewBase,
&size,
ViewShare,
0,
PAGE_READWRITE | PAGE_NOCACHE);
if (!NT_SUCCESS(status))
{
status = ZwMapViewOfSection (physicalMemorySectionHandle,
processHandle,
&mappedVirtualAddress,
0L,
size,
&viewBase,
&size,
ViewShare,
0,
PAGE_READWRITE |PAGE_WRITECOMBINE);
}
if (!NT_SUCCESS(status))
{
status = ZwMapViewOfSection (physicalMemorySectionHandle,
processHandle,
&mappedVirtualAddress,
0L,
size,
&viewBase,
&size,
ViewShare,
0,
PAGE_READWRITE);
}
if (!NT_SUCCESS(status))
{
((PVOID)pVA) = NULL;
ZwClose(physicalMemorySectionHandle);
return;
}
//now size is 20480 – rounded up to 4kB boundary
mappedVirtualAddress = (PVOID)((ULONG)mappedVirtualAddress + (ULONG)physicalAddressBase.LowPart - (ULONG)viewBase.LowPart);
((PVOID)pVA) = mappedVirtualAddress;
ZwClose(physicalMemorySectionHandle);
return;
};
It looks everything works OK, but when I’m trying to read whole the table from user space application the result is as follow:
[Value] [Mapped Virtual Address (hex)]
0 348b58
1 348b60
2 348b68
3 348b70
4 348b78
5 348b80
6 348b88
7 348b90
8 348b98
9 348ba0
10 348ba8
11 348bb0
……….
652 349fb8
653 349fc0
654 349fc8
655 349fd0
656 349fd8
657 349fe0
658 349fe8
659 349ff0
660 349ff8
14757395258967641088 34a000 <- here is next page and problems begins
14757395258967641292 34a008
1507725027235463051 34a010
5028082440786512726 34a018
17889923897613475068 34a020
23678979336568832 34a028
3640333463937649408 34a030
277895171801089 34a038
……
The problem appears not always but very often. It always lies on the boundary of two pages. Usually first or first two pages are visible properly but third, fourth and next pages are totally wrong. The table is static and allocated in driver so it is for sure NONPAGED memory.
Is it a problem with Virtual Translation Table at user space side?
Why, in spite of usage ZwMapViewOfSection which maps 20480, third, fourth and following pages are not visible form user application?