Partager via


Descripteurs de corrélation

Un descripteur de corrélation est une chaîne de format qui décrit une expression basée sur un argument lié à un autre argument. Un descripteur de corrélation est nécessaire pour gérer la sémantique liée aux attributs tels que [size_is()], [length_is()], [switch_is()] et [iid_is()]. Les descripteurs de corrélation sont utilisés avec des tableaux, des pointeurs dimensionnés, des unions et des pointeurs d’interface. La valeur d’expression finale peut être une taille, une longueur, un discriminant d’union ou un pointeur vers un IID, respectivement. En termes de chaînes de format, les descripteurs de corrélation sont utilisés avec des tableaux, des unions et des pointeurs d’interface. Un pointeur dimensionné est décrit dans chaînes de format en tant que pointeur vers un tableau.

Deux routines effectuent des calculs d’expression de base : NdrpComputeConformance est utilisé pour les tailles, les commutateurs et IID* tandis que NdrpComputeVariance est utilisé pour les longueurs. Il existe également une seule routine pour effectuer une validation de valeur de corrélation pour la fonctionnalité de déni d’attaque.

Les descripteurs de corrélation ont été conçus pour prendre en charge uniquement des expressions très limitées. Pour les situations complexes, le compilateur génère une routine d’évaluation d’expression à appeler par le moteur si nécessaire.

Un descripteur de corrélation a le format suivant :

correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]

Le descripteur de corrélation correlation_type<1> se compose de deux nibbles : les 4 bits supérieurs décrivent où l’expression peut être trouvée et les 4 bits inférieurs décrivent le type de la valeur d’expression.

Le grignoble supérieur peut avoir l’une des cinq valeurs suivantes :

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

Un cas normal de conformité, tel que celui décrit dans un champ d’une structure.

FC_POINTER_CONFORMANCE

Pour les pointeurs à attributs (size_is(),length_is()) qui sont des champs dans une structure. Cela affecte la façon dont le pointeur de mémoire de base est défini.

FC_TOP_LEVEL_CONFORMANCE

Pour la conformité de niveau supérieur décrite par un autre paramètre.

FC_TOP_LEVEL_MULTID_CONFORMANCE

Pour la conformité de niveau supérieur d’un tableau multidimensionnel décrit par un autre paramètre.

Notes

Les tableaux et pointeurs dimensionnés multidimensionnels déclenchent un basculement vers –Oicf.

 

FC_CONSTANT_CONFORMANCE

Pour une valeur constante. Le compilateur précalcule la valeur à partir d’une expression constante fournie par l’utilisateur. Dans ce cas, les 3 octets suivants dans la description de conformité contiennent les 3 octets inférieurs d’un long décrivant la taille de conformité. Aucun autre calcul n’est nécessaire.

Le grignoble inférieur donne le type de la valeur qui doit être extraite de la mémoire :

FC_LONG | FC_ULONG | 
FC_SHORT | FC_USHORT | 
FC_SMALL | FC_USMALL | 
FC_HYPER

Notes

Les expressions 64 bits ne sont pas prises en charge. FC_HYPER est utilisé uniquement pour iid_is() sur les plateformes 64 bits afin d’extraire la valeur de pointeur pour IID*.

Le compilateur définit le type nibble sur zéro pour les cas suivants : expression constante mentionnée ci-dessus et quand la routine d’expression d’évaluation doit être appelée, par exemple, quand FC_CONSTANT_CONFORMANCE et FC_CALLBACK sont utilisés.

 

Le champ size_is_op<1> permet d’appliquer l’une des opérations suivantes à la variable de conformité :

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

La constante FC_DEREFERENCE est utilisée pour la corrélation étant un pointe, comme pour [size_is(*pL)]. Les opérateurs arithmétiques utilisent simplement la constante indiquée. La constante FC_CALLBACK indique qu’une routine d’évaluation d’expression doit être appelée.

Le champ offset<2> est généralement un décalage de mémoire relatif par rapport à la variable d’argument expression. Il peut également s’agir d’un index de routine d’évaluation d’expression. Comme mentionné précédemment dans ce document, pour les expressions constantes, il fait partie de la valeur d’expression finale réelle.

L’interprétation du champ offset<2> en tant que décalage de mémoire dépend de la complexité de l’expression, de l’emplacement de la variable d’expression et, dans le cas d’un tableau, de la question de savoir si le tableau est réellement un pointeur à attributs.

Si le tableau est un pointeur avec attributs et que la variable de conformité est un champ dans une structure, le champ de décalage contient le décalage entre le début de la structure et le champ décrivant la conformité. Si le tableau n’est pas un pointeur avec attributs et que la variable de conformité est un champ dans une structure, le champ de décalage contient le décalage entre la fin de la partie non conforme de la structure et le champ décrivant la conformité. En règle générale, le tableau conforme se trouve à la fin de la structure.

Pour la conformité de niveau supérieur, le champ offset contient le décalage entre l’emplacement du premier paramètre du stub sur la pile et le paramètre qui décrit la conformité. Il n’est pas utilisé en mode –Os . Il existe d’autres exceptions à l’interprétation du champ offset; ces exceptions sont décrites dans la description de ces types.

Lorsque le décalage<2> est utilisé avec FC_CALLBACK, il contient un index dans la table de routine d’évaluation des expressions générée par le compilateur. Le message stub est passé à la routine d’évaluation, qui calcule ensuite la valeur de conformité et l’affecte au champ MaxCount du message stub.

Le champ robust_flags<2> a été ajouté pour Windows 2000 afin de prendre en charge /robust, comme la fonctionnalité de déni d’attaques. Les indicateurs suivants sont définis sur le premier octet :

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;

L’indicateur Early indique une corrélation précoce par rapport à une corrélation tardive. Une corrélation précoce est lorsque l’argument expression précède l’argument décrit, par exemple un argument size est avant un argument pointeur dimensionné. Une corrélation tardive est lorsque l’argument expression vient après l’argument associé. Le moteur effectue immédiatement la validation des valeurs de corrélation précoces. Les valeurs de corrélation tardives sont stockées à des fins de vérification une fois le démarshalation effectué.

L’indicateur Fractionner indique un fractionnement asynchrone entre les arguments [in] et [out]. Par exemple, un argument de taille peut être [in] tandis que le pointeur dimensionné peut être [out]. Dans le contexte asynchrone DCOM, ces arguments se trouvent sur des piles différentes. Le moteur doit donc en être conscient.

L’indicateur IsIidIs indique une corrélation iid_is(). La routine NdrComputeConformance est piégée pour obtenir un pointeur vers IID comme valeur d’expression, mais la routine de validation ne peut pas comparer ces valeurs (il s’agirait de pointeurs) et l’indicateur indique donc que les ID réels doivent être comparés.

Description de la variance et autres attributs de tableau

Le format du champ description de la variance est identique au champ description de conformité. La différence réside dans le fait qu’un autre champ de message stub est utilisé par le moteur NDR en tant que variable temporaire. Dans le cas de la description de la variance, c’est la longueur qui est évaluée et le champ correspondant est appelé ActualLength.

Avec la variance, le décalage de départ est généralement égal à zéro et le moteur est réglé en conséquence. Si l’attribut first_is() est appliqué à un tableau variable conforme, un rappel à une routine d’évaluation d’expression est forcé.