RtlCopyVolatileMemory - NtDoc

Native API online documentation, based on the System Informer (formerly Process Hacker) phnt headers
// wdm.h

volatile void * RtlCopyVolatileMemory(
  [out] volatile void       *Destination,
  [in]  volatile const void *Source,
  [in]  size_t              Length
);
View the official Windows Driver Kit DDI reference

NtDoc

No description available.

Windows Driver Kit DDI reference (nf-wdm-rtlcopyvolatilememory)

Description

RtlCopyVolatileMemory function provides RtlCopyMemory behavior (for example, copying memory from one location to another) in situations where the developer needs to be sure that the copy operation occurs (for example, isn't subject to compiler optimizations).

Parameters

Destination [out]

A pointer to the starting address of the copied block's destination.

Source [in]

A pointer to the starting address of the block of memory to copy.

Length [in]

The size of the block of memory to copy, in bytes.

Return value

Returns the value of Destination.

Remarks

The RtlCopyVolatileMemory function has the following properties:

[!NOTE] This function works on all versions of Windows, not just the latest. You need to consume the latest WDK to get the function declaration from the wdm.h header. You also need the library (volatileaccessk.lib) from the latest WDK. However, the resulting driver will run fine on older versions of Windows.

Example

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

}

See also

RtlCopyMemory