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

UptoLike

.assembly extern mscorlib
{
.ver 1:0:5000:0
}
.assembly arith
{
.hash algorithm 0x00008004
.ver 1:0:1:1
}
.module arith.exe
// MVID: {86612D1B-0333-4F08-A88A-857326D72DDF}
.imagebase 0x11000000
.subsystem 0x00000003
.file alignment 4096
.corflags 0x00000001
// Image base: 0x02ef0000
.method public static void calc() cil managed
{
.entrypoint
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldstr “Hello”
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: call string [mscorlib]System.Console::ReadLine()
IL_000f: call void [mscorlib]System.Console::WriteLine(string)
IL_0014: ret
}
Метаданные, используемые при генерации сборки, находятся в мас-
сиве metadata, который в программе описан следующим образом (полное
описание не приводится из-за его большого размера, полностью листинг
массива metadata приводится в исходных текстах учебного примера):
unsigned char metadata[] = {
0x42, 0x53, 0x4A, 0x42, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
. . . . . . . . . . . . . . . . . . . . . . . .
0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
В такой же форме в программе находится CIL-код методов:
unsigned char cilcode[] = {
0x56, 0x72, 0x01, 0x00, 0x00, 0x70, 0x28, 0x02,
Структура программных компонентов
63
В конце работы функции структура CLI_SECTION_IMAGE пишется в вы-
ходной файл, сразу после секции «.text». Записывается количество байт,
равное значению макроса SIZEOF_CLI, который имеет следующий вид:
#define SIZEOF_CLI(params) \
align(sizeof(struct CLI_SECTION_IMAGE), params->FileAlignment)
Если структура CLI_SECTION_IMAGE не кратна
inP->FileAlignment, то разница дописывается нулями.
2.1.6.4. Этап 4. Генерация секции «.reloc»
Функция, ответственная за этот этап – make_reloc_section. Прототип
данной функции:
void make_reloc_section (FILE* file, PINPUT_PARAMETERS inP);
Заключительная секция релокации содержит исправления для един-
ственного абсолютного адреса в сборке, который находится в точке входа
jmp dword ptr ds:[x] в секции «.cli». Адрес x надо исправить, если сборка
грузится по адресу, отличному от базового. Сгенерированная секция
«.reloc» содержит единственную структуру RELOC_SECTION, в которой есть
все необходимые поля для исправления.
Поле PageRVA содержит адрес страницы, в которой надо произвести
исправление. Заполняется значением макроса RVA_OF_CLI. Поле BlockSize
заполняется значением макроса SIZEOF_RELOC_NOTALIGNED, который опреде-
лен так:
#define SIZEOF_RELOC_NOTALIGNED sizeof(struct RELOC_SECTION).
В сборках .NET в качестве типа исправления используется значение
3. Смещение адреса x на странице равно 2, т.к. расположение секций в па-
мяти выровнено по страницам:
struct RELOC_SECTION
{
unsigned long PageRVA; // адрес страницы
unsigned long BlockSize; // размер блока
unsigned short TypeOffset; // тип исправления и
// смещение на странице
unsigned short Padding; // завершающие нули
};
Структура записывается в конец файла после секции «.cli». Чтобы
размер файла был кратен inP->FileAlignment, в него дописывается опреде-
ленное количество нулей.
2.1.6.5. Метаданные и методы
Если описать метаданные и методы сгенерированной сборки на CIL
с использованием синтаксиса ILASM, то получится следующая IL-про-
грамма:
62
CIL и системное программирование в Microsoft .NET
62                          CIL и системное программирование в Microsoft .NET   Структура программных компонентов                                  63


     В конце работы функции структура CLI_SECTION_IMAGE пишется в вы-                .assembly extern mscorlib
ходной файл, сразу после секции «.text». Записывается количество байт,               {
равное значению макроса SIZEOF_CLI, который имеет следующий вид:                       .ver 1:0:5000:0
     #define SIZEOF_CLI(params)              \                                       }
      align(sizeof(struct CLI_SECTION_IMAGE), params->FileAlignment)                 .assembly arith
     Если       структура       CLI_SECTION_IMAGE      не       кратна               {
inP->FileAlignment, то разница дописывается нулями.                                    .hash algorithm 0x00008004
                                                                                       .ver 1:0:1:1
2.1.6.4. Этап 4. Генерация секции «.reloc»                                           }
      Функция, ответственная за этот этап – make_reloc_section. Прототип             .module arith.exe
данной функции:                                                                      // MVID: {86612D1B-0333-4F08-A88A-857326D72DDF}
      void make_reloc_section (FILE* file, PINPUT_PARAMETERS inP);                   .imagebase 0x11000000
      Заключительная секция релокации содержит исправления для един-                 .subsystem 0x00000003
ственного абсолютного адреса в сборке, который находится в точке входа               .file alignment 4096
jmp dword ptr ds:[x] в секции «.cli». Адрес x надо исправить, если сборка            .corflags 0x00000001
грузится по адресу, отличному от базового. Сгенерированная секция                    // Image base: 0x02ef0000
«.reloc» содержит единственную структуру RELOC_SECTION, в которой есть               .method public static void calc() cil managed
все необходимые поля для исправления.                                                {
      Поле PageRVA содержит адрес страницы, в которой надо произвести                  .entrypoint
исправление. Заполняется значением макроса RVA_OF_CLI. Поле BlockSize                  // Code size     21 (0x15)
заполняется значением макроса SIZEOF_RELOC_NOTALIGNED, который опреде-                 .maxstack 8
лен так:                                                                               IL_0000: ldstr “Hello”
      #define SIZEOF_RELOC_NOTALIGNED sizeof(struct RELOC_SECTION).                    IL_0005: call void [mscorlib]System.Console::WriteLine(string)
      В сборках .NET в качестве типа исправления используется значение                 IL_000a: call string [mscorlib]System.Console::ReadLine()
3. Смещение адреса x на странице равно 2, т.к. расположение секций в па-               IL_000f: call void [mscorlib]System.Console::WriteLine(string)
мяти выровнено по страницам:                                                           IL_0014: ret
      struct RELOC_SECTION                                                           }
      {
         unsigned long PageRVA;           // адрес страницы                          Метаданные, используемые при генерации сборки, находятся в мас-
         unsigned long BlockSize;         // размер блока                       сиве metadata, который в программе описан следующим образом (полное
         unsigned short TypeOffset;       // тип исправления и                  описание не приводится из-за его большого размера, полностью листинг
                                          // смещение на странице               массива metadata приводится в исходных текстах учебного примера):
         unsigned short Padding;          // завершающие нули                        unsigned char metadata[] = {
      };                                                                                0x42, 0x53, 0x4A, 0x42, 0x01, 0x00, 0x01, 0x00,
      Структура записывается в конец файла после секции «.cli». Чтобы                   0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
размер файла был кратен inP->FileAlignment, в него дописывается опреде-                 . . . . . . . . . . . . . . . . . . . . . . . .
ленное количество нулей.                                                                0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
                                                                                        0x00, 0x00, 0x00, 0x00
2.1.6.5. Метаданные и методы                                                         };
     Если описать метаданные и методы сгенерированной сборки на CIL                  В такой же форме в программе находится CIL-код методов:
с использованием синтаксиса ILASM, то получится следующая IL-про-                    unsigned char cilcode[] = {
грамма:                                                                                 0x56, 0x72, 0x01, 0x00, 0x00, 0x70, 0x28, 0x02,