9

I am writing some kernel side code for Windows7 to access shared memory created in user mode, as suggested here.
The shared memory is created in user space with name:

"MySharedMem"

Opening the shared memory in user space works.
Opening the same shared memory in kernel mode calling ZwOpenSection fails returning:

#define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034L)

The kernel code is:

NTSTATUS CModule1::OpenShared()
{
SIZE_T vs = 256;
WCHAR stringBuffer[] =  L"\\BaseNamedObjects\\MySharedMem";
UNICODE_STRING  sectionName;

RtlInitUnicodeString(&sectionName,stringBuffer);

OBJECT_ATTRIBUTES myAttributes;

InitializeObjectAttributes(&myAttributes,&sectionName,0,NULL,NULL);
NTSTATUS status0 = ZwOpenSection(&sectionHandle_,SECTION_MAP_READ|SECTION_MAP_WRITE,&myAttributes);

NTSTATUS status = ZwMapViewOfSection(&sectionHandle_, ZwCurrentProcess(), (PVOID *)&pSharedData_, 0, 0, NULL, &vs, ViewShare, 0, PAGE_READWRITE); 
return status;
}

I tried several names (L"\\MySharedMem" or L"MySharedMem") but I got other errors as STATUS_OBJECT_PATH_INVALID or STATUS_OBJECT_PATH_NOT_FOUND.
Also creating the shared memory as "Global\\MySharedMem" does not work.

What am I doing wrong?

I tried to create the shared memory in kernel mode, I get success on ZwCreateSection and ZwMapViewOfSection but i get access violation when I access the pSharedData_ pointer to test the buffer:

NTSTATUS CModule1::MapUserSection()
{
typedef struct SHARED_SECTION {DWORD i; };
NTSTATUS status = STATUS_SUCCESS;
ULONG Attributes=OBJ_KERNEL_HANDLE | OBJ_FORCE_ACCESS_CHECK;

OBJECT_ATTRIBUTES objectAttributes;
LARGE_INTEGER MaxSize;
SIZE_T ViewSize=sizeof(SHARED_SECTION);
MaxSize.QuadPart=sizeof(SHARED_SECTION);

WCHAR stringBuffer[] =  L"\\MySm2";
UNICODE_STRING  sectionName;
RtlInitUnicodeString(&sectionName,stringBuffer);
InitializeObjectAttributes(&objectAttributes,&sectionName,Attributes,NULL,NULL);

status= ZwCreateSection(&sectionHandle_,SECTION_ALL_ACCESS,&objectAttributes,&MaxSize,PAGE_READWRITE,SEC_COMMIT,NULL);
status = ZwMapViewOfSection(sectionHandle_, ZwCurrentProcess(), (PVOID *)&pSharedData_, 0, 0, NULL, &ViewSize, ViewShare, 0, PAGE_READWRITE); 

//To test the buffer
RtlFillMemory(pSharedData_, '1',ViewSize);
return status;
}

Everything fails...

Stefano Piovesan
  • 1,185
  • 3
  • 19
  • 37
  • 1
    May be related, Every time I do something like this my names start with either `"Local\\"` or `"Global\\"`, you may need to append `"Local\\"` to the front of your names. – Serdalis Sep 15 '15 at 22:00
  • 1
    You would presumably need to use `Global\MySharedMem` when creating the file mapping. Once you've done that, use `winobj` (available from the MS web site) to look through the kernel namespace and find it. – Harry Johnston Sep 15 '15 at 22:19
  • 1
    I tried this creating the shared memory in user space with `Global\\MySharedMemame` but in this case I get the error `STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003BL` – Stefano Piovesan Sep 16 '15 at 07:09
  • 1
    What did `winobj` find? – Harry Johnston Sep 16 '15 at 22:11

1 Answers1

5

Concerning CreateFileMapping:

Creating a file mapping object in the global namespace from a session other than session zero requires the SeCreateGlobalPrivilege privilege.

From KB191840:

[T]he object is always mapped in the user address space (below 0x80000000) of a process (regardless of whether the object is created in kernel mode or user mode) the address is valid only if it is accessed in the context of the process.

The KB continues:

This method is not recommended and is used least by low-level device drivers because, as explained earlier, the scope of the address is limited to the process in which the object is mapped, and it cannot be accessed in a DPC or ISR. [Emphasis Mine]

The fix is either:

  1. Create the file mapping in kernel mode. (Suggested by the KB article.)
  2. Use IOCTL
theB
  • 6,450
  • 1
  • 28
  • 38
  • 1
    I tried to create the shared memory in kernel mode, but it fails when accessing the data pointer. I wiil try IOCTL. – Stefano Piovesan Sep 16 '15 at 19:19
  • 1
    Now I understand your comment (x64): the object `obj` allocated in the driver has this address `0xffffe000d44ae510`, while the shared memory pointer `pSM` is here at `0x000000e81bf20000`. `pSM` address can not be accessed from `obj` in the kernel code. – Stefano Piovesan Sep 17 '15 at 15:29
  • 1
    I found the sample code [here](http://www.winvistatips.com/threads/how-to-share-a-section-between-driver-and-user-mode-application.192587/) that I assumed it was working... – Stefano Piovesan Sep 17 '15 at 15:36