Função RtlMoveVolatileMemory (wdm.h)
A função RtlMoveVolatileMemory existe para fornecer o comportamento RtlMoveMemory (por exemplo, copiar memória de um local para outro) em situações em que o desenvolvedor precisa ter certeza de que a operação de cópia ocorre (por exemplo, não está sujeita a otimizações do compilador). Ao contrário de RtlCopyVolatileMemory, essa função lida com casos em que o buffer de origem e destino se sobrepõe.
Sintaxe
volatile void * RtlMoveVolatileMemory(
[out] volatile void *Destination,
[in] volatile const void *Source,
[in] size_t Length
);
Parâmetros
[out] Destination
Um ponteiro para o endereço inicial do destino do bloco copiado.
[in] Source
Um ponteiro para o endereço inicial do bloco de memória a ser copiado.
[in] Length
O tamanho do bloco de memória a ser copiado, em bytes.
Retornar valor
Retorna o valor de Destination.
Comentários
A função RtlMoveVolatileMemory tem as seguintes propriedades:
A função não é reconhecida como um compilador intrínseco, portanto, o compilador nunca otimizará a chamada (seja inteiramente ou substituirá a chamada por uma sequência equivalente de instruções). Isso difere de RtlMoveMemory , que está sujeito a várias otimizações do compilador.
Quando a chamada retorna, os dados foram copiados de Origem para Destino. Essas funções de acesso de memória à Origem e ao Destino só serão executadas dentro da função (por exemplo, o compilador não pode mover acessos de memória para fora dessa função).
A função poderá executar acessos de memória não assinados se a plataforma permitir.
A função pode acessar locais de memória mais de uma vez como parte de sua operação de cópia.
Semelhante a RtlMoveMemory em que ele dá suporte a operações de cópia quando Source e Destination se sobrepõem.
Observação
Essa função funciona em todas as versões do Windows, não apenas nas mais recentes. Você precisa consumir o WDK mais recente para obter a declaração de função do cabeçalho wdm.h. Você também precisa da biblioteca (volatileaccessk.lib) do WDK mais recente. No entanto, o driver resultante será executado bem em versões mais antigas do Windows.
Exemplo
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 |
---|---|
Cabeçalho | wdm.h (inclua Wdm.h) |
Biblioteca | volatileaccessk.lib (modo Kernel), volatileaccessu.lib (modo usuário) |