Partager via


Fonction RtlMoveVolatileMemory (wdm.h)

La fonction RtlMoveVolatileMemory existe pour fournir un comportement RtlMoveMemory (par exemple, la copie de la mémoire d’un emplacement vers un autre) dans les situations où le développeur doit s’assurer que l’opération de copie se produit (par exemple, n’est pas soumise à des optimisations du compilateur). Contrairement à RtlCopyVolatileMemory, cette fonction gère les cas où la mémoire tampon source et la mémoire tampon de destination se chevauchent.

Syntaxe

volatile void * RtlMoveVolatileMemory(
  [out] volatile void       *Destination,
  [in]  volatile const void *Source,
  [in]  size_t              Length
);

Paramètres

[out] Destination

Pointeur vers l’adresse de départ de la destination du bloc copié.

[in] Source

Pointeur vers l’adresse de départ du bloc de mémoire à copier.

[in] Length

Taille du bloc de mémoire à copier, en octets.

Valeur retournée

Retourne la valeur de Destination.

Remarques

La fonction RtlMoveVolatileMemory possède les propriétés suivantes :

  • La fonction n’étant pas reconnue en tant qu’intrinsèque du compilateur, le compilateur n’optimisera jamais l’appel (soit entièrement, soit remplacez l’appel par une séquence d’instructions équivalente). Cela diffère de RtlMoveMemory qui est soumis à diverses optimisations du compilateur.

  • Lorsque l’appel est retourné, les données ont été copiées de la source vers la destination. Cette fonction permet d’accéder à la mémoire à la source et à la destination uniquement au sein de la fonction (par exemple, le compilateur ne peut pas déplacer les accès à la mémoire en dehors de cette fonction).

  • La fonction peut effectuer des accès à la mémoire non alignés si la plateforme le permet.

  • La fonction peut accéder aux emplacements de mémoire plusieurs fois dans le cadre de son opération de copie.

  • Semblable à RtlMoveMemory en ce qu’il prend en charge les opérations de copie lorsque source et destination se chevauchent.

Notes

Cette fonction fonctionne sur toutes les versions de Windows, pas seulement sur la dernière version. Vous devez utiliser le dernier WDK pour obtenir la déclaration de fonction à partir de l’en-tête wdm.h. Vous avez également besoin de la bibliothèque (volatileaccessk.lib) du dernier WDK. Toutefois, le pilote résultant s’exécute correctement sur les versions antérieures de Windows.

Exemple

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);

}

Configuration requise

Condition requise Valeur
En-tête wdm.h (inclure Wdm.h)
Bibliothèque volatileaccessk.lib (mode noyau), volatileaccessu.lib (mode utilisateur)

Voir aussi

RtlCopyVolatileMemory

RtlMoveMemory