Condividi tramite


Funzione CopyVolatileMemory

La funzione CopyVolatileMemory copia il contenuto di un blocco di memoria di origine in un blocco di memoria di destinazione.

Importante

Alcune informazioni riguardano un prodotto in versione preliminare che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Parametri

Destinazione param [out]

Puntatore all'indirizzo iniziale della destinazione del blocco copiato.

Origine param [in]

Puntatore all'indirizzo iniziale del blocco di memoria da copiare.

Lunghezza param [in]

Dimensione del blocco di memoria da copiare, in byte.

Sintassi

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

Osservazioni:

Questa API esiste per fornire un comportamento CopyMemory (ovvero la copia della memoria da una posizione a un'altra) in situazioni in cui lo sviluppatore deve assicurarsi che l'operazione di copia si verifichi (ad esempio, non è soggetta alle ottimizzazioni del compilatore).

L'API ha le proprietà seguenti:

  • L'API non viene riconosciuta come un compilatore intrinseco, quindi il compilatore non ottimizza mai la chiamata (interamente o sostituisce la chiamata con una sequenza di istruzioni "equivalente"). Questo comportamento è diverso da CopyMemory , soggetto a un'ampia gamma di ottimizzazioni del compilatore.
  • Al termine della chiamata, i dati sono stati copiati da Origine a Destinazione. Questa funzione consente l'accesso alla memoria all'origine e alla destinazione solo all'interno della funzione, ovvero il compilatore non può spostare gli accessi alla memoria da questa funzione.
  • L'API può eseguire accessi in memoria non idonei se la piattaforma lo consente.
  • L'API può accedere ai percorsi di memoria più di una volta come parte dell'operazione di copia.
  • Analogamente a CopyMemory , in quanto non supporta le operazioni di copia quando l'origine e la destinazione si sovrappongono tra loro.

Nota

Questa funzione funziona su tutte le versioni di Windows, non solo sulla versione più recente. È necessario usare l'SDK più recente per ottenere la dichiarazione di funzione dall'intestazione winbase.h . È necessaria anche la libreria (volatileaccessu.lib) dall'SDK più recente. Tuttavia, il file binario risultante verrà eseguito correttamente nelle versioni precedenti di Windows.

Esempio

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

Requisiti

Client minimo supportato: Windows 11 Insider Preview Build TBD

Intestazione: winbase.h (include Winbase.h)

Libreria in modalità kernel: volatileaccessk.lib

Libreria in modalità utente: volatileaccessu.lib

Vedi anche