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

UptoLike

ной программы;
0x0008 – файл не содержит информации о символах исходной
программы;
0x0100 – файл предназначен для исполнения на 32-разрядной
машине.
Если сборка представляет собой динамическую библиотеку, то
дополнительно нужно установить флаг 0x2000.
Таким образом, значение поля Characteristics для exe-файлов
– 0x010E, а для dll-файлов – 0x210E.
Если исполняемый файл не содержит таблицы релокаций, то
дополнительно нужно установить флаг 0x0001.
2.1.3.3. Дополнительный заголовок PE-файла
Дополнительный заголовок PE-файла следует сразу за основным за-
головком. В современной документации он называется «PE Optional
Header». Строго говоря, «optional» означает «необязательный», а не «до-
полнительный». Дело в том, что в объектных файлах этот заголовок дейст-
вительно необязателен, но так как в исполняемых файлах он всегда при-
сутствует, мы будем называть его «дополнительным».
Поля дополнительного заголовка можно разделить на три группы:
Стандартные поля.
Группа стандартных полей пришла в PE из формата COFF. Они
содержат основную информацию, необходимую для загрузки и
исполнения PE-файла.
Поля, специфичные для Windows NT.
Эти поля специально предназначены для загрузчика Windows
NT. В формате COFF они изначально не присутствовали.
Директории данных.
Местонахождение некоторых важных структур данных в образе
загруженного в память PE-файла задается в так называемых ди-
ректориях данных (Data Directories). Каждая директория содер-
жит RVA и размер соответствующей структуры. Всего в допол-
нительном заголовке хранятся 16 директорий данных.
В состав дополнительного заголовка PE-файла входят следующие
стандартные поля:
unsigned short Magic;
Константа, задающая тип PE-файла:
0x010B – 32-разрядный файл;
0x020B – 64-разрядный файл.
Для сборок .NET должно быть установлено значение 0x010B.
char LMajor;
Старшее число версии компоновщика. Для сборок .NET – 6.
Структура программных компонентов
43
При разработке программного обеспечения, выполняющего чтение
PE-файлов, важно не забыть осуществить проверку сигнатуры. Дело в
том, что исполняемые файлы в устаревших форматах также начинаются с
похожего заголовка MS-DOS, после которого располагаются другие сиг-
натуры: «NE» для 16-разрядных приложений Windows, «LE» для виртуаль-
ных драйверов устройств, и даже «LX» для исполняемых файлов OS/2.
2.1.3.2. Заголовок PE-файла
Заголовок PE-файла непосредственно следует за сигнатурой PE-фай-
ла. В современной документации он называется «PE File Header», но в бо-
лее старых текстах можно встретить название «COFF Header».
Заголовок PE-файла состоит из следующих полей:
unsigned short Machine;
Это поле содержит идентификатор процессора, для которого
предназначен исполняемый файл. Для сборок .NET всегда ис-
пользуется значение 0x14c.
unsigned short NumberOfSections;
Задает количество секций в PE-файле. Массив заголовков сек-
ций следует сразу после всех заголовков, и это поле, таким обра-
зом, определяет размер этого массива.
long TimeDateStamp;
Время создания файла. Отсчитывается в секундах от начала 1
января 1970 года по Гринвичу. Самый простой способ получения
времени в этом формате – вызов функции time() из стандарт-
ной библиотеки языка C.
long PointerToSymbolTable;
long NumberOfSymbols;
Эти два поля использовались раньше для организации хранения
отладочной информации внутри COFF-файла. В настоящий
момент они не используются и всегда содержат нули.
unsigned short OptionalHeaderSize;
Задает размер дополнительного заголовка PE-файла, который
следует непосредственно за заголовком PE-файла. Сборки
.NET, как правило, содержат значение 0xE0 в этом поле. Вооб-
ще, наличие этого поля позволяет расширять формат путем до-
бавления новых полей в дополнительный заголовок PE-файла.
unsigned short Characteristics;
Представляет собой комбинацию флагов, задающую характери-
стики исполняемого файла. Для сборок .NET требуется устано-
вить следующий набор флагов:
0x0002 – файл является исполняемым;
0x0004 – файл не содержит информации о номерах строк исход-
42
CIL и системное программирование в Microsoft .NET
42                           CIL и системное программирование в Microsoft .NET   Структура программных компонентов                                     43


     При разработке программного обеспечения, выполняющего чтение                          ной программы;
PE-файлов, важно не забыть осуществить проверку сигнатуры. Дело в                          0x0008 – файл не содержит информации о символах исходной
том, что исполняемые файлы в устаревших форматах также начинаются с                        программы;
похожего заголовка MS-DOS, после которого располагаются другие сиг-                        0x0100 – файл предназначен для исполнения на 32-разрядной
натуры: «NE» для 16-разрядных приложений Windows, «LE» для виртуаль-                       машине.
ных драйверов устройств, и даже «LX» для исполняемых файлов OS/2.                          Если сборка представляет собой динамическую библиотеку, то
                                                                                           дополнительно нужно установить флаг 0x2000.
2.1.3.2. Заголовок PE-файла                                                                Таким образом, значение поля Characteristics для exe-файлов
     Заголовок PE-файла непосредственно следует за сигнатурой PE-фай-                      – 0x010E, а для dll-файлов – 0x210E.
ла. В современной документации он называется «PE File Header», но в бо-                    Если исполняемый файл не содержит таблицы релокаций, то
лее старых текстах можно встретить название «COFF Header».                                 дополнительно нужно установить флаг 0x0001.
     Заголовок PE-файла состоит из следующих полей:
     unsigned short Machine;                                                     2.1.3.3. Дополнительный заголовок PE-файла
           Это поле содержит идентификатор процессора, для которого                   Дополнительный заголовок PE-файла следует сразу за основным за-
           предназначен исполняемый файл. Для сборок .NET всегда ис-             головком. В современной документации он называется «PE Optional
           пользуется значение 0x14c.                                            Header». Строго говоря, «optional» означает «необязательный», а не «до-
     unsigned short NumberOfSections;                                            полнительный». Дело в том, что в объектных файлах этот заголовок дейст-
           Задает количество секций в PE-файле. Массив заголовков сек-           вительно необязателен, но так как в исполняемых файлах он всегда при-
           ций следует сразу после всех заголовков, и это поле, таким обра-      сутствует, мы будем называть его «дополнительным».
           зом, определяет размер этого массива.                                      Поля дополнительного заголовка можно разделить на три группы:
     long TimeDateStamp;                                                                  • Стандартные поля.
           Время создания файла. Отсчитывается в секундах от начала 1                       Группа стандартных полей пришла в PE из формата COFF. Они
           января 1970 года по Гринвичу. Самый простой способ получения                     содержат основную информацию, необходимую для загрузки и
           времени в этом формате – вызов функции time() из стандарт-                       исполнения PE-файла.
           ной библиотеки языка C.                                                        • Поля, специфичные для Windows NT.
     long PointerToSymbolTable;                                                             Эти поля специально предназначены для загрузчика Windows
     long NumberOfSymbols;                                                                  NT. В формате COFF они изначально не присутствовали.
           Эти два поля использовались раньше для организации хранения                    • Директории данных.
           отладочной информации внутри COFF-файла. В настоящий                             Местонахождение некоторых важных структур данных в образе
           момент они не используются и всегда содержат нули.                               загруженного в память PE-файла задается в так называемых ди-
     unsigned short OptionalHeaderSize;                                                     ректориях данных (Data Directories). Каждая директория содер-
           Задает размер дополнительного заголовка PE-файла, который                        жит RVA и размер соответствующей структуры. Всего в допол-
           следует непосредственно за заголовком PE-файла. Сборки                           нительном заголовке хранятся 16 директорий данных.
           .NET, как правило, содержат значение 0xE0 в этом поле. Вооб-               В состав дополнительного заголовка PE-файла входят следующие
           ще, наличие этого поля позволяет расширять формат путем до-           стандартные поля:
           бавления новых полей в дополнительный заголовок PE-файла.                  unsigned short Magic;
     unsigned short Characteristics;                                                        Константа, задающая тип PE-файла:
           Представляет собой комбинацию флагов, задающую характери-                        0x010B – 32-разрядный файл;
           стики исполняемого файла. Для сборок .NET требуется устано-                      0x020B – 64-разрядный файл.
           вить следующий набор флагов:                                                     Для сборок .NET должно быть установлено значение 0x010B.
           0x0002 – файл является исполняемым;                                        char LMajor;
           0x0004 – файл не содержит информации о номерах строк исход-                      Старшее число версии компоновщика. Для сборок .NET – 6.