Fonction RtlCopyVolatileMemory (wdm.h)
La fonction RtlCopyVolatileMemory fournit un comportement RtlCopyMemory (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).
Syntaxe
volatile void * RtlCopyVolatileMemory(
[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 RtlCopyVolatileMemory a les propriétés suivantes :
La fonction n’étant pas reconnue comme 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 RtlCopyMemory 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 plusieurs fois aux emplacements de mémoire dans le cadre de son opération de copie.
Il est similaire à RtlCopyMemory en ce qu’il ne prend pas 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 les versions les plus récentes. Vous devez utiliser la dernière clé 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) de la dernière 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
// 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);
}
Configuration requise
Condition requise | Valeur |
---|---|
En-tête | wdm.h (include Wdm.h) |
Bibliothèque | volatileaccessk.lib (mode noyau), volatileaccessu.lib (mode utilisateur) |