Função MoveVolatileMemory
Copia o conteúdo de um bloco de memória de origem para um bloco de memória de destino e dá suporte a blocos de memória de origem e de destino sobrepostos.
Importante
Algumas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Parâmetros
Destino do param [saída]
Um ponteiro para o endereço inicial do destino do bloco copiado.
Origem do param [entrada]
Um ponteiro para o endereço inicial do bloco de memória a ser copiado.
Comprimento do param [entrada]
O tamanho do bloco de memória a ser copiado, em bytes.
Sintaxe
volatile void* __cdecl
MoveVolatileMemory (
_Out_writes_bytes_all_(Length) volatile void* Destination,
_In_reads_bytes_(Length) volatile const void* Source,
SIZE_T Length
);
Comentários
Essa API existe para fornecer comportamento MoveMemory (ou seja, 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 (ou seja, não está sujeita a otimizações do compilador). Ao contrário de CopyVolatileMemory, essa API lida com casos em que o buffer de Origem e de Destino se sobrepõem.
A API tem as seguintes propriedades:
- A API não é reconhecida como um compilador intrínseco, portanto, o compilador nunca otimizará a chamada (seja totalmente ou substituindo a chamada por uma sequência "equivalente" de instruções). Isso difere de MoveMemory, que está sujeito a uma variedade de otimizações do compilador.
- Quando a chamada retorna, os dados foram copiados da Origem para o Destino. Os acessos à Origem e ao Destino da memória dessa função só serão executados dentro da função (ou seja, o compilador não pode mover os acessos à memória para fora dessa função).
- A API poderá executar acessos à memória não alinhados se a plataforma permitir.
- A API pode acessar locais de memória mais de uma vez como parte da operação de cópia dela.
- Semelhante ao MoveMemory, no sentido de que dá suporte a operações de cópia quando a Origem e o Destino se sobrepõem
Observação
Esta função funciona em todas as versões do Windows, não apenas na mais recente. Você precisa consumir o SDK mais recente para obter a declaração de função do cabeçalho winbase.h
. Você também precisa da biblioteca (volatileaccessu.lib
) do SDK mais recente. No entanto, o binário 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
// MoveMemory/RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// MoveVolatileMemory 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;
MoveVolatileMemory(&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/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 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 suportado: Windows 11 Insider Preview Build TBD
Cabeçalho: winbase.h (incluir Winbase.h)
Biblioteca de modo kernel: volatileaccessk.lib
Biblioteca de modo de usuário: volatileaccessu.lib