Compartilhar via


Função RtlCopyVolatileMemory (wdm.h)

A função RtlCopyVolatileMemory fornece o comportamento RtlCopyMemory (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).

Sintaxe

volatile void * RtlCopyVolatileMemory(
  [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 RtlCopyVolatileMemory 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 RtlCopyMemory , 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 RtlCopyMemory , pois não dá suporte a operações de cópia quando a origem e o destino 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
// RtlCopyMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// RtlCopyVolatileMemory does not handle a source/dest buffer that overlap
// with each other (RtlCopyMemory 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;

RtlCopyVolatileMemory(&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 had been used to copy the data, it is possible
    // that a compiler may optimize away the call to RtlCopyMemory 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)

Confira também

RtlCopyMemory