2015-09-15 18 views
8

Ich schreibe einige Kernel-Side-Code für Windows7 auf gemeinsam genutzten Speicher im Benutzermodus erstellt, wie vorgeschlagen here.
Der gemeinsam genutzte Speicher wird im User-Space mit dem Namen erstellt:Gemeinsamer Speicher zwischen Benutzermodus und Kernel-Modus

"MySharedMem" 

den gemeinsam genutzten Speicher im User-Space Arbeiten Öffnungs.
den gleichen gemeinsamen Speicher im Kernel-Modus öffnen ZwOpenSection Aufruf fehlschlägt Rückkehr:

#define STATUS_OBJECT_NAME_NOT_FOUND  ((NTSTATUS)0xC0000034L) 

Der Kernel-Code ist:

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; 
} 

ich mehrere Namen versucht (L"\\MySharedMem" oder L"MySharedMem"), aber ich habe andere Fehler als STATUS_OBJECT_PATH_INVALID oder STATUS_OBJECT_PATH_NOT_FOUND.
Auch das Erstellen des gemeinsamen Speichers als "Global\\MySharedMem" funktioniert nicht.

Was mache ich falsch?

Ich habe versucht, den gemeinsam genutzten Speicher im Kernel-Modus zu erstellen, bekomme ich Erfolg auf ZwCreateSection und ZwMapViewOfSection aber ich Zugriffsverletzung, wenn ich den pSharedData_ Zeiger Zugriff auf den Puffer zu testen:

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; 
} 

Alles versagt ...

+0

zusammenhänge, Jedesmal, wenn ich so etwas tun beginnen meine Namen entweder mit '„Local \\“' oder '„Globalen \\“', Möglicherweise müssen Sie '" Local \\ "' an die Vorderseite Ihrer Namen anhängen. – Serdalis

+0

Sie müssten vermutlich 'Global \ MySharedMem' beim Erstellen der Dateizuordnung verwenden. Sobald Sie dies getan haben, verwenden Sie 'winobj' (verfügbar auf der MS-Website), um durch den Kernel-Namespace zu suchen und ihn zu finden. –

+0

Ich habe versucht, den Shared Memory im Benutzerbereich mit 'Global \\ MySharedMemame' zu ​​erstellen, aber in diesem Fall bekomme ich den Fehler' STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003BL' –

Antwort

4

Bezüglich CreateFileMapping:

ein Dateizuordnungsobjekts im globalen Namespace Erstellen von einer Sitzung anderen th Eine Sitzung Null erfordert das Privileg SeCreateGlobalPrivilege.

Von KB191840:

[D] ie Objekt immer in dem Benutzeradressraum abgebildet wird (unter 0x80000000) einem Prozess (unabhängig davon, ob das Objekt im Kernel-Modus oder im Benutzermodus erstellt wird) Die Adresse ist nur gültig, wenn auf sie im Kontext des Prozesses zugegriffen wird.

Die KB weiter:

Diese Methode ist nicht empfohlen und wird verwendet, dest durch Low-Level-Gerätetreiber, da, wie bereits erläutert, der Schutzbereich der Adresse auf den Prozess beschränkt ist in dem das Objekt zugeordnet ist und auf das in einem DPC oder ISR nicht zugegriffen werden kann. [Hervorhebung von mir]

Das Update ist entweder:

  1. Erstellen Sie die Dateizuordnung im Kernel-Modus. (Vorgeschlagen von dem KB-Artikel.)
  2. Verwenden IOCTL
+0

Ich habe versucht, den freigegebenen Speicher im Kernelmodus zu erstellen, aber es schlägt fehl, wenn auf den Datenzeiger zugegriffen wird. Ich werde IOCTL versuchen. –

+0

Jetzt verstehe ich Ihren Kommentar (x64): das Objekt 'obj' im Treiber zugeordnet hat diese Adresse' 0xffffe000d44ae510', während der Shared Memory Pointer 'pSM' ist hier bei' 0x000000e81bf20000'. Auf 'pSM'-Adresse kann nicht von 'obj' im Kernel-Code zugegriffen werden. –

+0

Ich fand den Beispielcode [hier] (http://www.winvistatips.com/threads/how-to-share-a-section-between-driver-and-user-mode-application.192587/), den ich annahm es hat funktioniert ... –