RtlMoveVolatileMemory 함수(wdm.h)

RtlMoveVolatileMemory 함수는 개발자가 복사 작업이 발생하는지 확인해야 하는 상황에서 RtlMoveMemory 동작(예: 한 위치에서 다른 위치로 메모리 복사)을 제공하기 위해 존재합니다(예: 컴파일러 최적화의 적용을 받지 않음). RtlCopyVolatileMemory와 달리 이 함수는 원본대상 버퍼가 겹치는 경우를 처리합니다.

구문

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

매개 변수

[out] Destination

복사된 블록 대상의 시작 주소에 대한 포인터입니다.

[in] Source

복사할 메모리 블록의 시작 주소에 대한 포인터입니다.

[in] Length

복사할 메모리 블록의 크기(바이트)입니다.

반환 값

Destination 값을 반환 합니다.

설명

RtlMoveVolatileMemory 함수에는 다음과 같은 속성이 있습니다.

  • 함수는 컴파일러 내장 함수로 인식되지 않으므로 컴파일러는 호출을 최적화하지 않습니다(호출을 완전히 또는 동등한 명령 시퀀스로 대체). 이는 다양한 컴파일러 최적화의 적용을 받는 RtlMoveMemory 와 다릅니다.

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

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

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

  • 원본대상이 서로 겹칠 때 복사 작업을 지원한다는 측면에서 RtlMoveMemory와 유사합니다.

참고

이 함수는 최신 버전뿐만 아니라 모든 버전의 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
// RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// RtlMoveVolatileMemory does handle buffers 
// that overlap with each other (MoveMemory 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;

RtlMoveVolatileMemory(&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 RtlMoveMemory had been used to copy the data, it is possible
    // that a compiler may optimize away the call to MoveMemory 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(사용자 모드)

추가 정보

RtlCopyVolatileMemory

RtlMoveMemory