MoveVolatileMemory-Funktion

Kopiert den Inhalt eines Quellspeicherblocks in einen Zielspeicherblock und unterstützt überlappende Quell- und Zielspeicherblöcke.

Wichtig

Einige Informationen beziehen sich auf Vorabversionen, die vor der kommerziellen Freigabe grundlegend geändert werden können. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.

Parameter

Parameterziel [out]

Ein Zeiger auf die Startadresse am Ziel des kopierten Blocks.

Parameterquelle [in]

Ein Verweis auf die Startadresse des Speicherblocks, der kopiert werden soll.

Parameterlänge [in]

Die Größe des zu kopierenden Speicherblocks in Byte.

Syntax

volatile void* __cdecl
  MoveVolatileMemory (
    _Out_writes_bytes_all_(Length) volatile void* Destination,
    _In_reads_bytes_(Length) volatile const void* Source,
    SIZE_T Length
  );

Hinweise

Diese API stellt das MoveMemory-Verhalten (d. h. das Kopieren des Speichers von einem Speicherort in einen anderen) in Situationen bereit, in denen Entwickler*innen sicherstellen müssen, dass der Kopiervorgang durchgeführt wird (d. h., er unterliegt nicht Compileroptimierungen). Im Gegensatz zu CopyVolatileMemory behandelt diese API Fälle, in denen sich der Quell- und Zielpuffer überlappen.

Die API verfügt über die folgenden Eigenschaften:

  • Die API wird nicht als systeminterner Compiler erkannt, wodurch der Aufruf niemals durch Optimierungen des Compilers entfernt wird, die den Aufruf vollständig entfernen oder mit einer equivalent-Anweisungssequenz ersetzen würden. Dies ist ein Unterschied zu MoveMemory, das einer Vielzahl von Compileroptimierungen unterliegt.
  • Wenn der Aufruf zurückgegeben wird, wurden die Daten aus der Quelle in das Ziel kopiert. Der Speicherzugriff dieser Funktion auf die Quelle und das Ziel gilt nur innerhalb der Funktion (d. h., der Compiler kann Speicherzugriffe nicht aus dieser Funktion verschieben).
  • Die API kann möglicherweise nicht ausgerichtete Zugriffe auf den Arbeitsspeicher ausführen, sofern die Plattform dies zulässt.
  • Die API kann im Rahmen des Kopiervorgangs mehrmals auf Speicherspeicherorte zugreifen.
  • Ähnlich wie MoveMemory, da Kopiervorgänge unterstützt werden, wenn Quelle und Ziel sich gegenseitig überlappen

Hinweis

Diese Funktion funktioniert nicht nur unter der neuesten Windows-Version, sondern unter allen Versionen. Sie müssen das neueste SDK verwenden, um die Funktionsdeklaration aus dem winbase.h-Header abzurufen. Außerdem benötigen Sie die Bibliothek (volatileaccessu.lib) aus dem neuesten SDK. Die resultierende Binärdatei wird jedoch in älteren Versionen von Windows problemlos ausgeführt.

Beispiel

HEADER MyHeader;
UCHAR RawBuffer[100];

// Ensure that the shared memory (which could be constantly changing)
// is copied in to the local MyHeader variable.
// Note that the compiler is allowed to optimize away calls to
// MoveMemory/RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// MoveVolatileMemory does handle
// buffers that overlap with each other (MoveMemory semantics).
// Assume SharedMemory points to virtual memory that is also mapped in an untrusted process.
// Assume that untrusted process is changing the memory contents while you are accessing it.
PVOID SharedMemory;

MoveVolatileMemory(&MyHeader, SharedMemory, sizeof(MyHeader));

if (MyHeader.Size < 100) {
  // Because MyHeader is local and we are guaranteed we actually made
  // a local copy, we can be sure that the "Size" value will not change
  // between the previous bounds check and the below call to RtlFillMemory.
  // If RtlMoveMemory/RtlMoveMemory had been used to copy the data, it is possible
  // that a compiler may optimize away the call to MoveMemory and instead fetch
  // the “size” field of MyHeader directly from untrusted memory two times.
  // The first time it would be fetched for the bounds check, and the second
  // time it is fetched is for the call to FillMemory. It is possible the memory
  // could have changed between the two accesses resulting in the size check
  // being ineffective.

  FillMemory (RawBuffer, MyHeader.Size, 0);
}

Anforderungen

Unterstützte Mindestversion (Client): Windows 11 Insider Preview Build TBD

Header: winbase.h (Winbase.h eingeschlossen)

Kernelmodusbibliothek: volatileaccessk.lib

Benutzermodusbibliothek: volatileaccessu.lib

Siehe auch