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 와 다릅니다.

  • 호출이 반환되면 데이터가 원본 에서 대상으로 복사됩니다. 이 함수는 원본대상 에 대한 메모리 액세스는 함수 내에서만 수행됩니다(예: 컴파일러는 이 함수에서 메모리 액세스를 이동할 수 없음).

  • 플랫폼이 허용하는 경우 함수는 정렬되지 않은 메모리 액세스를 수행할 수 있습니다.

  • 함수는 복사 작업의 일부로 메모리 위치에 두 번 이상 액세스할 수 있습니다.

  • 원본대상이 서로 겹칠 때 복사 작업을 지원하지 않는다는 측면에서 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);

}

요구 사항

요구 사항
헤더 wdm.h(Wdm.h 포함)
라이브러리 volatileaccessk.lib(커널 모드), volatileaccessu.lib(사용자 모드)

추가 정보

RtlCopyMemory