RtlCopyVolatileMemory 関数 (wdm.h)

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 とは異なります。

  • 呼び出しが返されると、データは Source から Destination にコピーされます。 この関数は 、SourceDestination へのメモリ アクセスを関数内でのみ実行します (たとえば、コンパイラはこの関数からメモリ アクセスを移動できません)。

  • プラットフォームで許可されている場合、関数は整列されていないメモリ アクセスを実行できます。

  • 関数は、コピー操作の一環としてメモリの場所に複数回アクセスできます。

  • これは RtlCopyMemory に似ていますが、 コピー元コピー先 が互いに重なっている場合はコピー操作をサポートしません。

注意

この関数は、最新バージョンだけでなく、すべてのバージョンの Windows で動作します。 wdm.h ヘッダーから関数宣言を取得するには、最新の WDK を使用する必要があります。 また、最新の 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);

}

要件

要件
Header wdm.h (Wdm.h を含む)
Library volatileaccessk.lib (カーネル モード)、volatileaccessu.lib (ユーザー モード)

こちらもご覧ください

RtlCopyMemory