Função CopyVolatileMemory
A função CopyVolatileMemory copia o conteúdo de um bloco de memória de origem para um bloco de memória de destino.
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
Parâmetro Destination [saída]
Um ponteiro para o endereço inicial do destino do bloco copiado.
Parâmetro Source [entrada]
Um ponteiro para o endereço inicial do bloco de memória que será copiado.
Parâmetro Length [entrada]
O tamanho do bloco de memória a ser copiado, em bytes.
Sintaxe
volatile void* __cdecl
CopyVolatileMemory (
_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 oferecer um comportamento CopyMemory (ou seja, copiar memória de um local para outro) em situações em que os desenvolvedores precisam ter certeza de que a operação de cópia ocorre (ou seja, não está sujeita a otimizações do compilador).
A API possui as seguintes características:
- A API não é reconhecida como uma função intrínseca do compilar, portanto, o compilador nunca otimizará a chamada (seja totalmente ou substituindo a chamada por uma sequência "equivalente" de instruções). Isso difere de CopyMemory, que está sujeito a uma variedade de otimizações do compilador.
- Quando a chamada retorna, os dados foram copiados da Source para o Destination. Os acessos à memória desta função a Source e Destination só serão realizados dentro da função (ou seja, o compilador não pode mover acessos à memória para fora desta função).
- A API pode realizar 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.
- Semelhante a CopyMemory, no sentido que de que não suporta operações de cópia quando Source e Destination se sobrepõem.
Observação
Esta função é compatível com todas as versões do Windows, não apenas as mais recentes. Você precisa utilizar 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. Contudo, o binário resultante funcionará corretamente em versões anteriores 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
// 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 com suporte: Windows 11 Insider Preview Build TBD
Cabeçalho: winbase.h (inclua Winbase.h)
Biblioteca em modo kernel: volatileaccessk.lib
Biblioteca em modo de usuário: volatileaccessu.lib