(wdm.h) RtlCopyVolatileMemory 函式

例如,RtlCopyVolatileMemory 函式會提供 RtlCopyMemory 行為 (,例如) ,在開發人員需要確定複製作業發生 (的情況下,不會受限於編譯程式優化) 。

語法

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

參數

[out] Destination

所複製區塊目的地之起始位址的指標。

[in] Source

要複製之內存區塊起始位址的指標。

[in] Length

要複製的記憶體區塊大小,以位元組為單位。

傳回值

傳回 Destination 的值。

備註

RtlCopyVolatileMemory 函式具有下列屬性:

  • 函式無法辨識為編譯程式內部函數,因此編譯程式永遠不會完全優化呼叫 (,或將呼叫取代為) 的對等指令序列。 這與 RtlCopyMemory 不同,這受限於各種編譯程式優化。

  • 當呼叫傳回時,數據已從 來源 複製到 目的地。 此函式記憶體存取 來源目的地 只會在函式內執行 (例如,編譯程式無法將記憶體存取移出此函式) 。

  • 如果平台允許,函式可能會執行未對齊的記憶體存取。

  • 函式可能會在其複製作業中多次存取記憶體位置。

  • 它類似於 RtlCopyMemory ,因為它在 來源目的地 彼此重疊時不支援複製作業。

注意

此函式適用於所有版本的 Windows,而不只是最新版本。 您需要使用最新的 WDK,才能從 wdm.h 標頭取得函式宣告。 您也需要來自最新 WDK 的連結庫 (volatileaccessk.lib) 。 不過,產生的驅動程式會在舊版 Windows 上正常執行。

範例

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

}

規格需求

需求
標頭 wdm.h (包含 Wdm.h)
程式庫 volatileaccessk.lib (核心模式) 、volatileaccessu.lib (使用者模式)

另請參閱

RtlCopyMemory