Функция CopyVolatileMemory
Функция CopyVolatileMemory копирует содержимое блока исходной памяти в блок целевой памяти.
Важно!
Некоторые сведения относятся к предварительному продукту, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Параметры
Назначение Param [out]
Указатель на начальный адрес места назначения скопированного блока.
Источник Param [in]
Указатель на начальный адрес блока памяти для копирования.
Длина param [in]
Размер блока памяти для копирования в байтах.
Синтаксис
volatile void* __cdecl
CopyVolatileMemory (
_Out_writes_bytes_all_(Length) volatile void* Destination,
_In_reads_bytes_(Length) volatile const void* Source,
SIZE_T Length
);
Замечания
Этот API существует для обеспечения поведения CopyMemory (т. е. копирования памяти из одного расположения в другое) в ситуациях, когда разработчик должен убедиться, что операция копирования возникает (т. е. не подлежит оптимизации компилятора).
API имеет следующие свойства:
- API не распознается как встроенный компилятор, поэтому компилятор никогда не оптимизирует вызов (полностью или замените вызов эквивалентной последовательностью инструкций). Это отличается от CopyMemory, которое зависит от различных оптимизаций компилятора.
- Когда вызов возвращается, данные копируются из источника в назначение. Эти функции, доступ к памяти к источнику и назначению , будут выполняться только в функции (т. е. компилятор не может перемещать доступ к памяти из этой функции).
- API может выполнять неподготовленный доступ к памяти, если платформа позволяет ей.
- API может получить доступ к расположениям памяти более одного раза в рамках операции копирования.
- Аналогично CopyMemory в том, что он не поддерживает операции копирования, когда источник и назначение перекрываются друг с другом.
Примечание.
Эта функция работает во всех версиях Windows, а не только на последних версиях. Чтобы получить объявление функции из заголовка winbase.h
, необходимо использовать последний пакет SDK. Вам также нужна библиотека (volatileaccessu.lib
) из последнего пакета SDK. Однако результирующий двоичный файл будет работать в более ранних версиях 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
// CopyMemory/RtlCopyMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// CopyVolatileMemory does not handle a source/dest buffer that overlap
// with each other (CopyMemory 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;
CopyVolatileMemory(&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/RtlCopyMemory had been used to copy the data, it is possible
// that a compiler may optimize away the call to CopyMemory 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);
}
Requirements
Минимальный поддерживаемый клиент: сборка предварительной версии Windows 11 Insider Preview ТБ D
Заголовок: winbase.h (включая Winbase.h)
Библиотека режима ядра: volatileaccessk.lib
Библиотека пользовательского режима: volatileaccessu.lib