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