Función RtlMoveVolatileMemory (wdm.h)
La función RtlMoveVolatileMemory existe para proporcionar el comportamiento RtlMoveMemory (por ejemplo, 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 (por ejemplo, no está sujeta a optimizaciones del compilador). A diferencia de RtlCopyVolatileMemory, esta función controla los casos en los que el búfer de origen y destino se superponen.
Sintaxis
volatile void * RtlMoveVolatileMemory(
[out] volatile void *Destination,
[in] volatile const void *Source,
[in] size_t Length
);
Parámetros
[out] Destination
Puntero a la dirección inicial del destino del bloque copiado.
[in] Source
Puntero a la dirección inicial del bloque de memoria que se va a copiar.
[in] Length
Tamaño del bloque de memoria que se va a copiar, en bytes.
Valor devuelto
Devuelve el valor de Destination.
Comentarios
La función RtlMoveVolatileMemory tiene las siguientes propiedades:
La función no se reconoce como intrínseca del compilador, por lo que el compilador nunca optimizará la llamada (ya sea completamente o reemplazará la llamada por una secuencia equivalente de instrucciones). Esto difiere de RtlMoveMemory , que está sujeto a varias optimizaciones del compilador.
Cuando se devuelve la llamada, los datos se han copiado de Origen a Destino. Esta función funciona con accesos de memoria al origen yal destino solo se realizará dentro de la función (por ejemplo, el compilador no puede mover los accesos de memoria fuera de esta función).
La función puede realizar accesos a memoria no asignadas si la plataforma lo permite.
La función puede acceder a ubicaciones de memoria más de una vez como parte de su operación de copia.
De forma similar a RtlMoveMemory en que 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 versión más reciente. Debe consumir el WDK más reciente para obtener la declaración de función del encabezado wdm.h. También necesita la biblioteca (volatileaccessk.lib) del WDK más reciente. Sin embargo, el controlador 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
// RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// RtlMoveVolatileMemory 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;
RtlMoveVolatileMemory(&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 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 RtlFillMemory. It is possible the memory
// could have changed between the two accesses resulting in the size check
// being ineffective.
RtlFillMemory (RawBuffer, MyHeader.Size, 0);
}
Requisitos
Requisito | Valor |
---|---|
Header | wdm.h (incluya Wdm.h) |
Library | volatileaccessk.lib (modo kernel), volatileaccessu.lib (modo de usuario) |