用户模式和内核模式之间的共享内存

Ste*_*san 9 c++ windows winapi shared-memory kernel32

我正在为Windows7编写一些内核端代码来访问在用户模式下创建的共享内存,如此处所示.
共享内存在用户空间中创建,名称为:

"MySharedMem"
Run Code Online (Sandbox Code Playgroud)

在用户空间中打开共享内存有效.
在内核模式下打开相同的共享内存调用 ZwOpenSection失败返回:

#define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034L)
Run Code Online (Sandbox Code Playgroud)

内核代码是:

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;
}
Run Code Online (Sandbox Code Playgroud)

我尝试了几个名字(L"\\MySharedMem"L"MySharedMem"),但我得到了其他错误STATUS_OBJECT_PATH_INVALIDSTATUS_OBJECT_PATH_NOT_FOUND.
同时创建共享内存"Global\\MySharedMem"不起作用.

我究竟做错了什么?

我尝试在内核模式下创建共享内存,我获得了成功ZwCreateSection,ZwMapViewOfSection但是当我访问pSharedData_指针来测试缓冲区时,我得到了访问冲突:

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;
}
Run Code Online (Sandbox Code Playgroud)

一切都失败了......

the*_*heB 5

关于CreateFileMapping

从非零会话的会话在全局名称空间中创建文件映射对象需要SeCreateGlobalPrivilege特权。

KB191840

对象总是映射在进程的用户地址空间中(低于0x80000000)(无论对象是在内核模式还是在用户模式下创建),只有在进程上下文中访问该地址时,该地址才有效。

KB继续:

不建议使用此方法,并且至少由低级设备驱动程序使用此方法,因为如前所述,地址的范围仅限于映射对象的过程,并且不能在DPC或ISR中访问该方法。[重点矿]

解决方法是:

  1. 在内核模式下创建文件映射。(由知识库文章建议。)
  2. 使用IOCTL