From: partys on
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<size/sizeof(__int64); 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?

From: Don Burn on
People are already answering this on NTDEV where you posted the same
question earlier. But, several things to consider:

1. This is a really stupid idea, since it compromises security
2. Even if you are going to share using "\\Device\\PhysicalMemory" is
really a poor idea
3. You are not guaranteed contigous pages which you seem to be expecting

Really why in the world do you want to do this, you are breaking security,
making a much more complex driver (especially with everything you need to
cleanup when the app goes away), and not going to get any performance
increase unless you are talking huge areas, where you will have other
problems.



--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply


"partys" <partys(a)discussions.microsoft.com> wrote in message
news:53F235D1-CDE0-4A59-8F74-50E4C233C225(a)microsoft.com...
> 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<size/sizeof(__int64); 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?
>