Как узнать header файла

Обновлено: 25.06.2024

Заголовок PE (IMAGE_NT_HEADERS) всегда выравнен на границу 8 байт и состоит из трех частей:

Как уже было сказано, заголовок PE всегда начинается с 4-байтовой сигнатуры "PE\0\0" (IMAGE_NT_SIGNATURE). За ней следуют два заголовка: заголовок файла (IMAGE_FILE_HEADER) и необязательный заголовок (IMAGE_OPTIONAL_HEADER). Несмотря на свое название, IMAGE_OPTIONAL_HEADER присутствует в PE-файле всегда (необязательным он является с точки зрения общего формата COFF, поскольку не используется в объектных и библиотечных файлах).

3.2. Заголовок файла

Заголовок файла состоит из 0x14 байтов (определение IMAGE_SIZEOF_FILE_HEADER), размещается сразу после сигнатуры и содержит общее описание файла. Он состоит из следующих полей:

Опишем назначения полей.

Поле Machine

16-битовое число, которое задает архитектуру процессора, на которой может выполняться данная программа. Мне известны следующие коды процессоров (большинство из которых так никогда и не были поддержаны в Windows):

Название Значение Процессор
IMAGE_FILE_MACHINE_UNKNOWN 0 неизвестный процессор
IMAGE_FILE_MACHINE_I386 0x014C Intel 80386 или выше
0x014D Intel 80486 или выше
0x014E Intel Pentium или выше
0x0160 MIPS R3000, big-endian
IMAGE_FILE_MACHINE_R3000 0x0162 MIPS R3000, little-endian
IMAGE_FILE_MACHINE_R4000 0x0166 MIPS R4000
IMAGE_FILE_MACHINE_R10000 0x0168 MIPS R10000
IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 MIPS WCE v2
IMAGE_FILE_MACHINE_ALPHA 0x0184 DEC/Compaq Alpha AXP
IMAGE_FILE_MACHINE_SH3 0x01A2 Hitachi SH3
IMAGE_FILE_MACHINE_SH3DSP 0x01A3 Hitachi SH3 DSP
IMAGE_FILE_MACHINE_SH3E 0x01A4 Hitachi SH3E
IMAGE_FILE_MACHINE_SH4 0x01A6 Hitachi SH4
IMAGE_FILE_MACHINE_SH5 0x01A8 Hitachi SH5
IMAGE_FILE_MACHINE_ARM 0x01C0 ARM
IMAGE_FILE_MACHINE_THUMB 0x01C2 ARM Thumb
IMAGE_FILE_MACHINE_AM33 0x01D3 Panasonic AM33
IMAGE_FILE_MACHINE_POWERPC 0x01F0 IBM PowerPC
IMAGE_FILE_MACHINE_POWERPCFP 0x01F1 IBM PowerPC FP
IMAGE_FILE_MACHINE_IA64 0x0200 Intel IA-64 (Itanium)
IMAGE_FILE_MACHINE_MIPS16 0x0266 MIPS16
0x0268 Motorola 68000
IMAGE_FILE_MACHINE_ALPHA64 0x0284 DEC/Compaq Alpha AXP 64-bit
0x0290 HP PA-RISC
IMAGE_FILE_MACHINE_MIPSFPU 0x0366 MIPS with FPU
IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 MIPS16 with FPU
IMAGE_FILE_MACHINE_TRICORE 0x0520 Infineon TriCore
IMAGE_FILE_MACHINE_CEF 0x0CEF .
IMAGE_FILE_MACHINE_EBC 0x0EBC EFI Byte Code
IMAGE_FILE_MACHINE_AMD64 0x8664 AMD 64 (K8)
IMAGE_FILE_MACHINE_M32R 0x9041 Renesas M32R
IMAGE_FILE_MACHINE_CEE 0xC0EE .

Поле TimeDateStamp

32-битовое число, которое содержит дату и время создания данного файла. Формат этого поля недокументирован, однако сборщики Microsoft заносят сюда время как количество секунд от полуночи 01.01.1970 в UTC (т. е. используют юниксовский формат времени, возвращаемого функцией time языка C). Между прочим, это означает, что текущее состояние формата PE действительно только до 18.01.2038 г.

Поскольку формат этого поля недокументирован, некоторые сборщики третьих фирм сохраняют его значение в других форматах. Это может оказаться важным, т. к. данное поле используется при динамическом связывании импорта из DLL.

Поля PointerToSymbolTable и NumberOfSymbols

Согласно стандарту COFF, эти 4-байтовые поля должны обеспечивать доступ к отладочной информации в файле. Однако все известные мне сборщики заносят в них нули, а для доступа к отладочной информации используется иной способ (см. каталог отладочной информации).

Поле SizeOfOptionalHeader

16-битовое число, задающее размер необязательного заголовка. Оно равно 0xE0 для файлов PE32 (IMAGE_SIZEOF_NT_OPTIONAL32_HEADER) и 0xF0 для файлов PE32+ (IMAGE_SIZEOF_NT_OPTIONAL64_HEADER).

Поле Characteristics

16-битовое поле флагов, содержащее COFF-атрибуты файла. Перечислим только те флаги, которые относятся к исполняемым файлам.

3.3. Необязательный заголовок

Необязательный заголовок имеет два различных формата: для PE32 и для PE32+. Соответствующие структуры называются IMAGE_OPTIONAL_HEADER32 и IMAGE_OPTIONAL_HEADER64. Их поля сведены в следующей таблице:

Смещение (hex, PE32/PE32+) Размер (PE32/PE32+) Тип (PE32/PE32+) Название Описание
00 2 WORD Magic Сигнатура заголовка.
02 1 BYTE MajorLinkerVersion Старшая цифра номера версии сборщика. Загрузчиком не используется.
03 1 BYTE MinorLinkerVersion Младшая цифра номера версии сборщика. Загрузчиком не используется.
04 4 DWORD SizeOfCode Сумма размеров всех секций, содержащих програмный код.
08 4 DWORD SizeOfInitializedData Сумма размеров всех секций, содержащих инициализированные данные.
0C 4 DWORD SizeOfUninitializedData Сумма размеров всех секций, содержащих неинициализированные данные.
10 4 DWORD AddressOfEntryPoint RVA точки запуска программы. Для драйвера – это адрес DriverEntry, для DLL – адрес DllMain или нуль.
14 4 DWORD BaseOfCode RVA начала кода программы.
18/– 4/0 DWORD BaseOfData RVA начала данных программы. Ненадежное поле, загрузчиком не используется. В PE32+ отсутствует!
1С/18 4/8 DWORD/ULONGLONG ImageBase Предпочтительный базовый адрес программы в памяти, кратный 64 Кб. По умолчанию равен 0x00400000 для EXE-файлов в Windows 9x/NT, 0x00010000 для EXE-файлов в Windows CE и 0x10000000 для DLL. Загрузка программы с этого адреса позволяет обойтись без настройки адресов.
20 4 DWORD SectionAlignment Выравнивание в байтах для секций при загрузке в память, большее или равное FileAlignment. По умолчанию равно размеру страницы виртуальной памяти для данного процессора.
24 4 DWORD FileAlignment Выравнивание в байтах для секций внутри файла. Должно быть степенью 2 от 512 до 64 Кб включительно. По умолчанию равно 512. Если SectionAlignment меньше размера страницы виртуальной памяти, то FileAlignment должно с ним совпадать.
28 2 WORD MajorOperatingSystemVersion Старшая цифра номера версии операционной системы. Загрузчиком не используется.
2A 2 WORD MinorOperatingSystemVersion Младшая цифра номера версии операционной системы. Загрузчиком не используется.
2C 2 WORD MajorImageVersion Старшая цифра номера версии данного файла. Загрузчиком не используется.
2E 2 WORD MinorImageVersion Младшая цифра номера версии данного файла. Загрузчиком не используется.
30 2 WORD MajorSubsystemVersion Старшая цифра номера версии подсистемы.
32 2 WORD MinorSubsystemVersion Младшая цифра номера версии подсистемы.
34 4 DWORD Win32VersionValue Зарезервировано, всегда равно 0.
38 4 DWORD SizeOfImage Размер файла в памяти, включая все заголовки. Должен быть кратен SectionAlignment.
3C 4 DWORD SizeOfHeaders Суммарный размер заголовка и заглушки DOS, заголовка PE и заголовков секций, выравненный на границу FileAlignment. Задает смещение от начала файла до данных первой секции.
40 4 DWORD CheckSum Контрольная сумма файла.
44 2 WORD Subsystem Исполняющая подсистема Windows для данного файла.
46 2 WORD DllCharacteristics Дополнительные атрибуты файла.
48 4/8 DWORD/ULONGLONG SizeOfStackReserve Размер стека стартового потока программы в байтах виртуальной памяти. При загрузке в физическую память отображается только SizeOfStackCommit байт, в дальнейшем отображается по одной странице виртуальной памяти. По умолчанию равен 1 Мб.
4C/50 4/8 DWORD/ULONGLONG SizeOfStackCommit Начальный размер стека программы в байтах. По умолчанию равен 4 Кб.
50/58 4/8 DWORD/ULONGLONG SizeOfHeapReserve Размер кучи программы в байтах. При загрузке в физическую память отображается только SizeOfHeapCommit байт, в дальнейшем отображается по одной странице виртуальной памяти. По умолчанию равен 1 Мб. Во всех 32-разрядных версиях Windows куча ограничена только размером виртуальной памяти и это поле, по-видимому, игнорируется.
54/60 4/8 DWORD/ULONGLONG SizeOfHeapCommit Начальный размер кучи программы в байтах. По умолчанию равен 4 Кб.
58/68 4 DWORD LoaderFlags Устаревшее поле, не используется.
5C/6C 4 DWORD NumberOfRvaAndSizes Количество описателей каталогов данных. На текущий момент всегда равно 16.
60/70 128 IMAGE_DATA_DIRECTORY[16] DataDirectory Описатели каталогов данных.

Поясним некоторые поля этой структуры.

Поле Magic

16-битовое поле, содержащее сигнатуру заголовка. Может принимать значения:

Название Значение Описание
IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107 Заголовок прошивки в ПЗУ ?
IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010B Заголовок PE32.
IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020B Заголовок PE32+.

Поля MajorSubsystemVersion и MinorSubsystemVersion

16-битовые числа, указывающее ожидаемую версию Windows. В отличие от всех остальных полей с номерами версий это поле анализировалось при загрузке программ в NT 4.0 и 95. Если программа была графическим приложением и это поле не содержало версии 4.0, то считалось, что программа разработана для NT 3.51 и моделировалось поведение этой ОС (в частности, отсутствие трехмерных стилей диалогов и пр.). В настоящее время не используется и практически всегда равно 4.0.

Поле CheckSum

32-битовая контрольная сумма файла. Проверяется только в Windows NT при загрузке драйверов ядра и нескольких системных DLL. Алгоритм вычисления контрольной суммы недокументирован, но для ее вычисления можно использовать системную функцию CheckSumMappedFile из библиотеки IMAGEHLP.DLL.

Поле Subsystem

16-битовое число, указывающее в какой подсистеме Windows API должен исполняться данный файл. Его возможные значения:

Название Значение Подсистема
IMAGE_SUBSYSTEM_UNKNOWN 0 Неизвестная подсистема.
IMAGE_SUBSYSTEM_NATIVE 1 Подсистема не требуется, используется драйверами и "родными" приложениями NT.
IMAGE_SUBSYSTEM_WINDOWS_GUI 2 Графическая подсистема Windows.
IMAGE_SUBSYSTEM_WINDOWS_CUI 3 Консольная подсистема Windows.
IMAGE_SUBSYSTEM_OS2_CUI 5 Консольная подсистема OS/2.
IMAGE_SUBSYSTEM_POSIX_CUI 7 Консольная подсистема POSIX.
IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 "Родной" драйвер Win 9x.
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 Графическая подсистема Windows CE.
IMAGE_SUBSYSTEM_EFI_APPLICATION 10 Программа EFI.
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 Драйвер EFI, обеспечивающий загрузочный сервис.
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 Драйвер EFI времени выполнения.
IMAGE_SUBSYSTEM_EFI_ROM 13 Прошивка ПЗУ для EFI.
IMAGE_SUBSYSTEM_XBOX 14 Подсистема Xbox.

Поле DLLCharacteristics

16-битовое поле флагов, задающие дополнительные атрибуты файла. Возможные значения флагов:

Название Значение Описание
IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 Файл не использует структурную обработку исключений.
IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 Запрещает статическое связывание этого файла.
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 Файл является WDM-драйвером.
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 Если этот флаг не установлен, то при загрузке программы терминальным сервером будет загружена вспомогательная DLL, обеспечивающая совместимость кода.

Поля NumberOfRvaAndSizes и DataDirectory

В конце необязательного заголовка располагается 32-битовое число, в котором хранится количество описателей каталогов данных. За ним следует массив самих описателей, каждый из которых имеет такой вид:

В настоящее время поле NumberOfRvaAndSizes всегда содержит число 16 (символическое имя IMAGE_NUMBEROF_DIRECTORY_ENTRIES). Соответственно массив DataDirectory состоит также из 16 описателей. Каждый описатель содержит RVA и размер для одного каталога данных. Если какого-либо каталога в файле нет, то оба поля его описателя равны нулю.

Каждый из каталогов данных содержит определенную служебную информацию. Вид этой информации определяется номером каталога в массиве описателей. Поскольку каталоги данных, как правило, располагаются внутри секций, для доступа к их содержимому нам потребуется сначала изучить структуру секций.

Все файлы на диске хранятся в виде двоичного (бинарного) кода. Последовательность цифр 1 и 0 определяет содержимое файла. В одном случае эти цифры могут составлять простой текст, в результате чего мы видим обычные текстовые файлы. В другом - это последовательность байт, которая несет самую разную информацию, например: аудио, видео, картинки или закодированный текст. Откройте в текстовом редакторе файлы .TXT и .EXE и вы почувствуете разницу.

В данной статье рассказано каким еще способом (кроме непосредственно расширения файла) можно идентифицировать формат двоичного файла, который не является обычным текстовым. Таких файлов большинство. Именно в них часто есть заголовок файла - это первые несколько байт в определенной последовательности. Часть заголовка может быть одинакова у файлов с одинаковым расширением. Эта часть отвечает за формат файла, для удобства назовем ее «дескриптор заголовка файла» (description с англ. - описание).

Таким образом, если необходимо более точно идентифицировать формат файла или файл переименован и его истинное расширение неизвестно, то узнать что это за файл можно с помощью дескриптора заголовка файла. У нас на сайте дескрипторы представлены в трех видах: HEX, ASCII и ASCII (расширенный). Опишем преимущества каждого представления.

HEX и ASCII. Чтобы определить дескриптор заголовка файла и, соответственно, формат файла, необходима программа, которая представляет файл в виде HEX (шестнадцатеричного кода). Это может быть любой HEX-редактор. Но лучше всего для наших целей подойдет программа MiniDumper (20 Кб).

Скачиваем программу, распаковываем ее, открываем. Далее нажимаем кнопку «Select file…», выбираем файл и видим следующее:

Скриншот Minidumper (HEX, ASCII)

Берем первые 2-3 блока из левой колонки (HEX) или первые символы (точки не учитываем) из правой колонки (ASCII), как показано на рисунке; вводим в соответствующее поле расширенного поиска и получаем результат:

Расширенный поиск (HEX, ASCII)

Если расширений найдено много, то можно увеличивать количество блоков до достижения однозначного результата. И наоборот, если Вы ничего не нашли, то следует уменьшить количество блоков.

ASCII (расширенный). ASCII с расширенной таблицей символов - кириллицей и специальными символами. Этот вариант специально создан для ленивых: просто откройте файл с помощью блокнота и ищите первые от начала значащие символы. Например:

Скриншот Блокнота (ASCII, расш.)

Далее, вставляем эти символы в соответствующее поле расширенного поиска и получаем результат:

 Расширенный поиск (ASCII, расш.)

Обращаем ваше внимание, что наиболее точным и продуктивным из всех трех вариантов будет поиск по HEX-декскрипторам, т.к. некоторые последовательности байт невозможно перевести в корректный ASCII-код и HEX-значения мы берем точно из начала файла.

like

97

Скорее всего, вы знаете, что при открытии страницы любого сайта происходят действия на сервере, которые не видны пользователям. Однако эти данные обрабатывают поисковые системы. И к счастью, некоторые из этих данных поддаются корректировке, и мы немного можем облегчить работу веб-сервера.

  1. Клиент устанавливает TCP-соединение (или соответствующее соединение, если транспортный уровень не является TCP).
  2. Клиент отправляет свой запрос и ждёт ответа.
  3. Сервер обрабатывает запрос, отправляя ответ обратно, предоставляя код состояния и соответствующие данные.

Этот заголовок может содержать инструкции, которые клиенты и поисковые системы могут использовать для правильной обработки URL.

X-Robots-Tag

Это аналог метатега robots в html. У данного элемента есть преимущества над meta name=“robots”. Например, если вы хотите запретить к индексации файлы PDF, метатег robots не поможет, так как он не работает с PDF-файлами. Вместо этого, вы можете использовать заголовок X-Robots-Tag.

К тому же у X-Robots-Tag есть ещё одно преимущество – его легко настраивать для целых каталогов и папок, что может ускорить работу.

Помимо «noindex» и «nofollow», вы можете прописать другие ответы X-Robots-Tag. Директивы из справки Google — ссылка:

Директивы X-Robots-Tag из справки Google

Canonical

Hreflang

Cache-control

Cache-control может влиять на то, как браузер кэширует страницу и связанные с ней ресурсы. Например, вы можете предоставить ответ «max-age», который сообщает браузеру, что через некоторое время страница должна быть повторно запрошена с сервера. В противном случае кэш страницы действителен то время, которое указано в значении «max-age», тем самым ускоряя скорость загрузки страницы. Директивы из справки Google — ссылка:

Директивы Cache-control из справки Google

Служит для определения различий отображения контента для ПК и мобильных устройств. Особенно это важно для сайтов, которые используют динамический показ для мобильных пользователей. Для сайтов с адаптивным дизайном данный элемент не так актуален.

При правильной настройке заголовка Vary поисковые боты будут сканировать сайт со всеми указанными типами User-agent и определять, какая версия кода будет ранжироваться для какого типа пользователей.

Last-Modified

If-Modified-Since

Это условный запрос, который передаёт объект, если он был изменен после указанной даты. То есть передаются данные только в том случае, когда кэш устарел.

If-Unmodified-Since

Это условный запрос, который передаёт объект, только если он не был изменен после указанной даты.

Expires

Дата/время, после которого ответ веб-сервера считается устаревшим. Например, можно указывать текущую дату + 7/10/14 дней.

Accept-Encoding

Content-Encoding

Content-Length

Размер ресурса в десятичном числе байтов.

Content-Type

Указывает тип носителя ресурса.

Location

Указывает URL-адрес для перенаправления страницы. Он используется только тогда, когда для пользователя указывается перенаправление на другую страницу (3xx код) или при новом местоположении ресурса (201 код).

Инструменты разработчика в Google Chrome

После чего выбрать вкладку «Network» и обновить страницу (F5).

Network в Google Chrome

Далее в графе «Name» необходимо выбрать тип файла, для которого вы хотите проверить заголовки, и справа во вкладке «Headers» будут указаны все заголовки текущего файла.

Просмотр http-заголовков в Chrome

Аналогичным способом можно проверить заголовки и в Firefox: при помощи Ctrl+Shift+C либо в верхнем выпадающем меню выбрать «Веб-разработка»→«Инструменты разработчика». Далее выбрать вкладку «Сеть» и обновить страницу (F5). После чего выбрать тип документа для проверки и в правой части экрана выбрать вкладку «Заголовки». Перед вами появятся заголовки текущей страницы.

Просмотр http-заголовков в Firefox

Примеры популярных расширений:

Также в сети есть большое количество онлайн-программ, при помощи которых вы можете проверить заголовки своего сайта:

В заключение

Имена программных элементов, таких как переменные, функции, классы и т. д., должны быть объявлены, прежде чем их можно будет использовать. Например, нельзя просто писать x = 42 без предварительного объявления "x".

Объявление сообщает компилятору, является ли элемент int , a double , функцией class или другим элементом. Кроме того, каждое имя должно быть объявлено (прямо или косвенно) в каждом cpp-файле, в котором он используется. При компиляции программы каждый CPP-файл компилируется независимо в единицу компиляции. Компилятор не имеет сведений о том, какие имена объявляются в других единицах компиляции. Это означает, что если вы определите класс или функцию или глобальную переменную, необходимо предоставить объявление этого объекта в каждом дополнительном cpp-файле, который его использует. Каждое объявление этого элемента должно быть точно одинаковым во всех файлах. Небольшая несогласованность вызовет ошибки или непреднамеренное поведение, когда компоновщик пытается объединить все единицы компиляции в одну программу.

в Visual Studio 2019 функция модулей c++ 20 появилась в качестве улучшения и в конечном итоге заменяет файлы заголовков. Дополнительные сведения см. в разделе Общие сведения о модулях в C++.

Пример

В следующем примере показан общий способ объявления класса и его использования в другом исходном файле. Начнем с файла заголовка, my_class.h . Он содержит определение класса, но обратите внимание, что определение не завершено; Функция-член do_something не определена:

В файле реализации при необходимости можно использовать using оператор, чтобы не указывать каждое упоминание "my_class" или "cout" с "N::" или "std::". Не помещайте using операторы в файлы заголовков!

После того как компилятор завершит компиляцию каждого CPP-файла в OBJ-файлы, он передает OBJ-файлы компоновщику. Когда компоновщик объединяет объектные файлы, обнаруживается только одно определение для my_class; Он находится в OBJ-файле, созданном для my_class. cpp, и сборка выполняется.

Включить условия

Что следует разместить в файле заголовка

Поскольку файл заголовка потенциально может включаться в несколько файлов, он не может содержать определения, которые могут формировать несколько определений с одним и тем же именем. Следующие действия не разрешены или считаются очень неправильными.

  • встроенные определения типов в пространстве имен или глобальной области
  • невстроенные определения функций
  • определения неконстантных переменных
  • агрегатные определения
  • безымянные пространства имен
  • Директивы using

Использование using директивы не обязательно приведет к ошибке, но может вызвать проблему, так как она переводит пространство имен в область каждого CPP-файла, который напрямую или косвенно включает этот заголовок.

Пример файла заголовка

В следующем примере показаны различные виды объявлений и определений, допустимых в файле заголовка.

Читайте также: