Share via


Función CopyVolatileMemory

La función CopyVolatileMemory copia el contenido de un bloque de memoria de origen en un bloque de memoria de destino.

Importante

Parte de la información hace referencia a un producto de versión preliminar que puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Parámetros

Destino del parámetro [out]

Un puntero a la dirección inicial del destino del bloque copiado.

Origen del parámetro [in]

Un puntero a la dirección inicial del bloque de memoria que se va a copiar.

Longitud del parámetro [in]

El tamaño del bloque de memoria que se va a copiar, en bytes.

Sintaxis

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

Comentarios

Esta API existe para proporcionar el comportamiento de CopyMemory (es decir, copiar memoria de una ubicación a otra) en situaciones en las que el desarrollador debe asegurarse de que se produce la operación de copia (es decir, no está sujeta a optimizaciones del compilador).

La API tiene las siguientes propiedades:

  • La API no se reconoce como intrínseca del compilador, por lo que este nunca optimizará la llamada (ya sea por completo o reemplazándola por una secuencia "equivalente" de instrucciones). Esto difiere de CopyMemory, que está sujeto a una variedad de optimizaciones del compilador.
  • Cuando se devuelve la llamada, los datos se han copiado de Origen a Destino. Esta función solo accederá a la memoria de Origen y Destino dentro de la función (es decir, el compilador no puede mover los accesos de memoria fuera de esta función).
  • La API puede realizar accesos a memoria no asignadas si la plataforma lo permite.
  • La API puede acceder a ubicaciones de memoria más de una vez como parte de su operación de copia.
  • Similar a CopyMemory en que no admite operaciones de copia cuando Origen y Destino se superponen entre sí.

Nota:

Esta función funciona en todas las versiones de Windows, no solo en la más reciente. Debe consumir el SDK más reciente para obtener la declaración de función del encabezado winbase.h. También necesita la biblioteca (volatileaccessu.lib) del SDK más reciente. Sin embargo, el binario resultante se ejecutará correctamente en versiones anteriores de Windows.

Ejemplo

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

Requisitos

Cliente mínimo admitido: compilación TBD de Windows 11 Insider Preview

Encabezado: winbase.h (incluya Winbase.h)

Biblioteca en modo kernel: volatileaccessk.lib

Biblioteca en modo de usuario: volatileaccessu.lib

Consulte también