Составители:
Рубрика:
unsigned short MinorRuntimeVersion;
struct IMAGE_DATA_DIRECTORY MetaData;
unsigned long Flags;
unsigned long EntryPointToken;
struct IMAGE_DATA_DIRECTORY NotUsed[6];
}CLI_HEADER;
struct _IMPORT_TABLE {
// Import Address Table
unsigned long HintNameTableRVA2;
unsigned long zero2;
// Вход в таблицу импорта
unsigned long ImportLookupTableRVA;
unsigned long TimeDateStamp;
unsigned long ForwarderChain;
unsigned long NameRVA;
unsigned long ImportAddressTableRVA;
unsigned char zero[20];
// Import Lookup Table
unsigned long HintNameTableRVA1;
unsigned long zero1;
// Hint/Name Table
unsigned short Hint;
char Name[12];
// Dll name (“mscoree.dll”)
char DllName[12];
}IMPORT_TABLE;
};
Поле JmpAddress заполняется значением выражения:
RVA_OF_CLI(inP) + OFFSETOF(struct CLI_SECTION_IMAGE,IMPORT_TABLE.Hint)
+ inP->ImageBase;
Заметим, что
#define OFFSETOF(s,m) (size_t)&(((s *)0)->m).
Таким образом, к абсолютному адресу секции «.cli» прибавляется
смещение поля Hint в структуре CLI_SECTION_IMAGE.
Сразу за точкой входа находится заголовок CLI, который служит для
определения положения метаданных в PE-файле. В заголовке находится
информация об RVA и размере метаданных, а также информация о версии
CLR, для которой предназначена сборка и токен метаданных, указываю-
щий на точку входа в сборку. У DLL токен точки входа равен 0, т.к. DLL
не может сама выполнять какие-либо действия.
Структура программных компонентов
61
В заключение структура HEADERS пишется в начало выходного файла,
причем записывается количество байт, равное значению макроса
SIZE_OF_HEADERS(params), который объявлен следующим образом:
#define SIZEOF_HEADERS(params) \
align(sizeof(struct HEADERS), params->FileAlignment)
Обычно размер структуры HEADERS не кратен
inP->FileAlignment, следовательно разница дописывается нулями.
2.1.6.2. Этап 2. Генерация секции «.text»
Функция, выполняющая работу на этом этапе – make_text_section.
Прототип функции:
void make_text_section (FILE* file, PINPUT_PARAMETERS inP);
В секции «.text» находятся метаданные и тела методов. Сначала в па-
мяти выделяется массив, кратный выравниванию в файле. Размер масси-
ва задается макросом SIZEOF_TEXT(params), который определен следующим
образом:
#define SIZEOF_TEXT(params) \
align(params->SizeOfMetadata+params->SizeOfCilCode, \
params->FileAlignment)
Макрос принимает в качестве аргумента блок входных параметров.
В выделенную память записываются метаданные из массива
metadata и тела методов из массива cilcode, адреса которых передаются в
функцию через поля inP->metadata и inP->cilcode блока входных параме-
тров. Затем этот массив записывается в выходной файл сразу после заго-
ловка HEADERS. Если размер метаданных и CIL-кода не кратен
inP->FileAlignment, то разница дописывается нулями.
2.1.6.3. Этап 3. Генерация секции «.cli»
Всю работу на этом этапе выполняет функция make_cli_section. Про-
тотип функции:
void make_cli_section (FILE* file, PINPUT_PARAMETERS inP);
В секции «.cli» содержится структура CLI_SECTION_IMAGE, в которой
находится точка входа в приложение, заголовок CLI, таблица импорта и
таблица адресов импорта:
struct CLI_SECTION_IMAGE {
struct _JMP_STUB { // Точка входа
unsigned short JmpInstruction;
unsigned long JmpAddress;
}JMP_STUB;
struct _CLI_HEADER { // Заголовок CLI
unsigned long cb;
unsigned short MajorRuntimeVersion;
60
CIL и системное программирование в Microsoft .NET
60 CIL и системное программирование в Microsoft .NET Структура программных компонентов 61 В заключение структура HEADERS пишется в начало выходного файла, unsigned short MinorRuntimeVersion; причем записывается количество байт, равное значению макроса struct IMAGE_DATA_DIRECTORY MetaData; SIZE_OF_HEADERS(params), который объявлен следующим образом: unsigned long Flags; #define SIZEOF_HEADERS(params) \ unsigned long EntryPointToken; align(sizeof(struct HEADERS), params->FileAlignment) struct IMAGE_DATA_DIRECTORY NotUsed[6]; Обычно размер структуры HEADERS не кратен }CLI_HEADER; inP->FileAlignment, следовательно разница дописывается нулями. struct _IMPORT_TABLE { 2.1.6.2. Этап 2. Генерация секции «.text» // Import Address Table Функция, выполняющая работу на этом этапе – make_text_section. unsigned long HintNameTableRVA2; Прототип функции: unsigned long zero2; void make_text_section (FILE* file, PINPUT_PARAMETERS inP); // Вход в таблицу импорта В секции «.text» находятся метаданные и тела методов. Сначала в па- unsigned long ImportLookupTableRVA; мяти выделяется массив, кратный выравниванию в файле. Размер масси- unsigned long TimeDateStamp; ва задается макросом SIZEOF_TEXT(params), который определен следующим unsigned long ForwarderChain; образом: unsigned long NameRVA; #define SIZEOF_TEXT(params) \ unsigned long ImportAddressTableRVA; align(params->SizeOfMetadata+params->SizeOfCilCode, \ unsigned char zero[20]; params->FileAlignment) // Import Lookup Table Макрос принимает в качестве аргумента блок входных параметров. unsigned long HintNameTableRVA1; В выделенную память записываются метаданные из массива unsigned long zero1; metadata и тела методов из массива cilcode, адреса которых передаются в // Hint/Name Table функцию через поля inP->metadata и inP->cilcode блока входных параме- unsigned short Hint; тров. Затем этот массив записывается в выходной файл сразу после заго- char Name[12]; ловка HEADERS. Если размер метаданных и CIL-кода не кратен // Dll name (“mscoree.dll”) inP->FileAlignment, то разница дописывается нулями. char DllName[12]; }IMPORT_TABLE; 2.1.6.3. Этап 3. Генерация секции «.cli» }; Всю работу на этом этапе выполняет функция make_cli_section. Про- тотип функции: Поле JmpAddress заполняется значением выражения: void make_cli_section (FILE* file, PINPUT_PARAMETERS inP); RVA_OF_CLI(inP) + OFFSETOF(struct CLI_SECTION_IMAGE,IMPORT_TABLE.Hint) В секции «.cli» содержится структура CLI_SECTION_IMAGE, в которой + inP->ImageBase; находится точка входа в приложение, заголовок CLI, таблица импорта и Заметим, что таблица адресов импорта: #define OFFSETOF(s,m) (size_t)&(((s *)0)->m). struct CLI_SECTION_IMAGE { Таким образом, к абсолютному адресу секции «.cli» прибавляется struct _JMP_STUB { // Точка входа смещение поля Hint в структуре CLI_SECTION_IMAGE. unsigned short JmpInstruction; Сразу за точкой входа находится заголовок CLI, который служит для unsigned long JmpAddress; определения положения метаданных в PE-файле. В заголовке находится }JMP_STUB; информация об RVA и размере метаданных, а также информация о версии struct _CLI_HEADER { // Заголовок CLI CLR, для которой предназначена сборка и токен метаданных, указываю- unsigned long cb; щий на точку входа в сборку. У DLL токен точки входа равен 0, т.к. DLL unsigned short MajorRuntimeVersion; не может сама выполнять какие-либо действия.
Страницы
- « первая
- ‹ предыдущая
- …
- 35
- 36
- 37
- 38
- 39
- …
- следующая ›
- последняя »