Дескрипторы корреляции
Дескриптор корреляции — это строка формата, описывающая выражение на основе одного аргумента, связанного с другим аргументом. Дескриптор корреляции необходим для обработки семантики, связанной с такими атрибутами, как [size_is()], [length_is()], [switch_is()] и [iid_is()]. Дескрипторы корреляции используются с массивами, указателями размера, объединениями и указателями интерфейса. Конечным значением выражения может быть размер, длина, дискриминант объединения или указатель на IID соответственно. С точки зрения строк формата дескрипторы корреляции используются с массивами, объединениями и указателями интерфейса. Указатель размера описывается в строке форматирования как указатель на массив.
Существуют две подпрограммы, выполняющие основные вычисления выражений: NdrpComputeConformance используется для размеров, переключателей и IID*, а NdrpComputeVariance — для длины. Существует также одна подпрограмма для выполнения проверки значения корреляции для функциональности типа "отказ в атаке".
Дескрипторы корреляции предназначены для поддержки только очень ограниченных выражений. В сложных ситуациях компилятор создает подпрограмму вычисления выражений, которая будет вызываться подсистемой при необходимости.
Дескриптор корреляции имеет следующий формат:
correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]
Дескриптор корреляции correlation_type<1> состоит из двух прерывов: верхние 4 бита описывают, где можно найти выражение, а нижние 4 бита — тип значения выражения.
Верхний перо может иметь одно из следующих пяти значений:
00 FC_NORMAL_CONFORMANCE
10 FC_POINTER_CONFORMANCE
20 FC_TOP_LEVEL_CONFORMANCE
80 FC_TOP_LEVEL_MULTID_CONFORMANCE
40 FC_CONSTANT_CONFORMANCE
-
FC_NORMAL_CONFORMANCE
-
Нормальный случай соответствия, например описанный в поле структуры.
-
FC_POINTER_CONFORMANCE
-
Для указателей с атрибутами (size_is()length_is()), которые являются полями в структуре. Это влияет на способ установки указателя базовой памяти.
-
FC_TOP_LEVEL_CONFORMANCE
-
Для соответствия верхнего уровня, описанного другим параметром.
-
FC_TOP_LEVEL_MULTID_CONFORMANCE
-
Для соответствия верхнего уровня многомерного массива, описанного другим параметром.
Примечание
Массивы и указатели многомерного размера активируют переключение на –Oicf.
-
FC_CONSTANT_CONFORMANCE
-
Для константного значения. Компилятор предварительно вычисляет значение из константного выражения, предоставленного пользователем. В этом случае последующие 3 байта в описании соответствия содержат более низкие 3 байта длинного описания соответствия. Дальнейшие вычисления не требуются.
Нижний значок задает тип значения, которое необходимо извлечь из памяти:
FC_LONG | FC_ULONG |
FC_SHORT | FC_USHORT |
FC_SMALL | FC_USMALL |
FC_HYPER
Примечание
64-разрядные выражения не поддерживаются. FC_HYPER используется только для iid_is() на 64-разрядных платформах для извлечения значения указателя для IID*.
Компилятор задает тип nibble равным нулю в следующих случаях: константное выражение, упомянутое выше, и когда необходимо вызвать подпрограмму выражения вычисления, например при использовании FC_CONSTANT_CONFORMANCE и FC_CALLBACK.
Поле size_is_op<1> позволяет применить к переменной соответствия одну из следующих операций:
FC_DEREFERENCE |
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 |
FC_CALLBACK
Константная FC_DEREFERENCE используется для корреляции в качестве указателя, например для [size_is(*pL)]. Арифметические операторы используют только указанную константу. Константой FC_CALLBACK указывает, что необходимо вызвать подпрограмму вычисления выражений.
Поле смещения<2> обычно является относительным смещением памяти к переменной аргумента выражения. Это также может быть индекс обычной оценки выражения. Как упоминалось ранее в этом документе, для константных выражений это часть фактического, конечного значения выражения.
Интерпретация поля смещения<2> как смещения памяти зависит от сложности выражения, расположения переменной выражения и, в случае массива, является ли массив фактически указателем с атрибутом.
Если массив является указателем с атрибутами, а переменная соответствия является полем в структуре, поле смещения содержит смещение от начала структуры к полю описания соответствия. Если массив не является указателем с атрибутами, а переменная соответствия является полем в структуре, поле смещения содержит смещение от конца несоответствующей части структуры к полю описания соответствия. Как правило, соответствующий массив находится в конце структуры.
Для соответствия верхнего уровня поле смещения содержит смещение от расположения первого параметра заглушки в стеке до параметра, описывающего соответствие. Этот параметр не используется в режиме –Os . Существуют и другие исключения из интерпретации поля смещения; такие исключения описаны в описании этих типов.
Если используется смещение<2> с FC_CALLBACK, оно содержит индекс в таблице подпрограмм вычисления выражений, созданной компилятором. Сообщение-заглушка передается в подпрограмму оценки, которая затем вычисляет значение соответствия и назначает его полю MaxCount сообщения-заглушки.
Поле robust_flags<2> было добавлено для Windows 2000 для поддержки /robust, например функции "отказ в атаках". В первом байте определяются следующие флаги:
typedef struct _NDR_CORRELATION_FLAGS
{
unsigned char Early : 1;
unsigned char Split : 1;
unsigned char IsIidIs : 1;
unsigned char DontCheck : 1;
unsigned char Unused : 4;
} NDR_CORRELATION_FLAGS;
Флаг Ранний указывает раннюю и позднюю корреляцию. Ранняя корреляция — это когда аргумент выражения предшествует описанному аргументу, например аргумент size находится перед аргументом указателя размера. Поздняя корреляция — это когда аргумент выражения появляется после связанного аргумента. Подсистема выполняет проверку ранних значений корреляции сразу же, а поздние значения корреляции сохраняются для проверки после отмены размежевывания.
Флаг Split указывает на асинхронное разделение аргументов [in] и [out]. Например, аргумент size может иметь значение [in], а указатель размера — [out]. В асинхронном контексте DCOM эти аргументы могут находиться в разных стеках, поэтому обработчик должен знать об этом.
Флаг IsIidIs указывает на корреляцию iid_is(). Подпрограмма NdrComputeConformance используется для получения указателя на IID в качестве значения выражения, но подпрограмма проверки не может сравнивать такие значения (они будут указателями), поэтому флаг указывает на необходимость сравнения фактических идентификаторов IID.
Описание дисперсии и другие атрибуты массива
Формат поля описания дисперсии идентичен полю описания соответствия. Разница заключается в том, что в качестве временной переменной обработчик NDR использует другое поле сообщения-заглушки. В случае описания дисперсии вычисляется длина, а соответствующее поле называется ActualLength.
При дисперсии начальная смещение обычно равна нулю, и подсистема настраивается соответствующим образом. Если атрибут first_is() применяется к соответствующему переменному массиву, принудительный вызов подпрограммы вычисления выражений выполняется принудительно.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по