CopyVolatileMemory-Funktion
Die CopyVolatileMemory-Funktion kopiert den Inhalt eines Quellspeicherblocks in einen Zielspeicherblock.
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
CopyVolatileMemory (
_Out_writes_bytes_all_(Length) volatile void* Destination,
_In_reads_bytes_(Length) volatile const void* Source,
SIZE_T Length
);
Hinweise
Diese API stellt das CopyMemory-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).
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 CopyMemory, 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 CopyMemory, da Kopiervorgänge nicht 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
// CopyMemory/RtlCopyMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// CopyVolatileMemory does not handle a source/dest buffer that overlap
// with each other (CopyMemory 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;
CopyVolatileMemory(&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 RtlCopyMemory/RtlCopyMemory had been used to copy the data, it is possible
// that a compiler may optimize away the call to CopyMemory 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