Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 83 стр.

UptoLike

4.4.1. Metadata Unmanaged API
Metadata Unmanaged API осуществляет импорт и генерацию метадан-
ных. Это API, как явствует из его названия, работает не под управлением
.NET Runtime. Оно предназначено, главным образом, для использования
в компиляторах и загрузчиках, которым требуется высокая скорость дос-
тупа к метаданным и работа с метаданными на низком уровне.
При использовании Metadata Unmanaged API метаинструмент рабо-
тает с образом сборки в памяти (в документации такой образ называется
scope). Метаинструмент может создать образ новой сборки или загрузить
существующую сборку из файла, а кроме того, может сохранить образ
сборки в файл. Навигация через иерархию метаданных осуществляется на
достаточно низком уровне с использованием токенов метаданных (напом-
ним, что токен некоторого элемента метаданных – это 32-разрядное чис-
ло, старший байт которого обозначает таблицу, в которой хранятся эле-
менты метаданных соответствующего типа, а остальные три байта являют-
ся индексом элемента в этой таблице). Metadata Unmanaged API предоста-
вляет прямой доступ к таблицам метаданных, позволяет сливать несколь-
ко сборок в одну, но не содержит явных средств для работы с CIL-кодом.
Кроме того, метаинструмент, использующий это API, должен быть напи-
сан на C++.
Для того чтобы использовать Metadata Unmanaged API из програм-
мы, написанной на Visual C++, необходимо включить в программу следу-
ющие строки:
#include <corhlpr.h>
#pragma comment(lib, “format.lib”)
Первая строка подключает заголовочный файл, в котором описыва-
ются нужные интерфейсы, а также вспомогательные структуры данных и
функции. Вторая строка дает указание компоновщику использовать биб-
лиотеку format.lib.
Взаимодействие с Metadata Unmanaged API осуществляется через на-
бор COM-интерфейсов. Они перечислены в таблице 4.2.
Таблица 4.2. Интерфейсы Metadata Unmanaged API
Анализ кода на CIL
153
нение после инструкции P[i]. Для каждой такой инструкции
P[j] выполняем следующее:
a. если j < i, то проверяем, совместима ли конфигурация S с
конфигурацией M[j]. Если оказывается, что несовместима,
то алгоритм завершается неуспехом;
b. если j >= i и M[j] еще не содержит конфигурации стека, то
M[j] = S;
c. если j >= i и M[j] уже содержит конфигурацию стека, то
выполняем попытку слияния конфигураций S и M[j]. Если
попытка увенчалась успехом, то записываем результат сли-
яния в M[j]. В противном случае алгоритм завершается
неуспехом.
Если все инструкции были просмотрены и ни на одном шаге алго-
ритм не завершился неуспехом, то метод успешно прошел верификацию.
4.4. Библиотеки для создания
метаинструментов
Во второй главе мы рассмотрели написанную на языке C программу,
осуществлявшую генерацию сборки .NET. Эта программа не использова-
ла никаких библиотек для работы с метаданными и CIL-кодом, то есть за-
дача генерации сборки была решена на самом низком уровне – на уровне
двоичных форматов. Хотя такой подход во многих случаях бывает оправ-
дан, на практике гораздо удобнее воспользоваться специальными библио-
теками, предназначенными для разработчиков метаинструментов.
Напомним, что метаинструменты для платформы .NET – это про-
граммы, рассматривающие сборки .NET в качестве объектов анализа, ге-
нерации или преобразования. При этом анализ существующей сборки вы-
полняется верификаторами, загрузчиками, отладчиками и т.д. Генерация
новой сборки осуществляется компиляторами и RAD-средствами. Преоб-
разование сборки выполняется оптимизаторами и средствами, затрудняю-
щими декомпиляцию и взлом сборки.
Сборка .NET представляет собой совокупность метаданных, CIL-ко-
да и, возможно, ресурсов. Поэтому библиотеки, необходимые для созда-
ния метаинструментов, должны обеспечивать чтение и генерацию этой
информации. В составе .NET Framework SDK поставляются две библиоте-
ки, частично решающие эти задачи. Это Metadata Unmanaged API и биб-
лиотека рефлексии (Reflection API). Кроме того, существуют созданные
сторонними разработчиками библиотеки AbsIL SDK и Reflection Extension
API. В данном разделе проведем обзор этих библиотек.
152
CIL и системное программирование в Microsoft .NET
Интерфейс Описание
IMetadataDispenserEx Позволяет загружать образ исполняемого
либо объектного файла в память или созда-
вать новый образ
IMetadataImport Предназначен для чтения метаданных
IMetadataEmit Предназначен для генерации метаданных
152                         CIL и системное программирование в Microsoft .NET   Анализ кода на CIL                                                  153


          нение после инструкции P[i]. Для каждой такой инструкции              4.4.1. Metadata Unmanaged API
          P[j] выполняем следующее:
            a. если j < i, то проверяем, совместима ли конфигурация S с              Metadata Unmanaged API осуществляет импорт и генерацию метадан-
               конфигурацией M[j]. Если оказывается, что несовместима,          ных. Это API, как явствует из его названия, работает не под управлением
               то алгоритм завершается неуспехом;                               .NET Runtime. Оно предназначено, главным образом, для использования
            b. если j >= i и M[j] еще не содержит конфигурации стека, то        в компиляторах и загрузчиках, которым требуется высокая скорость дос-
               M[j] = S;                                                        тупа к метаданным и работа с метаданными на низком уровне.
            c. если j >= i и M[j] уже содержит конфигурацию стека, то                При использовании Metadata Unmanaged API метаинструмент рабо-
               выполняем попытку слияния конфигураций S и M[j]. Если            тает с образом сборки в памяти (в документации такой образ называется
               попытка увенчалась успехом, то записываем результат сли-         scope). Метаинструмент может создать образ новой сборки или загрузить
               яния в M[j]. В противном случае алгоритм завершается             существующую сборку из файла, а кроме того, может сохранить образ
               неуспехом.                                                       сборки в файл. Навигация через иерархию метаданных осуществляется на
    Если все инструкции были просмотрены и ни на одном шаге алго-               достаточно низком уровне с использованием токенов метаданных (напом-
ритм не завершился неуспехом, то метод успешно прошел верификацию.              ним, что токен некоторого элемента метаданных – это 32-разрядное чис-
                                                                                ло, старший байт которого обозначает таблицу, в которой хранятся эле-
4.4. Библиотеки для создания                                                    менты метаданных соответствующего типа, а остальные три байта являют-
                                                                                ся индексом элемента в этой таблице). Metadata Unmanaged API предоста-
метаинструментов                                                                вляет прямой доступ к таблицам метаданных, позволяет сливать несколь-
     Во второй главе мы рассмотрели написанную на языке C программу,            ко сборок в одну, но не содержит явных средств для работы с CIL-кодом.
осуществлявшую генерацию сборки .NET. Эта программа не использова-              Кроме того, метаинструмент, использующий это API, должен быть напи-
ла никаких библиотек для работы с метаданными и CIL-кодом, то есть за-          сан на C++.
дача генерации сборки была решена на самом низком уровне – на уровне                 Для того чтобы использовать Metadata Unmanaged API из програм-
двоичных форматов. Хотя такой подход во многих случаях бывает оправ-            мы, написанной на Visual C++, необходимо включить в программу следу-
дан, на практике гораздо удобнее воспользоваться специальными библио-           ющие строки:
теками, предназначенными для разработчиков метаинструментов.                         #include 
     Напомним, что метаинструменты для платформы .NET – это про-                     #pragma comment(lib, “format.lib”)
граммы, рассматривающие сборки .NET в качестве объектов анализа, ге-                 Первая строка подключает заголовочный файл, в котором описыва-
нерации или преобразования. При этом анализ существующей сборки вы-             ются нужные интерфейсы, а также вспомогательные структуры данных и
полняется верификаторами, загрузчиками, отладчиками и т.д. Генерация            функции. Вторая строка дает указание компоновщику использовать биб-
новой сборки осуществляется компиляторами и RAD-средствами. Преоб-              лиотеку format.lib.
разование сборки выполняется оптимизаторами и средствами, затрудняю-                 Взаимодействие с Metadata Unmanaged API осуществляется через на-
щими декомпиляцию и взлом сборки.                                               бор COM-интерфейсов. Они перечислены в таблице 4.2.
     Сборка .NET представляет собой совокупность метаданных, CIL-ко-
да и, возможно, ресурсов. Поэтому библиотеки, необходимые для созда-                 Таблица 4.2. Интерфейсы Metadata Unmanaged API
ния метаинструментов, должны обеспечивать чтение и генерацию этой
информации. В составе .NET Framework SDK поставляются две библиоте-             Интерфейс                  Описание
ки, частично решающие эти задачи. Это Metadata Unmanaged API и биб-             IMetadataDispenserEx       Позволяет загружать образ исполняемого
лиотека рефлексии (Reflection API). Кроме того, существуют созданные                                       либо объектного файла в память или созда-
сторонними разработчиками библиотеки AbsIL SDK и Reflection Extension                                      вать новый образ
API. В данном разделе проведем обзор этих библиотек.                            IMetadataImport            Предназначен для чтения метаданных
                                                                                IMetadataEmit              Предназначен для генерации метаданных