Share via


MoveVolatileMemory 함수

원본 메모리 블록의 내용을 대상 메모리 블록에 복사하고 겹치는 원본 및 대상 메모리 블록을 지원합니다.

Important

일부 정보는 상용 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.

매개 변수

Param Destination [out]

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

Param 원본 [in]

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

Param Length [in]

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

구문

volatile void* __cdecl
  MoveVolatileMemory (
    _Out_writes_bytes_all_(Length) volatile void* Destination,
    _In_reads_bytes_(Length) volatile const void* Source,
    SIZE_T Length
  );

설명

이 API는 개발자가 복사 작업이 발생하도록 해야 하는 경우(즉, 컴파일러 최적화의 대상이 아님) MoveMemory 동작(즉, 한 위치에서 다른 위치로 메모리 복사)을 제공하기 위해 존재합니다. CopyVolatileMemory와 달리 이 API는 원본대상 버퍼가 겹치는 경우를 처리합니다.

API에는 다음과 같은 속성이 있습니다.

  • API는 컴파일러 내장 함수로 인식되지 않으므로 컴파일러가 호출을 최적화하지 않습니다(호출을 완전히 또는 "동등한" 명령 시퀀스로 대체). 이는 다양한 컴파일러 최적화가 적용되는 MoveMemory와 다릅니다.
  • 호출이 반환되면 데이터가 원본에서 대상으로 복사됩니다. 원본대상대한 이 함수 메모리 액세스는 함수 내에서만 수행됩니다(즉, 컴파일러가 이 함수에서 메모리 액세스를 이동할 수 없음).
  • 플랫폼이 허용하는 경우 API는 정렬되지 않은 메모리 액세스를 수행할 수 있습니다.
  • API는 복사 작업의 일부로 메모리 위치에 두 번 이상 액세스할 수 있습니다.
  • 원본과 대상이 서로 겹칠 때 복사 작업을 지원한다는 측면에서 MoveMemory유사합니다.

참고 항목

이 함수는 최신 버전뿐만 아니라 모든 버전의 Windows에서 작동합니다. 헤더에서 함수 선언을 얻으려면 최신 SDK를 winbase.h 사용해야 합니다. 최신 SDK의 라이브러리(volatileaccessu.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
// MoveMemory/RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// MoveVolatileMemory 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;

MoveVolatileMemory(&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/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 FillMemory. It is possible the memory
  // could have changed between the two accesses resulting in the size check
  // being ineffective.

  FillMemory (RawBuffer, MyHeader.Size, 0);
}

요구 사항

지원되는 최소 클라이언트: Windows 11 Insider Preview 빌드 TBD

헤더: winbase.h(Winbase.h 포함)

커널 모드 라이브러리: volatileaccessk.lib

사용자 모드 라이브러리: volatileaccessu.lib

참고 항목